Commit 94c8925a authored by Florent POITTEVIN's avatar Florent POITTEVIN
Browse files

fix: use download service provided by solidify

parent e1be6f12
......@@ -169,6 +169,7 @@
"options": {
"browserTarget": "dlcm-frontend:build",
"proxyConfig": "proxy.conf.js",
"optimization": false,
"sourceMap": {
"scripts": true,
"styles": true,
......
......@@ -25,7 +25,6 @@ import {
urlSeparator,
} from "@shared/enums/routes.enum";
import {StateEnum} from "@shared/enums/state.enum";
import {DownloadService} from "@shared/services/download.service";
import {Observable} from "rxjs";
import {
catchError,
......@@ -34,6 +33,7 @@ import {
import {
ApiService,
defaultResourceStateInitValue,
DownloadService,
HttpStatus,
isNullOrUndefined,
isTrue,
......
......@@ -29,7 +29,6 @@ import {
import {ApiActionNameEnum} from "@shared/enums/api-action-name.enum";
import {LabelTranslateEnum} from "@shared/enums/label-translate.enum";
import {StateEnum} from "@shared/enums/state.enum";
import {DownloadService} from "@shared/services/download.service";
import {defaultStatusHistoryInitValue} from "@shared/stores/status-history/status-history.state";
import {Observable} from "rxjs";
import {
......@@ -43,6 +42,7 @@ import {
CompositionStateModel,
defaultCompositionStateInitValue,
defaultResourceStateInitValue,
DownloadService,
isNullOrUndefined,
MappingObjectUtil,
MARK_AS_TRANSLATABLE,
......
......@@ -9,10 +9,10 @@ import {
} from "@ngxs/store";
import {ApiEnum} from "@shared/enums/api.enum";
import {StateEnum} from "@shared/enums/state.enum";
import {DownloadService} from "@shared/services/download.service";
import {
ApiService,
defaultResourceStateInitValue,
DownloadService,
NotificationService,
ResourceState,
ResourceStateModel,
......
......@@ -78,7 +78,6 @@ import {StateEnum} from "@shared/enums/state.enum";
import {DataFile} from "@shared/models/business/data-file.model";
import {FileListModel} from "@shared/models/business/file-list.model";
import {LocalStateModel} from "@shared/models/local-state.model";
import {DownloadService} from "@shared/services/download.service";
import {SecurityService} from "@shared/services/security.service";
import {SharedLanguageAction} from "@shared/stores/language/shared-language.action";
import {ResourceLogoStateModel} from "@shared/stores/resource-logo/resource-logo-state.model";
......@@ -104,6 +103,7 @@ import {
defaultAssociationRemoteStateInitValue,
defaultResourceStateInitValue,
defaultUploadStateInitValue,
DownloadService,
ErrorHelper,
isEmptyArray,
isNonEmptyString,
......
......@@ -15,10 +15,10 @@ import {
preservationPlanningDepositActionNameSpace,
} from "@preservation-planning/deposit/stores/preservation-planning-deposit.action";
import {StateEnum} from "@shared/enums/state.enum";
import {DownloadService} from "@shared/services/download.service";
import {
ApiService,
defaultResourceStateInitValue,
DownloadService,
isNotNullNorUndefined,
isNullOrUndefined,
NotificationService,
......@@ -89,5 +89,4 @@ export class PreservationPlanningDepositState extends ResourceState<Preservation
this.downloadService.download(false, url, fileName + this._ZIP_EXTENSION);
}
}
......@@ -23,7 +23,6 @@ import {
} from "@preservation-planning/dip/stores/data-file/status-history/preservation-planning-dip-data-file-status-history.state";
import {LabelTranslateEnum} from "@shared/enums/label-translate.enum";
import {StateEnum} from "@shared/enums/state.enum";
import {DownloadService} from "@shared/services/download.service";
import {defaultStatusHistoryInitValue} from "@shared/stores/status-history/status-history.state";
import {Observable} from "rxjs";
import {
......@@ -35,6 +34,7 @@ import {
CompositionState,
CompositionStateModel,
defaultCompositionStateInitValue,
DownloadService,
NotificationService,
Result,
ResultActionStatusEnum,
......
......@@ -33,7 +33,6 @@ import {
RoutesEnum,
} from "@shared/enums/routes.enum";
import {StateEnum} from "@shared/enums/state.enum";
import {DownloadService} from "@shared/services/download.service";
import {defaultStatusHistoryInitValue} from "@shared/stores/status-history/status-history.state";
import {Observable} from "rxjs";
import {
......@@ -44,6 +43,7 @@ import {
ApiService,
defaultAssociationStateInitValue,
defaultResourceStateInitValue,
DownloadService,
isNullOrUndefined,
MARK_AS_TRANSLATABLE,
NotificationService,
......
......@@ -29,13 +29,13 @@ import {
urlSeparator,
} from "@shared/enums/routes.enum";
import {StateEnum} from "@shared/enums/state.enum";
import {DownloadService} from "@shared/services/download.service";
import {defaultStatusHistoryInitValue} from "@shared/stores/status-history/status-history.state";
import {
ApiService,
CompositionState,
CompositionStateModel,
defaultCompositionStateInitValue,
DownloadService,
NotificationService,
} from "solidify-frontend";
import {ApiActionNameEnum} from "../../../../../shared/enums/api-action-name.enum";
......
......@@ -23,7 +23,6 @@ import {
} from "@preservation-planning/sip/stores/data-file/status-history/preservation-planning-sip-data-file-status-history.state";
import {LabelTranslateEnum} from "@shared/enums/label-translate.enum";
import {StateEnum} from "@shared/enums/state.enum";
import {DownloadService} from "@shared/services/download.service";
import {defaultStatusHistoryInitValue} from "@shared/stores/status-history/status-history.state";
import {Observable} from "rxjs";
import {
......@@ -35,6 +34,7 @@ import {
CompositionState,
CompositionStateModel,
defaultCompositionStateInitValue,
DownloadService,
NotificationService,
Result,
ResultActionStatusEnum,
......
......@@ -25,7 +25,6 @@ import {
PreservationPlanningSipStatusHistoryStateModel,
} from "@preservation-planning/sip/stores/status-history/preservation-planning-sip-status-history.state";
import {StateEnum} from "@shared/enums/state.enum";
import {DownloadService} from "@shared/services/download.service";
import {defaultStatusHistoryInitValue} from "@shared/stores/status-history/status-history.state";
import {Observable} from "rxjs";
import {
......@@ -35,6 +34,7 @@ import {
import {
ApiService,
defaultResourceStateInitValue,
DownloadService,
isNullOrUndefined,
MARK_AS_TRANSLATABLE,
NotificationService,
......
......@@ -23,13 +23,13 @@ import {
SharedAipCollectionStatusHistoryStateModel,
} from "@shared/features/aip/stores/aip-collection/status-history/shared-aip-collection-status-history.state";
import {SharedAipAction} from "@shared/features/aip/stores/shared-aip.action";
import {DownloadService} from "@shared/services/download.service";
import {defaultStatusHistoryInitValue} from "@shared/stores/status-history/status-history.state";
import {
ApiService,
CompositionState,
CompositionStateModel,
defaultCompositionStateInitValue,
DownloadService,
NotificationService,
} from "solidify-frontend";
import {ApiActionNameEnum} from "../../../../enums/api-action-name.enum";
......
......@@ -21,7 +21,6 @@ import {
sharedAipDataFileActionNameSpace,
} from "@shared/features/aip/stores/aip-data-file/shared-aip-data-file.action";
import {SharedAipDataFileStatusHistoryState} from "@shared/features/aip/stores/aip-data-file/status-history/shared-aip-data-file-status-history.state";
import {DownloadService} from "@shared/services/download.service";
import {defaultStatusHistoryInitValue} from "@shared/stores/status-history/status-history.state";
import {Observable} from "rxjs";
import {
......@@ -33,6 +32,7 @@ import {
CompositionState,
CompositionStateModel,
defaultCompositionStateInitValue,
DownloadService,
NotificationService,
Result,
ResultActionStatusEnum,
......
......@@ -45,7 +45,6 @@ import {
SharedAipStatusHistoryState,
SharedAipStatusHistoryStateModel,
} from "@shared/features/aip/stores/status-history/shared-aip-status-history.state";
import {DownloadService} from "@shared/services/download.service";
import {defaultStatusHistoryInitValue} from "@shared/stores/status-history/status-history.state";
import {Observable} from "rxjs";
import {
......@@ -55,6 +54,7 @@ import {
import {
ApiService,
defaultResourceStateInitValue,
DownloadService,
isNullOrUndefined,
MARK_AS_TRANSLATABLE,
NotificationService,
......
import {
HttpClient,
HttpHeaders,
} from "@angular/common/http";
import {Injectable} from "@angular/core";
import {environment} from "@environments/environment";
import {DownloadToken} from "@models";
import {ApiEnum} from "@shared/enums/api.enum";
import {LabelTranslateEnum} from "@shared/enums/label-translate.enum";
import {urlSeparator} from "@shared/enums/routes.enum";
import {saveAs} from "file-saver";
import {
from,
Observable,
} from "rxjs";
import {
catchError,
take,
tap,
} from "rxjs/operators";
import {
AbstractBaseService,
ApiService,
HttpStatus,
isNotNullNorUndefined,
isNullOrUndefined,
isTrue,
NotificationService,
OAuth2Service,
SolidifyHttpErrorResponseModel,
} from "solidify-frontend";
import streamSaver from "streamsaver";
import {WritableStream} from "web-streams-polyfill/ponyfill";
@Injectable({
providedIn: "root",
})
export class DownloadService extends AbstractBaseService {
constructor(private readonly _oauth2Service: OAuth2Service,
private readonly _httpClient: HttpClient,
private readonly _apiService: ApiService,
private readonly _notificationService: NotificationService) {
super();
}
download(isPublic: boolean, url: string, fileName: string, size?: number, archiveId?: string): void {
this._notificationService.showInformation(LabelTranslateEnum.fileDownloadStart);
if (isPublic) {
this.downloadBrowserNatif(url);
} else {
if (isNotNullNorUndefined(archiveId) && environment.production) {
this._getAndStoreDownloadTokenThenDownload(url, archiveId);
} else {
this._downloadPrivateWithoutDownloadToken(url, fileName, size);
}
}
}
downloadBrowserNatif(url: string): void {
window.open(url, "_self");
}
private _downloadPrivateWithoutDownloadToken(url: string, fileName: string, size?: number): void {
this.subscribe(this.downloadWithMitm(url, fileName, size).pipe(
tap(result => {
if (result === HttpStatus.OK) {
this._notificationService.showSuccess(LabelTranslateEnum.fileDownloadedSuccessfully);
} else if (result === HttpStatus.FORBIDDEN) {
this._notificationService.showError(LabelTranslateEnum.fileDownloadForbidden);
} else {
this._notificationService.showSuccess(LabelTranslateEnum.fileDownloadFail);
}
}),
));
}
private _getAndStoreDownloadTokenThenDownload(url: string, archiveId: string): void {
this.subscribe(this._httpClient.get<DownloadToken>(ApiEnum.accessDownloadToken + urlSeparator + archiveId, {
withCredentials: true,
}).pipe(
take(1),
tap(result => {
this.downloadBrowserNatif(url);
}),
catchError((error: SolidifyHttpErrorResponseModel) => {
this._notificationService.showError(LabelTranslateEnum.fileDownloadForbidden);
throw error;
}),
));
}
downloadWithMitm(url: string, fileName: string, size?: number): Observable<number> {
if (isNullOrUndefined(streamSaver.WritableStream)) {
streamSaver.WritableStream = WritableStream;
}
if (isTrue(environment.useSelfHostedStreamSaverMitm)) {
// Allow to avoid to see download from https://jimmywarting.github.io/StreamSaver.js
streamSaver.mitm = window.location.origin + window.location.pathname.replace(/\/[^\/]+$/, "/") + "mitm.html";
}
const fileStream = streamSaver.createWriteStream(fileName, {
size: size,
writableStrategy: undefined,
readableStrategy: undefined,
});
const requestHeaders: HeadersInit = new Headers();
requestHeaders.set("Content-Type", "application/json");
const token = this._oauth2Service.getAccessToken();
if (!isNullOrUndefined(token)) {
requestHeaders.set("Authorization", "Bearer " + token);
}
const fetchResult = fetch(url, {
headers: requestHeaders,
}).then(res => {
if (res.status !== HttpStatus.OK) {
return res.status;
}
const readableStream = res.body;
// const readableStream = new ReadableStream(res.body); // TODO To allow optimize version on firefox but half work and break Chrome download
const writableStream = streamSaver.WritableStream;
// Optimized way for supported browser (like Chrome)
if (writableStream && readableStream.pipeTo) {
return readableStream.pipeTo(fileStream)
.then(() => HttpStatus.OK);
}
// Standard way for other browser (like Firefox)
const writer = fileStream.getWriter();
const reader = res.body.getReader();
const pump = () => reader.read()
.then(result => {
if (result.done) {
writer.close();
return HttpStatus.OK;
} else {
writer.write(result.value).then(pump);
return HttpStatus.OK;
}
});
return pump();
});
return from(fetchResult);
}
// Prefer use download api to stream directly on disk
downloadInMemory(url: string, fileName: string, withSaveAs: boolean = true): Observable<Blob> {
let headers = new HttpHeaders();
headers = headers.set("Content-Disposition", "attachment; filename=" + fileName);
return this._httpClient.get(url, {
headers,
responseType: "blob",
}).pipe(tap((blobContent: Blob) => {
if (withSaveAs) {
saveAs(blobContent, fileName);
}
}));
}
}
......@@ -21,7 +21,6 @@ import {LabelTranslateEnum} from "@shared/enums/label-translate.enum";
import {urlSeparator} from "@shared/enums/routes.enum";
import {StateEnum} from "@shared/enums/state.enum";
import {ArchiveHelper} from "@shared/helpers/archive.helper";
import {DownloadService} from "@shared/services/download.service";
import {
SharedArchiveAction,
sharedArchiveActionNameSpace,
......@@ -45,6 +44,7 @@ import {
ApiService,
CollectionTyped,
defaultResourceStateInitValue,
DownloadService,
ErrorDto,
HttpStatus,
isFalse,
......
......@@ -17,11 +17,11 @@ import {
} from "@ngxs/store";
import {LabelTranslateEnum} from "@shared/enums/label-translate.enum";
import {StateEnum} from "@shared/enums/state.enum";
import {DownloadService} from "@shared/services/download.service";
import {Observable} from "rxjs/index";
import {
ApiService,
defaultResourceStateInitValue,
DownloadService,
NotificationService,
ResourceState,
ResourceStateModel,
......
......@@ -12,12 +12,12 @@ import {PreservationPlanningDipDataFileAction} from "@preservation-planning/dip/
import {ApiResourceNameEnum} from "@shared/enums/api-resource-name.enum";
import {ApiEnum} from "@shared/enums/api.enum";
import {StateEnum} from "@shared/enums/state.enum";
import {DownloadService} from "@shared/services/download.service";
import {
ApiService,
CompositionState,
CompositionStateModel,
defaultCompositionStateInitValue,
DownloadService,
NotificationService,
} from "solidify-frontend";
import {ApiActionNameEnum} from "../../../../shared/enums/api-action-name.enum";
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment