[DEV] add drag & drop
This commit is contained in:
parent
334d68ac1f
commit
d8ceaef3f9
@ -3,7 +3,7 @@
|
|||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>org.kar</groupId>
|
<groupId>org.kar</groupId>
|
||||||
<artifactId>karideo</artifactId>
|
<artifactId>karideo</artifactId>
|
||||||
<version>0.2.0</version>
|
<version>0.3.0</version>
|
||||||
<properties>
|
<properties>
|
||||||
<maven.compiler.version>3.1</maven.compiler.version>
|
<maven.compiler.version>3.1</maven.compiler.version>
|
||||||
<maven.compiler.source>21</maven.compiler.source>
|
<maven.compiler.source>21</maven.compiler.source>
|
||||||
@ -20,7 +20,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>kangaroo-and-rabbit</groupId>
|
<groupId>kangaroo-and-rabbit</groupId>
|
||||||
<artifactId>archidata</artifactId>
|
<artifactId>archidata</artifactId>
|
||||||
<version>0.7.1</version>
|
<version>0.7.3</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.slf4j</groupId>
|
<groupId>org.slf4j</groupId>
|
||||||
|
@ -35,7 +35,6 @@ import jakarta.ws.rs.Path;
|
|||||||
import jakarta.ws.rs.PathParam;
|
import jakarta.ws.rs.PathParam;
|
||||||
import jakarta.ws.rs.Produces;
|
import jakarta.ws.rs.Produces;
|
||||||
import jakarta.ws.rs.core.MediaType;
|
import jakarta.ws.rs.core.MediaType;
|
||||||
import jakarta.ws.rs.core.Response;
|
|
||||||
|
|
||||||
@Path("/media")
|
@Path("/media")
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
@ -63,7 +62,7 @@ public class MediaResource {
|
|||||||
@Consumes(MediaType.APPLICATION_JSON)
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
@Operation(description = "Modify a specific Media", tags = "GLOBAL")
|
@Operation(description = "Modify a specific Media", tags = "GLOBAL")
|
||||||
public Media patch(@PathParam("id") final Long id, @AsyncType(Media.class) final String jsonRequest) throws Exception {
|
public Media patch(@PathParam("id") final Long id, @AsyncType(Media.class) final String jsonRequest) throws Exception {
|
||||||
System.out.println("update video " + id + " ==> '" + jsonRequest + "'");
|
LOGGER.info("update video {} ==> '{}'", id, jsonRequest);
|
||||||
DataAccess.updateWithJson(Media.class, id, jsonRequest);
|
DataAccess.updateWithJson(Media.class, id, jsonRequest);
|
||||||
return DataAccess.get(Media.class, id);
|
return DataAccess.get(Media.class, id);
|
||||||
}
|
}
|
||||||
@ -85,12 +84,19 @@ public class MediaResource {
|
|||||||
@RolesAllowed("ADMIN")
|
@RolesAllowed("ADMIN")
|
||||||
@Consumes({ MediaType.MULTIPART_FORM_DATA })
|
@Consumes({ MediaType.MULTIPART_FORM_DATA })
|
||||||
@Operation(description = "Create a new Media", tags = "GLOBAL")
|
@Operation(description = "Create a new Media", tags = "GLOBAL")
|
||||||
@AsyncType(Media.class)
|
|
||||||
@TypeScriptProgress
|
@TypeScriptProgress
|
||||||
public Response uploadFile(@FormDataParam("fileName") String fileName, @FormDataParam("universe") String universe, @FormDataParam("series") String series,
|
public Media uploadFile( //
|
||||||
//@FormDataParam("seriesId") String seriesId, Not used ...
|
@FormDataParam("fileName") String fileName, //
|
||||||
@FormDataParam("season") String season, @FormDataParam("episode") String episode, @FormDataParam("title") String title, @FormDataParam("typeId") String typeId,
|
@FormDataParam("universe") String universe, //
|
||||||
@FormDataParam("file") final InputStream fileInputStream, @FormDataParam("file") final FormDataContentDisposition fileMetaData) throws FailException {
|
@FormDataParam("series") String series, //
|
||||||
|
//@FormDataParam("seriesId") String seriesId, // Not used ...
|
||||||
|
@FormDataParam("season") String season, //
|
||||||
|
@FormDataParam("episode") String episode, //
|
||||||
|
@FormDataParam("title") String title, //
|
||||||
|
@FormDataParam("typeId") String typeId, //
|
||||||
|
@FormDataParam("file") final InputStream fileInputStream, //
|
||||||
|
@FormDataParam("file") final FormDataContentDisposition fileMetaData //
|
||||||
|
) throws FailException {
|
||||||
try {
|
try {
|
||||||
// correct input string stream :
|
// correct input string stream :
|
||||||
fileName = multipartCorrection(fileName);
|
fileName = multipartCorrection(fileName);
|
||||||
@ -102,16 +108,16 @@ public class MediaResource {
|
|||||||
typeId = multipartCorrection(typeId);
|
typeId = multipartCorrection(typeId);
|
||||||
|
|
||||||
//public NodeSmall uploadFile(final FormDataMultiPart form) {
|
//public NodeSmall uploadFile(final FormDataMultiPart form) {
|
||||||
System.out.println("Upload media file: " + fileMetaData);
|
LOGGER.info("Upload media file: {}", fileMetaData);
|
||||||
System.out.println(" - fileName: " + fileName);
|
LOGGER.info(" - fileName: {}", fileName);
|
||||||
System.out.println(" - universe: " + universe);
|
LOGGER.info(" - universe: {}", universe);
|
||||||
System.out.println(" - series: " + series);
|
LOGGER.info(" - series: {}", series);
|
||||||
System.out.println(" - season: " + season);
|
LOGGER.info(" - season: {}", season);
|
||||||
System.out.println(" - episode: " + episode);
|
LOGGER.info(" - episode: {}", episode);
|
||||||
System.out.println(" - title: " + title);
|
LOGGER.info(" - title: {}", title);
|
||||||
System.out.println(" - type: " + typeId);
|
LOGGER.info(" - type: {}", typeId);
|
||||||
System.out.println(" - fileInputStream: " + fileInputStream);
|
LOGGER.info(" - fileInputStream: {}", fileInputStream);
|
||||||
System.out.println(" - fileMetaData: " + fileMetaData);
|
LOGGER.info(" - fileMetaData: {}", fileMetaData);
|
||||||
System.out.flush();
|
System.out.flush();
|
||||||
if (typeId == null) {
|
if (typeId == null) {
|
||||||
throw new InputException("typeId", "TypiId is not specified");
|
throw new InputException("typeId", "TypiId is not specified");
|
||||||
@ -121,7 +127,7 @@ public class MediaResource {
|
|||||||
final String sha512 = DataResource.saveTemporaryFile(fileInputStream, tmpUID);
|
final String sha512 = DataResource.saveTemporaryFile(fileInputStream, tmpUID);
|
||||||
Data data = DataResource.getWithSha512(sha512);
|
Data data = DataResource.getWithSha512(sha512);
|
||||||
if (data == null) {
|
if (data == null) {
|
||||||
System.out.println("Need to add the data in the BDD ... ");
|
LOGGER.info("Need to add the data in the BDD ... ");
|
||||||
System.out.flush();
|
System.out.flush();
|
||||||
try {
|
try {
|
||||||
data = DataResource.createNewData(tmpUID, fileName, sha512);
|
data = DataResource.createNewData(tmpUID, fileName, sha512);
|
||||||
@ -130,33 +136,33 @@ public class MediaResource {
|
|||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
throw new FailException("can not create input media (the data model has an internal error");
|
throw new FailException("can not create input media (the data model has an internal error");
|
||||||
}
|
}
|
||||||
} else if (data!= null && data.deleted) {
|
} else if (data!= null && data.deleted != null && data.deleted) {
|
||||||
System.out.println("Data already exist but deleted");
|
LOGGER.info("Data already exist but deleted");
|
||||||
System.out.flush();
|
System.out.flush();
|
||||||
DataTools.undelete(data.id);
|
DataTools.undelete(data.id);
|
||||||
data.deleted = false;
|
data.deleted = false;
|
||||||
} else {
|
} else {
|
||||||
System.out.println("Data already exist ... all good");
|
LOGGER.info("Data already exist ... all good");
|
||||||
System.out.flush();
|
System.out.flush();
|
||||||
}
|
}
|
||||||
// Fist step: retieve all the Id of each parents:...
|
// Fist step: retieve all the Id of each parents:...
|
||||||
System.out.println("Find typeNode");
|
LOGGER.info("Find typeNode");
|
||||||
// check if id of type exist:
|
// check if id of type exist:
|
||||||
final Type typeNode = TypeResource.getId(Long.parseLong(typeId));
|
final Type typeNode = TypeResource.getId(Long.parseLong(typeId));
|
||||||
if (typeNode == null) {
|
if (typeNode == null) {
|
||||||
DataResource.removeTemporaryFile(tmpUID);
|
DataResource.removeTemporaryFile(tmpUID);
|
||||||
throw new InputException("typeId", "TypeId does not exist ...");
|
throw new InputException("typeId", "TypeId does not exist ...");
|
||||||
}
|
}
|
||||||
System.out.println(" ==> " + typeNode);
|
LOGGER.info(" ==> {}", typeNode);
|
||||||
System.out.println("Find seriesNode");
|
LOGGER.info("Find seriesNode");
|
||||||
// get uid of group:
|
// get uid of group:
|
||||||
Series seriesNode = null;
|
Series seriesNode = null;
|
||||||
if (series != null) {
|
if (series != null) {
|
||||||
seriesNode = SeriesResource.getOrCreate(series, typeNode.id);
|
seriesNode = SeriesResource.getOrCreate(series, typeNode.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
System.out.println(" ==> " + seriesNode);
|
LOGGER.info(" ==> {}", seriesNode);
|
||||||
System.out.println("Find seasonNode");
|
LOGGER.info("Find seasonNode");
|
||||||
// get uid of season:
|
// get uid of season:
|
||||||
Season seasonNode = null;
|
Season seasonNode = null;
|
||||||
if (seriesNode == null && season != null) {
|
if (seriesNode == null && season != null) {
|
||||||
@ -167,10 +173,9 @@ public class MediaResource {
|
|||||||
seasonNode = SeasonResource.getOrCreate(season, seriesNode.id);
|
seasonNode = SeasonResource.getOrCreate(season, seriesNode.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
System.out.println(" ==> " + seasonNode);
|
LOGGER.info(" ==> {}", seasonNode);
|
||||||
System.out.println("add media");
|
LOGGER.info("add media");
|
||||||
|
|
||||||
final long uniqueSQLID = -1;
|
|
||||||
try {
|
try {
|
||||||
final Media media = new Media();
|
final Media media = new Media();
|
||||||
media.name = title;
|
media.name = title;
|
||||||
@ -189,17 +194,17 @@ public class MediaResource {
|
|||||||
media.episode = Integer.parseInt(episode);
|
media.episode = Integer.parseInt(episode);
|
||||||
}
|
}
|
||||||
final Media out = DataAccess.insert(media);
|
final Media out = DataAccess.insert(media);
|
||||||
DataResource.removeTemporaryFile(tmpUID);
|
LOGGER.info("Generate new media {}", out);
|
||||||
System.out.println("uploaded .... compleate: " + uniqueSQLID);
|
return out;
|
||||||
final Media creation = get(uniqueSQLID);
|
|
||||||
return Response.ok(creation).build();
|
|
||||||
} catch (final SQLException ex) {
|
} catch (final SQLException ex) {
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
System.out.println("Catch error:" + ex.getMessage());
|
LOGGER.error("Catch error: {}", ex.getMessage());
|
||||||
throw new FailException("Catch SQLerror ==> check server logs");
|
throw new FailException("Catch SQLerror ==> check server logs");
|
||||||
|
} finally {
|
||||||
|
DataResource.removeTemporaryFile(tmpUID);
|
||||||
}
|
}
|
||||||
} catch (final Exception ex) {
|
} catch (final Exception ex) {
|
||||||
System.out.println("Catch an unexpected error ... " + ex.getMessage());
|
LOGGER.error("Catch an unexpected error ... {} ", ex.getMessage());
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
throw new FailException("Catch Exception ==> check server logs");
|
throw new FailException("Catch Exception ==> check server logs");
|
||||||
}
|
}
|
||||||
|
@ -119,9 +119,17 @@ public class Migration20240226 extends MigrationSqlStep {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
/* I am not sure then I prefer keep the primary key for the moment
|
||||||
addAction("""
|
addAction("""
|
||||||
ALTER TABLE `data` DROP `id`;
|
ALTER TABLE `data` DROP `id`;
|
||||||
""");
|
""");
|
||||||
|
*/
|
||||||
|
addAction("""
|
||||||
|
ALTER TABLE `data` CHANGE `id` `idOld` bigint NOT NULL DEFAULT 0;
|
||||||
|
""");
|
||||||
|
addAction("""
|
||||||
|
ALTER TABLE `data` DROP PRIMARY KEY;
|
||||||
|
""");
|
||||||
addAction("""
|
addAction("""
|
||||||
ALTER TABLE `data` CHANGE `uuid` `id` binary(16) DEFAULT (UUID_TO_BIN(UUID(), TRUE));
|
ALTER TABLE `data` CHANGE `uuid` `id` binary(16) DEFAULT (UUID_TO_BIN(UUID(), TRUE));
|
||||||
""");
|
""");
|
||||||
|
@ -49,4 +49,13 @@ public class Media extends GenericDataSoftDelete {
|
|||||||
// List of Id of the specific covers
|
// List of Id of the specific covers
|
||||||
@DataJson(targetEntity = Data.class)
|
@DataJson(targetEntity = Data.class)
|
||||||
public List<UUID> covers = null;
|
public List<UUID> covers = null;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Media [name=" + this.name + ", description=" + this.description + ", dataId=" + this.dataId + ", typeId=" + this.typeId
|
||||||
|
+ ", seriesId=" + this.seriesId + ", seasonId=" + this.seasonId + ", episode=" + this.episode + ", date=" + this.date
|
||||||
|
+ ", time=" + this.time + ", ageLimit=" + this.ageLimit + ", covers=" + this.covers + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -19,31 +19,31 @@
|
|||||||
},
|
},
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@angular/animations": "^17.3.4",
|
"@angular/animations": "^17.3.5",
|
||||||
"@angular/cdk": "^17.3.4",
|
"@angular/cdk": "^17.3.5",
|
||||||
"@angular/common": "^17.3.4",
|
"@angular/common": "^17.3.5",
|
||||||
"@angular/compiler": "^17.3.4",
|
"@angular/compiler": "^17.3.5",
|
||||||
"@angular/core": "^17.3.4",
|
"@angular/core": "^17.3.5",
|
||||||
"@angular/forms": "^17.3.4",
|
"@angular/forms": "^17.3.5",
|
||||||
"@angular/material": "^17.3.4",
|
"@angular/material": "^17.3.5",
|
||||||
"@angular/platform-browser": "^17.3.4",
|
"@angular/platform-browser": "^17.3.5",
|
||||||
"@angular/platform-browser-dynamic": "^17.3.4",
|
"@angular/platform-browser-dynamic": "^17.3.5",
|
||||||
"@angular/router": "^17.3.4",
|
"@angular/router": "^17.3.5",
|
||||||
"rxjs": "^7.8.1",
|
"rxjs": "^7.8.1",
|
||||||
"zone.js": "^0.14.4",
|
"zone.js": "^0.14.4",
|
||||||
"zod": "3.22.4",
|
"zod": "3.22.4",
|
||||||
"@kangaroo-and-rabbit/kar-cw": "^0.2.0"
|
"@kangaroo-and-rabbit/kar-cw": "^0.2.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@angular-devkit/build-angular": "^17.3.4",
|
"@angular-devkit/build-angular": "^17.3.5",
|
||||||
"@angular-eslint/builder": "17.3.0",
|
"@angular-eslint/builder": "17.3.0",
|
||||||
"@angular-eslint/eslint-plugin": "17.3.0",
|
"@angular-eslint/eslint-plugin": "17.3.0",
|
||||||
"@angular-eslint/eslint-plugin-template": "17.3.0",
|
"@angular-eslint/eslint-plugin-template": "17.3.0",
|
||||||
"@angular-eslint/schematics": "17.3.0",
|
"@angular-eslint/schematics": "17.3.0",
|
||||||
"@angular-eslint/template-parser": "17.3.0",
|
"@angular-eslint/template-parser": "17.3.0",
|
||||||
"@angular/cli": "^17.3.4",
|
"@angular/cli": "^17.3.5",
|
||||||
"@angular/compiler-cli": "^17.3.4",
|
"@angular/compiler-cli": "^17.3.5",
|
||||||
"@angular/language-service": "^17.3.4",
|
"@angular/language-service": "^17.3.5",
|
||||||
"npm-check-updates": "^16.14.18",
|
"npm-check-updates": "^16.14.18",
|
||||||
"tslib": "^2.6.2"
|
"tslib": "^2.6.2"
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,7 @@ import { environment } from 'environments/environment';
|
|||||||
|
|
||||||
import { FormsModule, ReactiveFormsModule } from "@angular/forms";
|
import { FormsModule, ReactiveFormsModule } from "@angular/forms";
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { FileDragNDropDirective } from './scene/upload/file-drag-n-drop.directive';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
@ -58,7 +59,8 @@ import { CommonModule } from '@angular/common';
|
|||||||
VideoEditScene,
|
VideoEditScene,
|
||||||
SeasonEditScene,
|
SeasonEditScene,
|
||||||
SeriesEditScene,
|
SeriesEditScene,
|
||||||
UploadScene
|
UploadScene,
|
||||||
|
FileDragNDropDirective,
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
FormsModule,
|
FormsModule,
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* API of the server (auto-generated code)
|
* API of the server (auto-generated code)
|
||||||
*/
|
*/
|
||||||
import { HTTPMimeType, HTTPRequestModel, ModelResponseHttp, RESTConfig, ProgressCallback, RESTRequestJson, RESTRequestJsonArray, RESTRequestVoid } from "./rest-tools"
|
import { HTTPMimeType, HTTPRequestModel, ModelResponseHttp, RESTConfig, RESTCallbacks, RESTRequestJson, RESTRequestJsonArray, RESTRequestVoid } from "./rest-tools"
|
||||||
import {UUID, } from "./model"
|
import {UUID, } from "./model"
|
||||||
export namespace DataResource {
|
export namespace DataResource {
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* API of the server (auto-generated code)
|
* API of the server (auto-generated code)
|
||||||
*/
|
*/
|
||||||
import { HTTPMimeType, HTTPRequestModel, ModelResponseHttp, RESTConfig, ProgressCallback, RESTRequestJson, RESTRequestJsonArray, RESTRequestVoid } from "./rest-tools"
|
import { HTTPMimeType, HTTPRequestModel, ModelResponseHttp, RESTConfig, RESTCallbacks, RESTRequestJson, RESTRequestJsonArray, RESTRequestVoid } from "./rest-tools"
|
||||||
import {} from "./model"
|
import {} from "./model"
|
||||||
export namespace Front {
|
export namespace Front {
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* API of the server (auto-generated code)
|
* API of the server (auto-generated code)
|
||||||
*/
|
*/
|
||||||
import { HTTPMimeType, HTTPRequestModel, ModelResponseHttp, RESTConfig, ProgressCallback, RESTRequestJson, RESTRequestJsonArray, RESTRequestVoid } from "./rest-tools"
|
import { HTTPMimeType, HTTPRequestModel, ModelResponseHttp, RESTConfig, RESTCallbacks, RESTRequestJson, RESTRequestJsonArray, RESTRequestVoid } from "./rest-tools"
|
||||||
import {HealthResult, isHealthResult, } from "./model"
|
import {HealthResult, isHealthResult, } from "./model"
|
||||||
export namespace HealthCheck {
|
export namespace HealthCheck {
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* API of the server (auto-generated code)
|
* API of the server (auto-generated code)
|
||||||
*/
|
*/
|
||||||
import { HTTPMimeType, HTTPRequestModel, ModelResponseHttp, RESTConfig, ProgressCallback, RESTRequestJson, RESTRequestJsonArray, RESTRequestVoid } from "./rest-tools"
|
import { HTTPMimeType, HTTPRequestModel, ModelResponseHttp, RESTConfig, RESTCallbacks, RESTRequestJson, RESTRequestJsonArray, RESTRequestVoid } from "./rest-tools"
|
||||||
import {UUID, Long, Media, isMedia, } from "./model"
|
import {UUID, Long, Media, isMedia, } from "./model"
|
||||||
export namespace MediaResource {
|
export namespace MediaResource {
|
||||||
|
|
||||||
@ -66,33 +66,6 @@ export namespace MediaResource {
|
|||||||
data,
|
data,
|
||||||
}, isMedia);
|
}, isMedia);
|
||||||
};
|
};
|
||||||
/**
|
|
||||||
* Upload a new season cover media
|
|
||||||
*/
|
|
||||||
export function uploadCover({ restConfig, params, data, progress, }: {
|
|
||||||
restConfig: RESTConfig,
|
|
||||||
params: {
|
|
||||||
id: Long,
|
|
||||||
},
|
|
||||||
data: {
|
|
||||||
fileName: string,
|
|
||||||
file: File,
|
|
||||||
},
|
|
||||||
progress?: ProgressCallback,
|
|
||||||
}): Promise<Media> {
|
|
||||||
return RESTRequestJson({
|
|
||||||
restModel: {
|
|
||||||
endPoint: "/media/{id}/cover",
|
|
||||||
requestType: HTTPRequestModel.POST,
|
|
||||||
contentType: HTTPMimeType.MULTIPART,
|
|
||||||
accept: HTTPMimeType.JSON,
|
|
||||||
},
|
|
||||||
restConfig,
|
|
||||||
params,
|
|
||||||
data,
|
|
||||||
progress,
|
|
||||||
}, isMedia);
|
|
||||||
};
|
|
||||||
/**
|
/**
|
||||||
* Get all Media
|
* Get all Media
|
||||||
*/
|
*/
|
||||||
@ -108,6 +81,33 @@ export namespace MediaResource {
|
|||||||
restConfig,
|
restConfig,
|
||||||
}, isMedia);
|
}, isMedia);
|
||||||
};
|
};
|
||||||
|
/**
|
||||||
|
* Upload a new season cover media
|
||||||
|
*/
|
||||||
|
export function uploadCover({ restConfig, params, data, callback, }: {
|
||||||
|
restConfig: RESTConfig,
|
||||||
|
params: {
|
||||||
|
id: Long,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
fileName: string,
|
||||||
|
file: File,
|
||||||
|
},
|
||||||
|
callback?: RESTCallbacks,
|
||||||
|
}): Promise<Media> {
|
||||||
|
return RESTRequestJson({
|
||||||
|
restModel: {
|
||||||
|
endPoint: "/media/{id}/cover",
|
||||||
|
requestType: HTTPRequestModel.POST,
|
||||||
|
contentType: HTTPMimeType.MULTIPART,
|
||||||
|
accept: HTTPMimeType.JSON,
|
||||||
|
},
|
||||||
|
restConfig,
|
||||||
|
params,
|
||||||
|
data,
|
||||||
|
callback,
|
||||||
|
}, isMedia);
|
||||||
|
};
|
||||||
/**
|
/**
|
||||||
* Remove a specific cover of a media
|
* Remove a specific cover of a media
|
||||||
*/
|
*/
|
||||||
@ -132,7 +132,7 @@ export namespace MediaResource {
|
|||||||
/**
|
/**
|
||||||
* Create a new Media
|
* Create a new Media
|
||||||
*/
|
*/
|
||||||
export function uploadFile({ restConfig, data, progress, }: {
|
export function uploadFile({ restConfig, data, callback, }: {
|
||||||
restConfig: RESTConfig,
|
restConfig: RESTConfig,
|
||||||
data: {
|
data: {
|
||||||
fileName: string,
|
fileName: string,
|
||||||
@ -144,7 +144,7 @@ export namespace MediaResource {
|
|||||||
typeId: string,
|
typeId: string,
|
||||||
title: string,
|
title: string,
|
||||||
},
|
},
|
||||||
progress?: ProgressCallback,
|
callback?: RESTCallbacks,
|
||||||
}): Promise<Media> {
|
}): Promise<Media> {
|
||||||
return RESTRequestJson({
|
return RESTRequestJson({
|
||||||
restModel: {
|
restModel: {
|
||||||
@ -155,7 +155,7 @@ export namespace MediaResource {
|
|||||||
},
|
},
|
||||||
restConfig,
|
restConfig,
|
||||||
data,
|
data,
|
||||||
progress,
|
callback,
|
||||||
}, isMedia);
|
}, isMedia);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -122,9 +122,9 @@ export function isLocalTime(data: any): data is LocalTime {
|
|||||||
|
|
||||||
export const ZodRestErrorResponse = zod.object({
|
export const ZodRestErrorResponse = zod.object({
|
||||||
uuid: ZodUUID.optional(),
|
uuid: ZodUUID.optional(),
|
||||||
time: zod.string().max(255).optional(),
|
name: zod.string().max(255).optional(),
|
||||||
error: zod.string().max(255).optional(),
|
|
||||||
message: zod.string().max(255).optional(),
|
message: zod.string().max(255).optional(),
|
||||||
|
time: zod.string().max(255).optional(),
|
||||||
status: ZodInteger,
|
status: ZodInteger,
|
||||||
statusMessage: zod.string().max(255).optional()
|
statusMessage: zod.string().max(255).optional()
|
||||||
});
|
});
|
||||||
|
@ -41,7 +41,7 @@ export interface RESTModel {
|
|||||||
accept?: HTTPMimeType;
|
accept?: HTTPMimeType;
|
||||||
// Content of the local data.
|
// Content of the local data.
|
||||||
contentType?: HTTPMimeType;
|
contentType?: HTTPMimeType;
|
||||||
// Mode of the TOKEN in urk or Header
|
// Mode of the TOKEN in URL or Header (?token:${tokenInUrl})
|
||||||
tokenInUrl?: boolean;
|
tokenInUrl?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,13 +71,28 @@ function isNullOrUndefined(data: any): data is undefined | null {
|
|||||||
return data === undefined || data === null;
|
return data === undefined || data === null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type RESTRequestType = {
|
// generic progression callback
|
||||||
|
export type ProgressCallback = (count: number, total: number) => void;
|
||||||
|
|
||||||
|
export interface RESTAbort {
|
||||||
|
abort?: () => boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Rest generic callback have a basic model to upload and download advancement.
|
||||||
|
export interface RESTCallbacks {
|
||||||
|
progressUpload?: ProgressCallback,
|
||||||
|
progressDownload?: ProgressCallback,
|
||||||
|
abortHandle?: RESTAbort,
|
||||||
|
};
|
||||||
|
|
||||||
|
export interface RESTRequestType {
|
||||||
restModel: RESTModel,
|
restModel: RESTModel,
|
||||||
restConfig: RESTConfig,
|
restConfig: RESTConfig,
|
||||||
data?: any,
|
data?: any,
|
||||||
params?: object,
|
params?: object,
|
||||||
queries?: object,
|
queries?: object,
|
||||||
progress?: ProgressCallback,
|
callback?: RESTCallbacks,
|
||||||
};
|
};
|
||||||
|
|
||||||
function removeTrailingSlashes(input: string): string {
|
function removeTrailingSlashes(input: string): string {
|
||||||
@ -124,63 +139,91 @@ export function RESTUrl({ restModel, restConfig, params, queries }: RESTRequestT
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export type ProgressCallback = (count: number, total: number) => void;
|
export function fetchProgress(generateUrl: string, { method, headers, body }: {
|
||||||
// input: RequestInfo | URL, init?: RequestInit): Promise<Response>;
|
|
||||||
export function fetchProgress<TYPE>(generateUrl: string, { method, headers, body }: {
|
|
||||||
method: HTTPRequestModel,
|
method: HTTPRequestModel,
|
||||||
headers: any,
|
headers: any,
|
||||||
body: any,
|
body: any,
|
||||||
}, progress: ProgressCallback): Promise<Response> {
|
}, { progressUpload, progressDownload, abortHandle }: RESTCallbacks): Promise<Response> {
|
||||||
|
const xhr = {
|
||||||
//async function fetchForm(form, options = {}) {
|
io: new XMLHttpRequest()
|
||||||
const action = generateUrl;
|
}
|
||||||
const data = body;
|
|
||||||
const xhr = new XMLHttpRequest();
|
|
||||||
console.log(`call fetch progress ...`);
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
xhr.responseType = 'blob';
|
// Stream the upload progress
|
||||||
xhr.onreadystatechange = () => {
|
if (progressUpload) {
|
||||||
if (xhr.readyState != 4) {
|
xhr.io.upload.addEventListener("progress", (dataEvent) => {
|
||||||
console.log(` ==> READY state`);
|
if (dataEvent.lengthComputable) {
|
||||||
// done
|
//console.log(` ==> has a progress event: ${dataEvent.loaded} / ${dataEvent.total}`);
|
||||||
return;
|
progressUpload(dataEvent.loaded, dataEvent.total);
|
||||||
}
|
}
|
||||||
console.log(` ==> has finish ...`);
|
|
||||||
const response = new Response(xhr.response, {
|
|
||||||
status: xhr.status,
|
|
||||||
statusText: xhr.statusText
|
|
||||||
});
|
});
|
||||||
resolve(response);
|
|
||||||
}
|
}
|
||||||
// If fail:
|
// Stream the download progress
|
||||||
xhr.addEventListener('error', () => {
|
if (progressDownload) {
|
||||||
console.log(` ==> IS REJECTED`);
|
xhr.io.addEventListener("progress", (dataEvent) => {
|
||||||
|
if (dataEvent.lengthComputable) {
|
||||||
|
//console.log(` ==> download progress:: ${dataEvent.loaded} / ${dataEvent.total}`);
|
||||||
|
progressUpload(dataEvent.loaded, dataEvent.total);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (abortHandle) {
|
||||||
|
abortHandle.abort = () => {
|
||||||
|
if (xhr.io) {
|
||||||
|
console.log(`Request abort on the XMLHttpRequest: ${generateUrl}`);
|
||||||
|
xhr.io.abort();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
console.log(`Request abort (FAIL) on the XMLHttpRequest: ${generateUrl}`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Check if we have an internal Fail:
|
||||||
|
xhr.io.addEventListener('error', () => {
|
||||||
|
xhr.io = undefined;
|
||||||
reject(new TypeError('Failed to fetch'))
|
reject(new TypeError('Failed to fetch'))
|
||||||
});
|
});
|
||||||
// Link the progression callback
|
|
||||||
if (progress) {
|
// Capture the end of the stream
|
||||||
xhr.addEventListener('progress', (dataEvent) => {
|
xhr.io.addEventListener("loadend", () => {
|
||||||
console.log(` ==> has a progress event: ${dataEvent.loaded} / ${dataEvent.total}`);
|
if (xhr.io.readyState !== XMLHttpRequest.DONE) {
|
||||||
progress(dataEvent.loaded, dataEvent.total);
|
//console.log(` ==> READY state`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (xhr.io.status === 0) {
|
||||||
|
//the stream has been aborted
|
||||||
|
reject(new TypeError('Fetch has been aborted'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Stream is ended, transform in a generic response:
|
||||||
|
const response = new Response(xhr.io.response, {
|
||||||
|
status: xhr.io.status,
|
||||||
|
statusText: xhr.io.statusText
|
||||||
});
|
});
|
||||||
}
|
const headersArray = xhr.io.getAllResponseHeaders().trim().replaceAll("\r\n", "\n").split('\n');
|
||||||
console.log(` ==> open`);
|
headersArray.forEach(function (header) {
|
||||||
// open the socket
|
const firstColonIndex = header.indexOf(':');
|
||||||
xhr.open(method, action, true);
|
if (firstColonIndex !== -1) {
|
||||||
console.log(` ==> set header`);
|
var key = header.substring(0, firstColonIndex).trim();
|
||||||
// configure the header
|
var value = header.substring(firstColonIndex + 1).trim();
|
||||||
|
response.headers.set(key, value);
|
||||||
|
} else {
|
||||||
|
response.headers.set(header, "");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
xhr.io = undefined;
|
||||||
|
resolve(response);
|
||||||
|
});
|
||||||
|
xhr.io.open(method, generateUrl, true);
|
||||||
if (!isNullOrUndefined(headers)) {
|
if (!isNullOrUndefined(headers)) {
|
||||||
for (const [key, value] of Object.entries(headers)) {
|
for (const [key, value] of Object.entries(headers)) {
|
||||||
xhr.setRequestHeader(key, value as string);
|
xhr.io.setRequestHeader(key, value as string);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.log(` ==> send`);
|
xhr.io.send(body);
|
||||||
xhr.send(data);
|
|
||||||
console.log(` ==> send done`);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function RESTRequest({ restModel, restConfig, data, params, queries, progress }: RESTRequestType): Promise<ModelResponseHttp> {
|
export function RESTRequest({ restModel, restConfig, data, params, queries, callback }: RESTRequestType): Promise<ModelResponseHttp> {
|
||||||
// Create the URL PATH:
|
// Create the URL PATH:
|
||||||
let generateUrl = RESTUrl({ restModel, restConfig, data, params, queries });
|
let generateUrl = RESTUrl({ restModel, restConfig, data, params, queries });
|
||||||
let headers: any = {};
|
let headers: any = {};
|
||||||
@ -207,21 +250,25 @@ export function RESTRequest({ restModel, restConfig, data, params, queries, prog
|
|||||||
}
|
}
|
||||||
body = formData
|
body = formData
|
||||||
}
|
}
|
||||||
console.log(`Call ${generateUrl}`)
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let action: Promise<Response> = undefined;
|
let action: undefined | Promise<Response> = undefined;
|
||||||
if (isNullOrUndefined(progress)) {
|
if (isNullOrUndefined(callback)
|
||||||
|
|| (isNullOrUndefined(callback.progressDownload)
|
||||||
|
&& isNullOrUndefined(callback.progressUpload)
|
||||||
|
&& isNullOrUndefined(callback.abortHandle))) {
|
||||||
|
// No information needed: call the generic fetch interface
|
||||||
action = fetch(generateUrl, {
|
action = fetch(generateUrl, {
|
||||||
method: restModel.requestType,
|
method: restModel.requestType,
|
||||||
headers,
|
headers,
|
||||||
body,
|
body,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
// need progression information: call old fetch model (XMLHttpRequest) that permit to keep % upload and % download for HTTP1.x
|
||||||
action = fetchProgress(generateUrl, {
|
action = fetchProgress(generateUrl, {
|
||||||
method: restModel.requestType,
|
method: restModel.requestType ?? HTTPRequestModel.GET,
|
||||||
headers,
|
headers,
|
||||||
body,
|
body,
|
||||||
}, progress);
|
}, callback);
|
||||||
}
|
}
|
||||||
action.then((response: Response) => {
|
action.then((response: Response) => {
|
||||||
if (response.status >= 200 && response.status <= 299) {
|
if (response.status >= 200 && response.status <= 299) {
|
||||||
@ -268,7 +315,7 @@ export function RESTRequest({ restModel, restConfig, data, params, queries, prog
|
|||||||
status: 999,
|
status: 999,
|
||||||
error: error,
|
error: error,
|
||||||
statusMessage: "Fetch catch error",
|
statusMessage: "Fetch catch error",
|
||||||
message: "http-wrapper.ts detect an error in the fetch request"
|
message: "rest-tools.ts detect an error in the fetch request"
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* API of the server (auto-generated code)
|
* API of the server (auto-generated code)
|
||||||
*/
|
*/
|
||||||
import { HTTPMimeType, HTTPRequestModel, ModelResponseHttp, RESTConfig, ProgressCallback, RESTRequestJson, RESTRequestJsonArray, RESTRequestVoid } from "./rest-tools"
|
import { HTTPMimeType, HTTPRequestModel, ModelResponseHttp, RESTConfig, RESTCallbacks, RESTRequestJson, RESTRequestJsonArray, RESTRequestVoid } from "./rest-tools"
|
||||||
import {UUID, Long, Season, isSeason, } from "./model"
|
import {UUID, Long, Season, isSeason, } from "./model"
|
||||||
export namespace SeasonResource {
|
export namespace SeasonResource {
|
||||||
|
|
||||||
@ -85,33 +85,6 @@ export namespace SeasonResource {
|
|||||||
data,
|
data,
|
||||||
}, isSeason);
|
}, isSeason);
|
||||||
};
|
};
|
||||||
/**
|
|
||||||
* Upload a new season cover season
|
|
||||||
*/
|
|
||||||
export function uploadCover({ restConfig, params, data, progress, }: {
|
|
||||||
restConfig: RESTConfig,
|
|
||||||
params: {
|
|
||||||
id: Long,
|
|
||||||
},
|
|
||||||
data: {
|
|
||||||
fileName: string,
|
|
||||||
file: File,
|
|
||||||
},
|
|
||||||
progress?: ProgressCallback,
|
|
||||||
}): Promise<Season> {
|
|
||||||
return RESTRequestJson({
|
|
||||||
restModel: {
|
|
||||||
endPoint: "/season/{id}/cover",
|
|
||||||
requestType: HTTPRequestModel.POST,
|
|
||||||
contentType: HTTPMimeType.MULTIPART,
|
|
||||||
accept: HTTPMimeType.JSON,
|
|
||||||
},
|
|
||||||
restConfig,
|
|
||||||
params,
|
|
||||||
data,
|
|
||||||
progress,
|
|
||||||
}, isSeason);
|
|
||||||
};
|
|
||||||
/**
|
/**
|
||||||
* Get a specific Season with his ID
|
* Get a specific Season with his ID
|
||||||
*/
|
*/
|
||||||
@ -127,6 +100,33 @@ export namespace SeasonResource {
|
|||||||
restConfig,
|
restConfig,
|
||||||
}, isSeason);
|
}, isSeason);
|
||||||
};
|
};
|
||||||
|
/**
|
||||||
|
* Upload a new season cover season
|
||||||
|
*/
|
||||||
|
export function uploadCover({ restConfig, params, data, callback, }: {
|
||||||
|
restConfig: RESTConfig,
|
||||||
|
params: {
|
||||||
|
id: Long,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
fileName: string,
|
||||||
|
file: File,
|
||||||
|
},
|
||||||
|
callback?: RESTCallbacks,
|
||||||
|
}): Promise<Season> {
|
||||||
|
return RESTRequestJson({
|
||||||
|
restModel: {
|
||||||
|
endPoint: "/season/{id}/cover",
|
||||||
|
requestType: HTTPRequestModel.POST,
|
||||||
|
contentType: HTTPMimeType.MULTIPART,
|
||||||
|
accept: HTTPMimeType.JSON,
|
||||||
|
},
|
||||||
|
restConfig,
|
||||||
|
params,
|
||||||
|
data,
|
||||||
|
callback,
|
||||||
|
}, isSeason);
|
||||||
|
};
|
||||||
/**
|
/**
|
||||||
* Remove a specific cover of a season
|
* Remove a specific cover of a season
|
||||||
*/
|
*/
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
/**
|
/**
|
||||||
* API of the server (auto-generated code)
|
* API of the server (auto-generated code)
|
||||||
*/
|
*/
|
||||||
import { HTTPMimeType, HTTPRequestModel, ModelResponseHttp, RESTConfig, ProgressCallback, RESTRequestJson, RESTRequestJsonArray, RESTRequestVoid } from "./rest-tools"
|
import { HTTPMimeType, HTTPRequestModel, ModelResponseHttp, RESTConfig, RESTCallbacks, RESTRequestJson, RESTRequestJsonArray, RESTRequestVoid } from "./rest-tools"
|
||||||
import { UUID, Long, Series, isSeries, } from "./model"
|
import {UUID, Long, Series, isSeries, } from "./model"
|
||||||
export namespace SeriesResource {
|
export namespace SeriesResource {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -85,33 +85,6 @@ export namespace SeriesResource {
|
|||||||
data,
|
data,
|
||||||
}, isSeries);
|
}, isSeries);
|
||||||
};
|
};
|
||||||
/**
|
|
||||||
* Upload a new season cover Series
|
|
||||||
*/
|
|
||||||
export function uploadCover({ restConfig, params, data, progress, }: {
|
|
||||||
restConfig: RESTConfig,
|
|
||||||
params: {
|
|
||||||
id: Long,
|
|
||||||
},
|
|
||||||
data: {
|
|
||||||
fileName: string,
|
|
||||||
file: File,
|
|
||||||
},
|
|
||||||
progress?: ProgressCallback,
|
|
||||||
}): Promise<Series> {
|
|
||||||
return RESTRequestJson({
|
|
||||||
restModel: {
|
|
||||||
endPoint: "/series/{id}/cover",
|
|
||||||
requestType: HTTPRequestModel.POST,
|
|
||||||
contentType: HTTPMimeType.MULTIPART,
|
|
||||||
accept: HTTPMimeType.JSON,
|
|
||||||
},
|
|
||||||
restConfig,
|
|
||||||
params,
|
|
||||||
data,
|
|
||||||
progress,
|
|
||||||
}, isSeries);
|
|
||||||
};
|
|
||||||
/**
|
/**
|
||||||
* Get all Series
|
* Get all Series
|
||||||
*/
|
*/
|
||||||
@ -127,6 +100,33 @@ export namespace SeriesResource {
|
|||||||
restConfig,
|
restConfig,
|
||||||
}, isSeries);
|
}, isSeries);
|
||||||
};
|
};
|
||||||
|
/**
|
||||||
|
* Upload a new season cover Series
|
||||||
|
*/
|
||||||
|
export function uploadCover({ restConfig, params, data, callback, }: {
|
||||||
|
restConfig: RESTConfig,
|
||||||
|
params: {
|
||||||
|
id: Long,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
fileName: string,
|
||||||
|
file: File,
|
||||||
|
},
|
||||||
|
callback?: RESTCallbacks,
|
||||||
|
}): Promise<Series> {
|
||||||
|
return RESTRequestJson({
|
||||||
|
restModel: {
|
||||||
|
endPoint: "/series/{id}/cover",
|
||||||
|
requestType: HTTPRequestModel.POST,
|
||||||
|
contentType: HTTPMimeType.MULTIPART,
|
||||||
|
accept: HTTPMimeType.JSON,
|
||||||
|
},
|
||||||
|
restConfig,
|
||||||
|
params,
|
||||||
|
data,
|
||||||
|
callback,
|
||||||
|
}, isSeries);
|
||||||
|
};
|
||||||
/**
|
/**
|
||||||
* Remove a specific Series of a season
|
* Remove a specific Series of a season
|
||||||
*/
|
*/
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* API of the server (auto-generated code)
|
* API of the server (auto-generated code)
|
||||||
*/
|
*/
|
||||||
import { HTTPMimeType, HTTPRequestModel, ModelResponseHttp, RESTConfig, ProgressCallback, RESTRequestJson, RESTRequestJsonArray, RESTRequestVoid } from "./rest-tools"
|
import { HTTPMimeType, HTTPRequestModel, ModelResponseHttp, RESTConfig, RESTCallbacks, RESTRequestJson, RESTRequestJsonArray, RESTRequestVoid } from "./rest-tools"
|
||||||
import {UUID, Long, Type, isType, } from "./model"
|
import {UUID, Long, Type, isType, } from "./model"
|
||||||
export namespace TypeResource {
|
export namespace TypeResource {
|
||||||
|
|
||||||
@ -85,33 +85,6 @@ export namespace TypeResource {
|
|||||||
data,
|
data,
|
||||||
}, isType);
|
}, isType);
|
||||||
};
|
};
|
||||||
/**
|
|
||||||
* Upload a new season cover Type
|
|
||||||
*/
|
|
||||||
export function uploadCover({ restConfig, params, data, progress, }: {
|
|
||||||
restConfig: RESTConfig,
|
|
||||||
params: {
|
|
||||||
id: Long,
|
|
||||||
},
|
|
||||||
data: {
|
|
||||||
fileName: string,
|
|
||||||
file: File,
|
|
||||||
},
|
|
||||||
progress?: ProgressCallback,
|
|
||||||
}): Promise<Type> {
|
|
||||||
return RESTRequestJson({
|
|
||||||
restModel: {
|
|
||||||
endPoint: "/type/{id}/cover",
|
|
||||||
requestType: HTTPRequestModel.POST,
|
|
||||||
contentType: HTTPMimeType.MULTIPART,
|
|
||||||
accept: HTTPMimeType.JSON,
|
|
||||||
},
|
|
||||||
restConfig,
|
|
||||||
params,
|
|
||||||
data,
|
|
||||||
progress,
|
|
||||||
}, isType);
|
|
||||||
};
|
|
||||||
/**
|
/**
|
||||||
* Get all Type
|
* Get all Type
|
||||||
*/
|
*/
|
||||||
@ -127,6 +100,33 @@ export namespace TypeResource {
|
|||||||
restConfig,
|
restConfig,
|
||||||
}, isType);
|
}, isType);
|
||||||
};
|
};
|
||||||
|
/**
|
||||||
|
* Upload a new season cover Type
|
||||||
|
*/
|
||||||
|
export function uploadCover({ restConfig, params, data, callback, }: {
|
||||||
|
restConfig: RESTConfig,
|
||||||
|
params: {
|
||||||
|
id: Long,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
fileName: string,
|
||||||
|
file: File,
|
||||||
|
},
|
||||||
|
callback?: RESTCallbacks,
|
||||||
|
}): Promise<Type> {
|
||||||
|
return RESTRequestJson({
|
||||||
|
restModel: {
|
||||||
|
endPoint: "/type/{id}/cover",
|
||||||
|
requestType: HTTPRequestModel.POST,
|
||||||
|
contentType: HTTPMimeType.MULTIPART,
|
||||||
|
accept: HTTPMimeType.JSON,
|
||||||
|
},
|
||||||
|
restConfig,
|
||||||
|
params,
|
||||||
|
data,
|
||||||
|
callback,
|
||||||
|
}, isType);
|
||||||
|
};
|
||||||
/**
|
/**
|
||||||
* Remove a specific cover of a type
|
* Remove a specific cover of a type
|
||||||
*/
|
*/
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* API of the server (auto-generated code)
|
* API of the server (auto-generated code)
|
||||||
*/
|
*/
|
||||||
import { HTTPMimeType, HTTPRequestModel, ModelResponseHttp, RESTConfig, ProgressCallback, RESTRequestJson, RESTRequestJsonArray, RESTRequestVoid } from "./rest-tools"
|
import { HTTPMimeType, HTTPRequestModel, ModelResponseHttp, RESTConfig, RESTCallbacks, RESTRequestJson, RESTRequestJsonArray, RESTRequestVoid } from "./rest-tools"
|
||||||
import {Long, UserMediaAdvancement, MediaInformationsDelta, isUserMediaAdvancement, } from "./model"
|
import {Long, UserMediaAdvancement, MediaInformationsDelta, isUserMediaAdvancement, } from "./model"
|
||||||
export namespace UserMediaAdvancementResource {
|
export namespace UserMediaAdvancementResource {
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* API of the server (auto-generated code)
|
* API of the server (auto-generated code)
|
||||||
*/
|
*/
|
||||||
import { HTTPMimeType, HTTPRequestModel, ModelResponseHttp, RESTConfig, ProgressCallback, RESTRequestJson, RESTRequestJsonArray, RESTRequestVoid } from "./rest-tools"
|
import { HTTPMimeType, HTTPRequestModel, ModelResponseHttp, RESTConfig, RESTCallbacks, RESTRequestJson, RESTRequestJsonArray, RESTRequestVoid } from "./rest-tools"
|
||||||
import {Long, UserKarideo, UserOut, isUserKarideo, isUserOut, } from "./model"
|
import {Long, UserKarideo, UserOut, isUserKarideo, isUserOut, } from "./model"
|
||||||
export namespace UserResource {
|
export namespace UserResource {
|
||||||
|
|
||||||
|
@ -147,7 +147,8 @@
|
|||||||
[mediaUploaded]="upload.mediaSendSize"
|
[mediaUploaded]="upload.mediaSendSize"
|
||||||
[mediaSize]="upload.mediaSize"
|
[mediaSize]="upload.mediaSize"
|
||||||
[result]="upload.result"
|
[result]="upload.result"
|
||||||
[error]="upload.error"></upload-progress>
|
[error]="upload.error"
|
||||||
|
(abort)="abortUpload()"></upload-progress>
|
||||||
<delete-confirm
|
<delete-confirm
|
||||||
[comment]="confirmDeleteComment"
|
[comment]="confirmDeleteComment"
|
||||||
[imageUrl]=confirmDeleteImageUrl
|
[imageUrl]=confirmDeleteImageUrl
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
import { PopInService, UploadProgress, isNumberFinite } from '@kangaroo-and-rabbit/kar-cw';
|
import { PopInService, UploadProgress, isNumberFinite } from '@kangaroo-and-rabbit/kar-cw';
|
||||||
import { Season, UUID } from 'app/back-api';
|
import { Season, UUID } from 'app/back-api';
|
||||||
|
import { RESTAbort } from 'app/back-api/rest-tools';
|
||||||
|
|
||||||
import { SeasonService, ArianeService, DataService } from 'app/service';
|
import { SeasonService, ArianeService, DataService } from 'app/service';
|
||||||
|
|
||||||
@ -29,11 +30,11 @@ export class SeasonEditScene implements OnInit {
|
|||||||
|
|
||||||
error: string = '';
|
error: string = '';
|
||||||
|
|
||||||
numberVal: number = null;
|
numberVal: string = null;
|
||||||
description: string = '';
|
description: string = '';
|
||||||
coverFile: File;
|
coverFile?: File;
|
||||||
uploadFileValue: string = '';
|
uploadFileValue: string = '';
|
||||||
selectedFiles: FileList;
|
selectedFiles?: FileList;
|
||||||
videoCount: string = null;
|
videoCount: string = null;
|
||||||
|
|
||||||
|
|
||||||
@ -45,6 +46,7 @@ export class SeasonEditScene implements OnInit {
|
|||||||
public confirmDeleteImageUrl: string = null;
|
public confirmDeleteImageUrl: string = null;
|
||||||
private deleteCoverId: UUID = null;
|
private deleteCoverId: UUID = null;
|
||||||
private deleteItemId: number = null;
|
private deleteItemId: number = null;
|
||||||
|
cancelHandle: RESTAbort = {};
|
||||||
deleteConfirmed() {
|
deleteConfirmed() {
|
||||||
if (this.deleteCoverId !== null) {
|
if (this.deleteCoverId !== null) {
|
||||||
this.removeCoverAfterConfirm(this.deleteCoverId);
|
this.removeCoverAfterConfirm(this.deleteCoverId);
|
||||||
@ -147,6 +149,10 @@ export class SeasonEditScene implements OnInit {
|
|||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abortUpload(): void {
|
||||||
|
this.cancelHandle.abort();
|
||||||
|
}
|
||||||
|
|
||||||
// At the file input element
|
// At the file input element
|
||||||
// (change)="selectFile($event)"
|
// (change)="selectFile($event)"
|
||||||
onChangeCover(value: any): void {
|
onChangeCover(value: any): void {
|
||||||
@ -169,7 +175,7 @@ export class SeasonEditScene implements OnInit {
|
|||||||
this.seasonService.uploadCover(this.idSeason, file, (count, total) => {
|
this.seasonService.uploadCover(this.idSeason, file, (count, total) => {
|
||||||
self.upload.mediaSendSize = count;
|
self.upload.mediaSendSize = count;
|
||||||
self.upload.mediaSize = total;
|
self.upload.mediaSize = total;
|
||||||
})
|
}, this.cancelHandle)
|
||||||
.then((response: any) => {
|
.then((response: any) => {
|
||||||
self.upload.result = 'Cover added done';
|
self.upload.result = 'Cover added done';
|
||||||
// we retrive the whiole media ==> update data ...
|
// we retrive the whiole media ==> update data ...
|
||||||
|
@ -171,7 +171,8 @@
|
|||||||
[mediaUploaded]="upload.mediaSendSize"
|
[mediaUploaded]="upload.mediaSendSize"
|
||||||
[mediaSize]="upload.mediaSize"
|
[mediaSize]="upload.mediaSize"
|
||||||
[result]="upload.result"
|
[result]="upload.result"
|
||||||
[error]="upload.error"></upload-progress>
|
[error]="upload.error"
|
||||||
|
(abort)="abortUpload()"></upload-progress>
|
||||||
<delete-confirm
|
<delete-confirm
|
||||||
[comment]="confirmDeleteComment"
|
[comment]="confirmDeleteComment"
|
||||||
[imageUrl]=confirmDeleteImageUrl
|
[imageUrl]=confirmDeleteImageUrl
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
import { PopInService, UploadProgress } from '@kangaroo-and-rabbit/kar-cw';
|
import { PopInService, UploadProgress } from '@kangaroo-and-rabbit/kar-cw';
|
||||||
import { UUID } from 'app/back-api';
|
import { UUID } from 'app/back-api';
|
||||||
|
import { RESTAbort } from 'app/back-api/rest-tools';
|
||||||
|
|
||||||
import { SeriesService, DataService, TypeService, ArianeService } from 'app/service';
|
import { SeriesService, DataService, TypeService, ArianeService } from 'app/service';
|
||||||
|
|
||||||
@ -55,6 +56,7 @@ export class SeriesEditScene implements OnInit {
|
|||||||
public confirmDeleteImageUrl: string = null;
|
public confirmDeleteImageUrl: string = null;
|
||||||
private deleteCoverId: UUID = null;
|
private deleteCoverId: UUID = null;
|
||||||
private deleteItemId: number = null;
|
private deleteItemId: number = null;
|
||||||
|
cancelHandle: RESTAbort = {};
|
||||||
deleteConfirmed() {
|
deleteConfirmed() {
|
||||||
if (this.deleteCoverId !== null) {
|
if (this.deleteCoverId !== null) {
|
||||||
this.removeCoverAfterConfirm(this.deleteCoverId);
|
this.removeCoverAfterConfirm(this.deleteCoverId);
|
||||||
@ -129,6 +131,10 @@ export class SeriesEditScene implements OnInit {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abortUpload(): void {
|
||||||
|
this.cancelHandle.abort();
|
||||||
|
}
|
||||||
|
|
||||||
updateCoverList(covers: any) {
|
updateCoverList(covers: any) {
|
||||||
this.coversDisplay = [];
|
this.coversDisplay = [];
|
||||||
if (covers !== undefined && covers !== null) {
|
if (covers !== undefined && covers !== null) {
|
||||||
@ -208,7 +214,7 @@ export class SeriesEditScene implements OnInit {
|
|||||||
this.seriesService.uploadCover(this.idSeries, file, (count, total) => {
|
this.seriesService.uploadCover(this.idSeries, file, (count, total) => {
|
||||||
self.upload.mediaSendSize = count;
|
self.upload.mediaSendSize = count;
|
||||||
self.upload.mediaSize = total;
|
self.upload.mediaSize = total;
|
||||||
})
|
}, this.cancelHandle)
|
||||||
.then((response: any) => {
|
.then((response: any) => {
|
||||||
self.upload.result = 'Cover added done';
|
self.upload.result = 'Cover added done';
|
||||||
// we retrive the whiole media ==> update data ...
|
// we retrive the whiole media ==> update data ...
|
||||||
|
44
front/src/app/scene/upload/file-drag-n-drop.directive.ts
Normal file
44
front/src/app/scene/upload/file-drag-n-drop.directive.ts
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
import { Directive, HostListener, HostBinding, Output, EventEmitter, Input } from '@angular/core';
|
||||||
|
|
||||||
|
@Directive({
|
||||||
|
selector: '[fileDragDrop]'
|
||||||
|
})
|
||||||
|
export class FileDragNDropDirective {
|
||||||
|
//@Input() private allowed_extensions : Array<string> = ['png', 'jpg', 'bmp'];
|
||||||
|
@Output() private filesChangeEmiter: EventEmitter<File[]> = new EventEmitter();
|
||||||
|
//@Output() private filesInvalidEmiter : EventEmitter<File[]> = new EventEmitter();
|
||||||
|
@HostBinding('style.background') private background = '#eee';
|
||||||
|
@HostBinding('style.border') private borderStyle = '2px dashed';
|
||||||
|
@HostBinding('style.border-color') private borderColor = '#696D7D';
|
||||||
|
@HostBinding('style.border-radius') private borderRadius = '10px';
|
||||||
|
|
||||||
|
constructor() { }
|
||||||
|
|
||||||
|
@HostListener('dragover', ['$event']) public onDragOver(evt) {
|
||||||
|
evt.preventDefault();
|
||||||
|
evt.stopPropagation();
|
||||||
|
this.background = 'lightgray';
|
||||||
|
this.borderColor = 'cadetblue';
|
||||||
|
this.borderStyle = '3px solid';
|
||||||
|
}
|
||||||
|
|
||||||
|
@HostListener('dragleave', ['$event']) public onDragLeave(evt) {
|
||||||
|
evt.preventDefault();
|
||||||
|
evt.stopPropagation();
|
||||||
|
this.background = '#eee';
|
||||||
|
this.borderColor = '#696D7D';
|
||||||
|
this.borderStyle = '2px dashed';
|
||||||
|
}
|
||||||
|
|
||||||
|
@HostListener('drop', ['$event']) public onDrop(evt) {
|
||||||
|
evt.preventDefault();
|
||||||
|
evt.stopPropagation();
|
||||||
|
this.background = '#eee';
|
||||||
|
this.borderColor = '#696D7D';
|
||||||
|
this.borderStyle = '2px dashed';
|
||||||
|
|
||||||
|
let files = evt.dataTransfer.files;
|
||||||
|
let valid_files: Array<File> = files;
|
||||||
|
this.filesChangeEmiter.emit(valid_files);
|
||||||
|
}
|
||||||
|
}
|
@ -3,34 +3,19 @@
|
|||||||
Upload Media
|
Upload Media
|
||||||
</div>
|
</div>
|
||||||
<div class="clear"><br/></div>
|
<div class="clear"><br/></div>
|
||||||
<div class="request_raw_table">
|
<div class="request_raw_table drop-area" fileDragDrop
|
||||||
<table>
|
(filesChangeEmiter)="onChangeFile($event)">
|
||||||
<colgroup>
|
<div class="clear"><br/></div>
|
||||||
<col style="width:10%">
|
<div class="centered">
|
||||||
<col style="width:80%">
|
<input type="file" name="file" id="file" (change)="onChangeFile($event.target.files)" multiple>
|
||||||
</colgroup>
|
<label for="file"><span class="textLink"><span class="material-icons">cloud_upload</span> Select your file</span> or <i>Drop it here!</i></label>
|
||||||
<tbody>
|
</div>
|
||||||
<tr>
|
<div class="clear"><br/></div>
|
||||||
<td class="left-colomn">format:</td>
|
<div class="centered">
|
||||||
<td class="right-colomn">
|
The format of the media permit to automatic find meta-data:<br/>
|
||||||
The format of the media permit to automatic find meta-data:<br/>
|
Univers:Series name-sXX-eXX-my name of my media.mkv<br/>
|
||||||
Univers:Series name-sXX-eXX-my name of my media.mkv<br/>
|
<b>example:</b> Stargate:SG1-s55-e22-Asgard.mkv <br/>
|
||||||
<b>example:</b> Stargate:SG1-s55-e22-Asgard.mkv <br/>
|
</div>
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td class="left-colomn">Media:</td>
|
|
||||||
<td class="right-colomn">
|
|
||||||
<input type="file"
|
|
||||||
(change)="onChangeFile($event.target)"
|
|
||||||
placeholder="Select a media file"
|
|
||||||
accept=".mkv,.webm"
|
|
||||||
width="90%"
|
|
||||||
multiple/>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
</div>
|
||||||
@if(parsedElement.length !== 0) {
|
@if(parsedElement.length !== 0) {
|
||||||
<div class="title">
|
<div class="title">
|
||||||
@ -210,11 +195,13 @@
|
|||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
<upload-progress [mediaTitle]="upload.labelMediaTitle"
|
<upload-progress
|
||||||
|
[mediaTitle]="upload.labelMediaTitle"
|
||||||
[mediaUploaded]="upload.mediaSendSize"
|
[mediaUploaded]="upload.mediaSendSize"
|
||||||
[mediaSize]="upload.mediaSize"
|
[mediaSize]="upload.mediaSize"
|
||||||
[result]="upload.result"
|
[result]="upload.result"
|
||||||
[error]="upload.error"></upload-progress>
|
[error]="upload.error"
|
||||||
|
(abort)="abortUpload()"></upload-progress>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
TODO: add a pop-in with:
|
TODO: add a pop-in with:
|
||||||
|
@ -1,43 +1,79 @@
|
|||||||
|
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
//background-color: green;
|
//background-color: green;
|
||||||
font-size: 45px;
|
font-size: 45px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
line-height: 60px;
|
line-height: 60px;
|
||||||
width:100%;
|
width: 100%;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
margin: 10px 0 10px 0;
|
margin: 10px 0 10px 0;
|
||||||
text-shadow: 1px 1px 2px white, 0 0 1em white, 0 0 0.2em white;
|
text-shadow: 1px 1px 2px white, 0 0 1em white, 0 0 0.2em white;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
font-family: "Roboto","Helvetica","Arial",sans-serif;
|
font-family: "Roboto", "Helvetica", "Arial", sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.drop-area {
|
||||||
|
height: 230px;
|
||||||
|
display: table;
|
||||||
|
width: 100%;
|
||||||
|
background-color: #eee;
|
||||||
|
border: dotted 1px #aaa;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-wrapper {
|
||||||
|
display: table-cell;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.centered {
|
||||||
|
font-family: sans-serif;
|
||||||
|
font-size: 1.3em;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.textLink {
|
||||||
|
background-color: #217500;
|
||||||
|
color: #fff;
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 5px;
|
||||||
|
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="file"] {
|
||||||
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.request_raw_table {
|
.request_raw_table {
|
||||||
display: block;
|
display: block;
|
||||||
width: 90%;
|
width: 90%;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
|
|
||||||
table {
|
table {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
th {
|
th {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
.left-colomn {
|
.left-colomn {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
|
||||||
input {
|
input {
|
||||||
width: 95%;
|
width: 95%;
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
border: 0px;
|
border: 0px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.right-colomn {
|
.right-colomn {
|
||||||
input {
|
input {
|
||||||
width: 95%;
|
width: 95%;
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
border: 0px;
|
border: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
width: 95%;
|
width: 95%;
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
@ -45,14 +81,16 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.error {
|
.error {
|
||||||
border-color: rgba(200,0,0,1.0);
|
border-color: rgba(200, 0, 0, 1.0);
|
||||||
background-color: rgba(256,220,220,1.0);
|
background-color: rgba(256, 220, 220, 1.0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.send_value {
|
.send_value {
|
||||||
width: 300px;
|
width: 300px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
@ -7,6 +7,7 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
import { PopInService, UploadProgress } from '@kangaroo-and-rabbit/kar-cw';
|
import { PopInService, UploadProgress } from '@kangaroo-and-rabbit/kar-cw';
|
||||||
import { Series } from 'app/back-api';
|
import { Series } from 'app/back-api';
|
||||||
|
import { RESTAbort } from 'app/back-api/rest-tools';
|
||||||
|
|
||||||
import { TypeService, SeriesService, MediaService, SeasonService } from 'app/service';
|
import { TypeService, SeriesService, MediaService, SeasonService } from 'app/service';
|
||||||
|
|
||||||
@ -51,7 +52,7 @@ export class UploadScene implements OnInit {
|
|||||||
selectedFiles: FileList;
|
selectedFiles: FileList;
|
||||||
typeId: number = null;
|
typeId: number = null;
|
||||||
seriesId: number = null;
|
seriesId: number = null;
|
||||||
saisonId: number = null;
|
seasonId: number = null;
|
||||||
needSend: boolean = false;
|
needSend: boolean = false;
|
||||||
|
|
||||||
// list of all files already registered in the bdd to compare with the current list of files.
|
// list of all files already registered in the bdd to compare with the current list of files.
|
||||||
@ -92,12 +93,14 @@ export class UploadScene implements OnInit {
|
|||||||
];
|
];
|
||||||
globalSeries: string = '';
|
globalSeries: string = '';
|
||||||
globalSeason: number = null;
|
globalSeason: number = null;
|
||||||
|
cancelHandle: RESTAbort = {};
|
||||||
constructor(
|
constructor(
|
||||||
private MediaService: MediaService,
|
private MediaService: MediaService,
|
||||||
private seasonService: SeasonService,
|
private seasonService: SeasonService,
|
||||||
private seriesService: SeriesService,
|
private seriesService: SeriesService,
|
||||||
private typeService: TypeService,
|
private typeService: TypeService,
|
||||||
private popInService: PopInService) {
|
private popInService: PopInService,
|
||||||
|
) {
|
||||||
// nothing to do.
|
// nothing to do.
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -238,7 +241,7 @@ export class UploadScene implements OnInit {
|
|||||||
|
|
||||||
this.typeId = null;
|
this.typeId = null;
|
||||||
this.seriesId = null;
|
this.seriesId = null;
|
||||||
this.saisonId = null;
|
this.seasonId = null;
|
||||||
this.listSeries = [{ value: null, label: '---' }];
|
this.listSeries = [{ value: null, label: '---' }];
|
||||||
this.listSeason = [{ value: null, label: '---' }];
|
this.listSeason = [{ value: null, label: '---' }];
|
||||||
}
|
}
|
||||||
@ -302,7 +305,7 @@ export class UploadScene implements OnInit {
|
|||||||
if (isNaN(season)) {
|
if (isNaN(season)) {
|
||||||
season = null;
|
season = null;
|
||||||
}
|
}
|
||||||
// remove extention
|
// remove extension
|
||||||
title = title.replace(new RegExp('\\.(mkv|MKV|Mkv|webm|WEBM|Webm|mp4)'), '');
|
title = title.replace(new RegExp('\\.(mkv|MKV|Mkv|webm|WEBM|Webm|mp4)'), '');
|
||||||
let tmp = new FileParsedElement(file, series, season, episode, title);
|
let tmp = new FileParsedElement(file, series, season, episode, title);
|
||||||
console.log(`==>${JSON.stringify(tmp)}`);
|
console.log(`==>${JSON.stringify(tmp)}`);
|
||||||
@ -310,14 +313,13 @@ export class UploadScene implements OnInit {
|
|||||||
this.parsedElement.push(tmp);
|
this.parsedElement.push(tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// At the file input element
|
// At the file input element
|
||||||
// (change)="selectFile($event)"
|
// (change)="selectFile($event)"
|
||||||
onChangeFile(value: any): void {
|
onChangeFile(files: File[]): void {
|
||||||
this.clearData();
|
this.clearData();
|
||||||
|
|
||||||
for (let iii = 0; iii < value.files.length; iii++) {
|
for (let iii = 0; iii < files.length; iii++) {
|
||||||
this.addFileWithMetaData(value.files[iii]);
|
this.addFileWithMetaData(files[iii]);
|
||||||
}
|
}
|
||||||
// check if all global parameters are generic:
|
// check if all global parameters are generic:
|
||||||
if (this.parsedElement.length === 0) {
|
if (this.parsedElement.length === 0) {
|
||||||
@ -350,7 +352,7 @@ export class UploadScene implements OnInit {
|
|||||||
|
|
||||||
this.updateNeedSend();
|
this.updateNeedSend();
|
||||||
this.seriesId = null;
|
this.seriesId = null;
|
||||||
this.saisonId = null;
|
this.seasonId = null;
|
||||||
let self = this;
|
let self = this;
|
||||||
if (this.globalSeries !== '') {
|
if (this.globalSeries !== '') {
|
||||||
this.seriesService.getLike(this.globalSeries)
|
this.seriesService.getLike(this.globalSeries)
|
||||||
@ -362,9 +364,9 @@ export class UploadScene implements OnInit {
|
|||||||
if (response.length === 0) {
|
if (response.length === 0) {
|
||||||
self.seriesId = null;
|
self.seriesId = null;
|
||||||
} else if (response.length === 1) {
|
} else if (response.length === 1) {
|
||||||
let serieElem = response[0];
|
let seriesElem = response[0];
|
||||||
self.seriesId = serieElem.id;
|
self.seriesId = seriesElem.id;
|
||||||
self.updateType(serieElem.parentId);
|
self.updateType(seriesElem.parentId);
|
||||||
}
|
}
|
||||||
self.updateListOfVideoToCheck();
|
self.updateListOfVideoToCheck();
|
||||||
}).catch((response) => {
|
}).catch((response) => {
|
||||||
@ -392,10 +394,11 @@ export class UploadScene implements OnInit {
|
|||||||
self.upload.result = 'Media creation done';
|
self.upload.result = 'Media creation done';
|
||||||
}
|
}
|
||||||
}, (value: string) => {
|
}, (value: string) => {
|
||||||
|
console.log("Detect error from serveur ...********************");
|
||||||
self.upload.error = `Error in the upload of the data...${value}`;
|
self.upload.error = `Error in the upload of the data...${value}`;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
uploadFile(eleemnent: FileParsedElement, id: number, total: number, sendDone: any, errorOccured: any): void {
|
uploadFile(element: FileParsedElement, id: number, total: number, sendDone: () => void, errorOccurred: (string) => void): void {
|
||||||
let self = this;
|
let self = this;
|
||||||
|
|
||||||
self.upload.labelMediaTitle = '';
|
self.upload.labelMediaTitle = '';
|
||||||
@ -414,37 +417,38 @@ export class UploadScene implements OnInit {
|
|||||||
self.upload.labelMediaTitle = `${self.upload.labelMediaTitle}s${self.globalSeason.toString()}`;
|
self.upload.labelMediaTitle = `${self.upload.labelMediaTitle}s${self.globalSeason.toString()}`;
|
||||||
}
|
}
|
||||||
// add episode ID
|
// add episode ID
|
||||||
if (eleemnent.episode !== null && eleemnent.episode !== undefined && eleemnent.episode.toString().length !== 0) {
|
if (element.episode !== null && element.episode !== undefined && element.episode.toString().length !== 0) {
|
||||||
if (self.upload.labelMediaTitle.length !== 0) {
|
if (self.upload.labelMediaTitle.length !== 0) {
|
||||||
self.upload.labelMediaTitle = `${self.upload.labelMediaTitle}-`;
|
self.upload.labelMediaTitle = `${self.upload.labelMediaTitle}-`;
|
||||||
}
|
}
|
||||||
self.upload.labelMediaTitle = `${self.upload.labelMediaTitle}e${eleemnent.episode.toString()}`;
|
self.upload.labelMediaTitle = `${self.upload.labelMediaTitle}e${element.episode.toString()}`;
|
||||||
}
|
}
|
||||||
// add title
|
// add title
|
||||||
if (self.upload.labelMediaTitle.length !== 0) {
|
if (self.upload.labelMediaTitle.length !== 0) {
|
||||||
self.upload.labelMediaTitle = `${self.upload.labelMediaTitle}-`;
|
self.upload.labelMediaTitle = `${self.upload.labelMediaTitle}-`;
|
||||||
}
|
}
|
||||||
self.upload.labelMediaTitle = `[${id + 1}/${total}]${self.upload.labelMediaTitle}${eleemnent.title}`;
|
self.upload.labelMediaTitle = `[${id + 1}/${total}]${self.upload.labelMediaTitle}${element.title}`;
|
||||||
|
|
||||||
self.MediaService.uploadFile(eleemnent.file,
|
self.MediaService.uploadFile(element.file,
|
||||||
self.globalSeries,
|
self.globalSeries,
|
||||||
self.seriesId,
|
self.seriesId,
|
||||||
self.globalSeason,
|
self.globalSeason,
|
||||||
eleemnent.episode,
|
element.episode,
|
||||||
eleemnent.title,
|
element.title,
|
||||||
self.typeId,
|
self.typeId,
|
||||||
(count, totalTmp) => {
|
(count, totalTmp) => {
|
||||||
// console.log("upload : " + count*100/totalTmp);
|
// console.log("upload : " + count*100/totalTmp);
|
||||||
self.upload.mediaSendSize = count;
|
self.upload.mediaSendSize = count;
|
||||||
self.upload.mediaSize = totalTmp;
|
self.upload.mediaSize = totalTmp;
|
||||||
})
|
}, this.cancelHandle)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
console.log(`get response of video : ${JSON.stringify(response, null, 2)}`);
|
console.log(`get response of video : ${JSON.stringify(response, null, 2)}`);
|
||||||
sendDone();
|
sendDone();
|
||||||
}).catch((response) => {
|
})
|
||||||
|
.catch((response) => {
|
||||||
// self.error = "Can not get the data";
|
// self.error = "Can not get the data";
|
||||||
console.log('Can not add the data in the system...');
|
console.log('Can not add the data in the system...');
|
||||||
errorOccured(JSON.stringify(response, null, 2));
|
errorOccurred(JSON.stringify(response, null, 2));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -518,7 +522,7 @@ export class UploadScene implements OnInit {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.saisonId = null;
|
self.seasonId = null;
|
||||||
// set 1 find the ID of the season:
|
// set 1 find the ID of the season:
|
||||||
this.seriesService.getSeason(this.seriesId)
|
this.seriesService.getSeason(this.seriesId)
|
||||||
.then((response: any[]) => {
|
.then((response: any[]) => {
|
||||||
@ -526,14 +530,14 @@ export class UploadScene implements OnInit {
|
|||||||
for (let iii = 0; iii < response.length; iii++) {
|
for (let iii = 0; iii < response.length; iii++) {
|
||||||
// console.log(" - " + JSON.stringify(response[iii]) + 'compare with : ' + JSON.stringify(self.globalSeason));
|
// console.log(" - " + JSON.stringify(response[iii]) + 'compare with : ' + JSON.stringify(self.globalSeason));
|
||||||
if (response[iii].name === `${self.globalSeason}`) {
|
if (response[iii].name === `${self.globalSeason}`) {
|
||||||
self.saisonId = response[iii].id;
|
self.seasonId = response[iii].id;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (self.saisonId === null) {
|
if (self.seasonId === null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
self.seasonService.getVideo(self.saisonId)
|
self.seasonService.getVideo(self.seasonId)
|
||||||
.then((response2: any[]) => {
|
.then((response2: any[]) => {
|
||||||
self.listFileInBdd = response2;
|
self.listFileInBdd = response2;
|
||||||
// console.log("find video: " + response2.length);
|
// console.log("find video: " + response2.length);
|
||||||
@ -549,6 +553,10 @@ export class UploadScene implements OnInit {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abortUpload(): void {
|
||||||
|
this.cancelHandle.abort();
|
||||||
|
}
|
||||||
|
|
||||||
eventPopUpSeason(event: string): void {
|
eventPopUpSeason(event: string): void {
|
||||||
console.log(`GET event: ${event}`);
|
console.log(`GET event: ${event}`);
|
||||||
this.popInService.close('popin-new-season');
|
this.popInService.close('popin-new-season');
|
||||||
@ -575,3 +583,7 @@ export class UploadScene implements OnInit {
|
|||||||
this.popInService.open('popin-create-type');
|
this.popInService.open('popin-create-type');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
function isNullOrUndefined(abort: () => boolean) {
|
||||||
|
throw new Error('Function not implemented.');
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -213,7 +213,8 @@
|
|||||||
[mediaUploaded]="upload.mediaSendSize"
|
[mediaUploaded]="upload.mediaSendSize"
|
||||||
[mediaSize]="upload.mediaSize"
|
[mediaSize]="upload.mediaSize"
|
||||||
[result]="upload.result"
|
[result]="upload.result"
|
||||||
[error]="upload.error"></upload-progress>
|
[error]="upload.error"
|
||||||
|
(abort)="abortUpload()"></upload-progress>
|
||||||
|
|
||||||
<delete-confirm
|
<delete-confirm
|
||||||
[comment]="confirmDeleteComment"
|
[comment]="confirmDeleteComment"
|
||||||
|
@ -9,6 +9,7 @@ import { Component, OnInit } from '@angular/core';
|
|||||||
import { DataService, TypeService, SeriesService, MediaService, ArianeService } from 'app/service';
|
import { DataService, TypeService, SeriesService, MediaService, ArianeService } from 'app/service';
|
||||||
import { PopInService, UploadProgress } from '@kangaroo-and-rabbit/kar-cw';
|
import { PopInService, UploadProgress } from '@kangaroo-and-rabbit/kar-cw';
|
||||||
import { Media, Season, Series, UUID } from 'app/back-api';
|
import { Media, Season, Series, UUID } from 'app/back-api';
|
||||||
|
import { RESTAbort } from 'app/back-api/rest-tools';
|
||||||
|
|
||||||
export interface ElementList {
|
export interface ElementList {
|
||||||
value?: number;
|
value?: number;
|
||||||
@ -90,6 +91,7 @@ export class VideoEditScene implements OnInit {
|
|||||||
listSeason: ElementList[] = [
|
listSeason: ElementList[] = [
|
||||||
{ value: undefined, label: '---' },
|
{ value: undefined, label: '---' },
|
||||||
];
|
];
|
||||||
|
cancelHandle: RESTAbort = {};
|
||||||
constructor(
|
constructor(
|
||||||
private dataService: DataService,
|
private dataService: DataService,
|
||||||
private MediaService: MediaService,
|
private MediaService: MediaService,
|
||||||
@ -101,6 +103,10 @@ export class VideoEditScene implements OnInit {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abortUpload(): void {
|
||||||
|
this.cancelHandle.abort();
|
||||||
|
}
|
||||||
|
|
||||||
updateNeedSend(): boolean {
|
updateNeedSend(): boolean {
|
||||||
this.needSend = false;
|
this.needSend = false;
|
||||||
if (this.data.name !== this.dataOri.name) {
|
if (this.data.name !== this.dataOri.name) {
|
||||||
@ -371,7 +377,7 @@ export class VideoEditScene implements OnInit {
|
|||||||
this.MediaService.uploadCover(this.idVideo, file, (count, total) => {
|
this.MediaService.uploadCover(this.idVideo, file, (count, total) => {
|
||||||
self.upload.mediaSendSize = count;
|
self.upload.mediaSendSize = count;
|
||||||
self.upload.mediaSize = total;
|
self.upload.mediaSize = total;
|
||||||
})
|
}, this.cancelHandle)
|
||||||
.then((response: any) => {
|
.then((response: any) => {
|
||||||
console.log(`get response of cover : ${JSON.stringify(response, null, 2)}`);
|
console.log(`get response of cover : ${JSON.stringify(response, null, 2)}`);
|
||||||
self.upload.result = 'Cover added done';
|
self.upload.result = 'Cover added done';
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { SessionService, DataStore } from '@kangaroo-and-rabbit/kar-cw';
|
import { SessionService, DataStore } from '@kangaroo-and-rabbit/kar-cw';
|
||||||
import { Media, MediaResource, UUID } from 'app/back-api';
|
import { Media, MediaResource, UUID } from 'app/back-api';
|
||||||
import { ProgressCallback, RESTConfig } from 'app/back-api/rest-tools';
|
import { ProgressCallback, RESTAbort, RESTConfig } from 'app/back-api/rest-tools';
|
||||||
import { environment } from 'environments/environment';
|
import { environment } from 'environments/environment';
|
||||||
import { GenericDataService } from './GenericDataService';
|
import { GenericDataService } from './GenericDataService';
|
||||||
|
|
||||||
@ -37,7 +37,8 @@ export class MediaService extends GenericDataService<Media> {
|
|||||||
episode?: number,
|
episode?: number,
|
||||||
title?: string,
|
title?: string,
|
||||||
typeId?: number,
|
typeId?: number,
|
||||||
progress: ProgressCallback | undefined = undefined) {
|
progress: ProgressCallback | undefined = undefined,
|
||||||
|
cancelHandle: RESTAbort | undefined = undefined) {
|
||||||
const formData = {
|
const formData = {
|
||||||
fileName: file.name,
|
fileName: file.name,
|
||||||
file,
|
file,
|
||||||
@ -52,7 +53,10 @@ export class MediaService extends GenericDataService<Media> {
|
|||||||
return MediaResource.uploadFile({
|
return MediaResource.uploadFile({
|
||||||
restConfig: this.getRestConfig(),
|
restConfig: this.getRestConfig(),
|
||||||
data: formData,
|
data: formData,
|
||||||
progress
|
callback: {
|
||||||
|
progressUpload: progress,
|
||||||
|
abortHandle: cancelHandle,
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,7 +114,8 @@ export class MediaService extends GenericDataService<Media> {
|
|||||||
}
|
}
|
||||||
uploadCover(id: number,
|
uploadCover(id: number,
|
||||||
file: File,
|
file: File,
|
||||||
progress: ProgressCallback | undefined = undefined): Promise<Media> {
|
progress: ProgressCallback | undefined = undefined,
|
||||||
|
cancelHandle: RESTAbort | undefined = undefined): Promise<Media> {
|
||||||
let self = this;
|
let self = this;
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
MediaResource.uploadCover({
|
MediaResource.uploadCover({
|
||||||
@ -122,7 +127,10 @@ export class MediaService extends GenericDataService<Media> {
|
|||||||
file,
|
file,
|
||||||
fileName: file.name
|
fileName: file.name
|
||||||
},
|
},
|
||||||
progress
|
callback: {
|
||||||
|
progressUpload: progress,
|
||||||
|
abortHandle: cancelHandle,
|
||||||
|
}
|
||||||
}).then((value) => {
|
}).then((value) => {
|
||||||
self.dataStore.updateValue(value);
|
self.dataStore.updateValue(value);
|
||||||
resolve(value);
|
resolve(value);
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { DataStore, SessionService, TypeCheck } from '@kangaroo-and-rabbit/kar-cw';
|
import { DataStore, SessionService, TypeCheck } from '@kangaroo-and-rabbit/kar-cw';
|
||||||
import { Media, Season, SeasonResource, UUID } from 'app/back-api';
|
import { Media, Season, SeasonResource, UUID } from 'app/back-api';
|
||||||
import { ProgressCallback, RESTConfig } from 'app/back-api/rest-tools';
|
import { ProgressCallback, RESTAbort, RESTConfig } from 'app/back-api/rest-tools';
|
||||||
import { environment } from 'environments/environment';
|
import { environment } from 'environments/environment';
|
||||||
import { GenericDataService } from './GenericDataService';
|
import { GenericDataService } from './GenericDataService';
|
||||||
import { MediaService } from './media';
|
import { MediaService } from './media';
|
||||||
@ -141,7 +141,8 @@ export class SeasonService extends GenericDataService<Season> {
|
|||||||
}
|
}
|
||||||
uploadCover(id: number,
|
uploadCover(id: number,
|
||||||
file: File,
|
file: File,
|
||||||
progress: ProgressCallback | undefined = undefined): Promise<Season> {
|
progress: ProgressCallback | undefined = undefined,
|
||||||
|
cancelHandle: RESTAbort | undefined = undefined): Promise<Season> {
|
||||||
let self = this;
|
let self = this;
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
SeasonResource.uploadCover({
|
SeasonResource.uploadCover({
|
||||||
@ -153,7 +154,10 @@ export class SeasonService extends GenericDataService<Season> {
|
|||||||
file,
|
file,
|
||||||
fileName: file.name
|
fileName: file.name
|
||||||
},
|
},
|
||||||
progress
|
callback: {
|
||||||
|
progressUpload: progress,
|
||||||
|
abortHandle: cancelHandle,
|
||||||
|
}
|
||||||
}).then((value) => {
|
}).then((value) => {
|
||||||
self.dataStore.updateValue(value);
|
self.dataStore.updateValue(value);
|
||||||
resolve(value);
|
resolve(value);
|
||||||
|
@ -8,7 +8,7 @@ import { Injectable } from '@angular/core';
|
|||||||
|
|
||||||
import { SessionService, DataStore, TypeCheck } from '@kangaroo-and-rabbit/kar-cw';
|
import { SessionService, DataStore, TypeCheck } from '@kangaroo-and-rabbit/kar-cw';
|
||||||
import { Media, Season, Series, SeriesResource, UUID } from 'app/back-api';
|
import { Media, Season, Series, SeriesResource, UUID } from 'app/back-api';
|
||||||
import { ProgressCallback, RESTConfig } from 'app/back-api/rest-tools';
|
import { ProgressCallback, RESTAbort, RESTConfig } from 'app/back-api/rest-tools';
|
||||||
import { environment } from 'environments/environment';
|
import { environment } from 'environments/environment';
|
||||||
import { GenericDataService } from './GenericDataService';
|
import { GenericDataService } from './GenericDataService';
|
||||||
import { SeasonService, MediaService } from '.';
|
import { SeasonService, MediaService } from '.';
|
||||||
@ -196,7 +196,8 @@ export class SeriesService extends GenericDataService<Series> {
|
|||||||
}
|
}
|
||||||
uploadCover(id: number,
|
uploadCover(id: number,
|
||||||
file: File,
|
file: File,
|
||||||
progress: ProgressCallback | undefined = undefined): Promise<Media> {
|
progress: ProgressCallback | undefined = undefined,
|
||||||
|
cancelHandle: RESTAbort | undefined = undefined): Promise<Media> {
|
||||||
let self = this;
|
let self = this;
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
SeriesResource.uploadCover({
|
SeriesResource.uploadCover({
|
||||||
@ -208,7 +209,10 @@ export class SeriesService extends GenericDataService<Series> {
|
|||||||
file,
|
file,
|
||||||
fileName: file.name
|
fileName: file.name
|
||||||
},
|
},
|
||||||
progress
|
callback: {
|
||||||
|
progressUpload: progress,
|
||||||
|
abortHandle: cancelHandle,
|
||||||
|
}
|
||||||
}).then((value) => {
|
}).then((value) => {
|
||||||
self.dataStore.updateValue(value);
|
self.dataStore.updateValue(value);
|
||||||
resolve(value);
|
resolve(value);
|
||||||
|
Loading…
Reference in New Issue
Block a user