448 lines
12 KiB
TypeScript
448 lines
12 KiB
TypeScript
import { Injectable, Inject, ChangeDetectorRef } from '@angular/core';
|
|
import {
|
|
HttpClient,
|
|
HttpEventType,
|
|
HttpResponse,
|
|
HttpRequest
|
|
} from '@angular/common/http';
|
|
|
|
import { Observable, Subject } from 'rxjs';
|
|
import { map, filter } from 'rxjs/operators';
|
|
|
|
import {
|
|
FileProfileSaveRequest,
|
|
FileProfileSaveResponse,
|
|
encodeFileProfileSave,
|
|
decodeFileProfileSave
|
|
} from '../apis/file-profile-save';
|
|
import {
|
|
FileTalkDownloadRequest,
|
|
encodeFileTalkDownload,
|
|
encodeFormDataFileTalkDownload
|
|
} from '../apis/file-talk-download';
|
|
import {
|
|
FileTalkSaveRequest,
|
|
FileTalkSaveResponse,
|
|
encodeFileTalkSave,
|
|
decodeFileTalkSave
|
|
} from '../apis/file-talk-save';
|
|
import {
|
|
FileTalkShareRequest,
|
|
FileTalkShareResponse,
|
|
encodeFileTalkShare,
|
|
decodeFileTalkShare
|
|
} from '../apis/file-talk-share';
|
|
import {
|
|
MassTalkDownloadRequest,
|
|
MassTalkDownloadResponse,
|
|
encodeMassTalkDownload,
|
|
decodeMassTalkDownload
|
|
} from '../apis/mass-talk-download';
|
|
import {
|
|
MassTalkSaveRequest,
|
|
MassTalkSaveResponse,
|
|
encodeMassTalkSave,
|
|
decodeMassTalkSave
|
|
} from '../apis/mass-talk-save';
|
|
import {
|
|
TransMassTalkDownloadRequest,
|
|
TransMassTalkDownloadResponse,
|
|
encodeTransMassTalkDownload,
|
|
decodeTransMassTalkDownload
|
|
} from '../apis/trans-mass-talk-download';
|
|
import {
|
|
TransMassTalkSaveRequest,
|
|
TransMassTalkSaveResponse,
|
|
encodeTransMassTalkSave,
|
|
decodeTransMassTalkSave
|
|
} from '../apis/trans-mass-talk-save';
|
|
import {
|
|
TranslationReqRequest,
|
|
TranslationReqResponse,
|
|
encodeTranslationReq,
|
|
decodeTranslationReq
|
|
} from '../apis/translation-req';
|
|
import {
|
|
TranslationSaveRequest,
|
|
TranslationSaveResponse,
|
|
encodeTranslationSave,
|
|
decodeTranslationSave
|
|
} from '../apis/translation-save';
|
|
|
|
import { _MODULE_CONFIG } from '../config/token';
|
|
import { ModuleConfig } from '../config/module-config';
|
|
import { Urls } from '../config/urls';
|
|
import { UrlConfig, MimeUtil, FileUtil } from '@ucap-webmessenger/core';
|
|
|
|
@Injectable({
|
|
providedIn: 'root'
|
|
})
|
|
export class CommonApiService {
|
|
readonly urls: Urls;
|
|
|
|
constructor(
|
|
@Inject(_MODULE_CONFIG) private moduleConfig: ModuleConfig,
|
|
private httpClient: HttpClient
|
|
) {
|
|
this.urls = UrlConfig.getUrls(
|
|
this.moduleConfig.hostConfig,
|
|
this.moduleConfig.urls
|
|
);
|
|
}
|
|
|
|
public fileProfileSave(
|
|
req: FileProfileSaveRequest,
|
|
fileProfileSaveUrl?: string
|
|
): Observable<FileProfileSaveResponse> {
|
|
const httpReq = new HttpRequest(
|
|
'POST',
|
|
!!fileProfileSaveUrl ? fileProfileSaveUrl : this.urls.fileProfileSave,
|
|
encodeFileProfileSave(req),
|
|
{ reportProgress: true, responseType: 'text' as 'json' }
|
|
);
|
|
|
|
const progress = req.fileUploadItem.uploadStart();
|
|
|
|
return this.httpClient.request(httpReq).pipe(
|
|
filter(event => {
|
|
if (event instanceof HttpResponse) {
|
|
return true;
|
|
} else if (HttpEventType.UploadProgress === event.type) {
|
|
progress.next(Math.round((100 * event.loaded) / event.total));
|
|
}
|
|
return false;
|
|
}),
|
|
map((event: HttpResponse<any>) => {
|
|
req.fileUploadItem.uploadComplete();
|
|
return decodeFileProfileSave(event.body);
|
|
})
|
|
);
|
|
}
|
|
|
|
public urlForFileTalkDownload(
|
|
req: FileTalkDownloadRequest,
|
|
fileTalkDownloadUrl?: string
|
|
): string {
|
|
const httpReq = new HttpRequest(
|
|
'GET',
|
|
!!fileTalkDownloadUrl ? fileTalkDownloadUrl : this.urls.fileTalkDownload,
|
|
{},
|
|
{
|
|
params: encodeFileTalkDownload(req)
|
|
}
|
|
);
|
|
|
|
return httpReq.urlWithParams;
|
|
}
|
|
|
|
public fileTalkDownload(
|
|
req: FileTalkDownloadRequest,
|
|
fileTalkDownloadUrl?: string
|
|
): Observable<Blob> {
|
|
const httpReq = new HttpRequest(
|
|
'POST',
|
|
!!fileTalkDownloadUrl ? fileTalkDownloadUrl : this.urls.fileTalkDownload,
|
|
encodeFormDataFileTalkDownload(req),
|
|
{ reportProgress: true, responseType: 'blob' }
|
|
);
|
|
|
|
let progress: Subject<number>;
|
|
if (!!req.fileDownloadItem) {
|
|
progress = req.fileDownloadItem.downloadStart();
|
|
}
|
|
|
|
return this.httpClient.request(httpReq).pipe(
|
|
filter(event => {
|
|
if (event instanceof HttpResponse) {
|
|
return true;
|
|
} else if (HttpEventType.DownloadProgress === event.type) {
|
|
if (!!progress) {
|
|
progress.next(Math.round((100 * event.loaded) / event.total));
|
|
}
|
|
}
|
|
return false;
|
|
}),
|
|
map((event: HttpResponse<any>) => {
|
|
if (!!progress) {
|
|
req.fileDownloadItem.downloadComplete();
|
|
}
|
|
return event.body;
|
|
})
|
|
);
|
|
}
|
|
|
|
public fileTalkSave(
|
|
req: FileTalkSaveRequest,
|
|
fileTalkSaveUrl?: string
|
|
): Observable<FileTalkSaveResponse> {
|
|
const httpReq = new HttpRequest(
|
|
'POST',
|
|
!!fileTalkSaveUrl ? fileTalkSaveUrl : this.urls.fileTalkSave,
|
|
encodeFileTalkSave(req),
|
|
{
|
|
reportProgress: true,
|
|
responseType: 'text' as 'json'
|
|
}
|
|
);
|
|
|
|
const progress = req.fileUploadItem.uploadStart();
|
|
|
|
return this.httpClient.request(httpReq).pipe(
|
|
filter(event => {
|
|
if (event instanceof HttpResponse) {
|
|
return true;
|
|
} else if (HttpEventType.UploadProgress === event.type) {
|
|
progress.next(Math.round((100 * event.loaded) / event.total));
|
|
}
|
|
return false;
|
|
}),
|
|
map((event: HttpResponse<any>) => {
|
|
req.fileUploadItem.uploadComplete();
|
|
return decodeFileTalkSave(event.body);
|
|
})
|
|
);
|
|
}
|
|
|
|
public acceptableExtensionForFileTalk(extensions: string[]): string[] {
|
|
const rejected: string[] = [];
|
|
for (const extension of extensions) {
|
|
if (
|
|
!extension ||
|
|
-1 ===
|
|
this.moduleConfig.acceptableFileExtensions.indexOf(
|
|
extension.toLowerCase()
|
|
)
|
|
) {
|
|
rejected.push(!!extension ? extension : 'empty-ext');
|
|
}
|
|
}
|
|
return 0 === rejected.length ? undefined : rejected;
|
|
}
|
|
|
|
public checkInvalidMediaMimeForFileTalk(files: File[]): Promise<string[]> {
|
|
return new Promise<string[]>(async (resolve, reject) => {
|
|
const mediaFiles = this.mediaFiles(files);
|
|
if (!mediaFiles) {
|
|
resolve(undefined);
|
|
return;
|
|
}
|
|
|
|
const rejected: string[] = [];
|
|
for (const file of mediaFiles) {
|
|
const info = await MimeUtil.getMimeFromBuffer(
|
|
await FileUtil.fromBlobToBuffer(file)
|
|
);
|
|
if (
|
|
!file ||
|
|
!info ||
|
|
(-1 === info.mime.indexOf('video/') &&
|
|
-1 === info.mime.indexOf('image/'))
|
|
) {
|
|
rejected.push(file.name);
|
|
}
|
|
}
|
|
|
|
resolve(0 === rejected.length ? undefined : rejected);
|
|
|
|
return;
|
|
});
|
|
}
|
|
|
|
mediaFiles(files: File[]): File[] {
|
|
const filtered: File[] = [];
|
|
|
|
for (const file of files) {
|
|
const extension = FileUtil.getExtension(file.name).toLocaleLowerCase();
|
|
if (
|
|
!!file &&
|
|
-1 !==
|
|
this.moduleConfig.acceptableFileExtensionsForImage.indexOf(extension)
|
|
) {
|
|
filtered.push(file);
|
|
}
|
|
if (
|
|
!!file &&
|
|
-1 !==
|
|
this.moduleConfig.acceptableFileExtensionsForVideo.indexOf(extension)
|
|
) {
|
|
filtered.push(file);
|
|
}
|
|
}
|
|
|
|
return 0 < filtered.length ? filtered : undefined;
|
|
}
|
|
|
|
/** @deprecated */
|
|
public mimeCheckForImageAndVideoFiles(files: File[]) {
|
|
files.forEach(file => {
|
|
console.log(file);
|
|
const fileReader = new FileReader();
|
|
fileReader.onloadend = () => {
|
|
const arr = new Uint8Array(fileReader.result as ArrayBuffer).subarray(
|
|
0,
|
|
4
|
|
);
|
|
let header = '';
|
|
for (let i = 0; i < arr.length; i++) {
|
|
header += arr[i].toString(16);
|
|
}
|
|
console.log('File header: ' + header);
|
|
|
|
// Check the file signature against known types
|
|
var type = 'unknown';
|
|
// http://forensic-proof.com/archives/300?ckattempt=1
|
|
|
|
if (header.startsWith('89504e47')) {
|
|
// 89504E470D0A1A0A
|
|
type = 'image/png';
|
|
} else if (header.startsWith('47494638')) {
|
|
// 474946383761
|
|
// 474946383961
|
|
type = 'image/gif';
|
|
} else if (header.startsWith('ffd8ffe')) {
|
|
// ffd8ffe0
|
|
// ffd8ffe1
|
|
// ffd8ffe2
|
|
// ffd8ffe8
|
|
type = 'image/jpeg';
|
|
} else if (header.startsWith('424d')) {
|
|
type = 'image/bmp';
|
|
} else if (header.startsWith('4d4d') || header.startsWith('4949')) {
|
|
type = 'image/tiff';
|
|
} else if (header.startsWith('4F676753')) {
|
|
// 4F67675300020000
|
|
type = 'image/ogg';
|
|
} else if (header.startsWith('38425053')) {
|
|
// 38 42 50 53
|
|
type = 'image/psd';
|
|
} else if (header.startsWith('25504446')) {
|
|
// 38 42 50 53
|
|
type = 'image/ai';
|
|
} else if (header.startsWith('52494646')) {
|
|
// avi
|
|
type = 'video/x-msvideo';
|
|
} else if (header.startsWith('00000018')) {
|
|
// 0000001866747970
|
|
type = 'video/x-msvideo';
|
|
}
|
|
|
|
console.log('type', type);
|
|
};
|
|
fileReader.readAsArrayBuffer(file);
|
|
});
|
|
}
|
|
|
|
public fileTalkShare(
|
|
req: FileTalkShareRequest
|
|
): Observable<FileTalkShareResponse> {
|
|
return this.httpClient
|
|
.post<any>(
|
|
this.urls.fileTalkShare,
|
|
{},
|
|
{
|
|
params: encodeFileTalkShare(req)
|
|
}
|
|
)
|
|
.pipe(map(res => decodeFileTalkShare(res)));
|
|
}
|
|
|
|
public massTalkDownload(
|
|
req: MassTalkDownloadRequest
|
|
): Observable<MassTalkDownloadResponse> {
|
|
return this.httpClient
|
|
.post<any>(
|
|
this.urls.massTalkDownload,
|
|
{},
|
|
{
|
|
params: encodeMassTalkDownload(req),
|
|
responseType: 'text' as 'json'
|
|
}
|
|
)
|
|
.pipe(map(res => decodeMassTalkDownload(res)));
|
|
}
|
|
|
|
public massTalkSave(
|
|
req: MassTalkSaveRequest
|
|
): Observable<MassTalkSaveResponse> {
|
|
const httpReq = new HttpRequest(
|
|
'POST',
|
|
this.urls.massTalkSave,
|
|
encodeMassTalkSave(req),
|
|
{ reportProgress: true, responseType: 'text' as 'json' }
|
|
);
|
|
|
|
return this.httpClient.request(httpReq).pipe(
|
|
filter(event => {
|
|
if (event instanceof HttpResponse) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}),
|
|
map(res => decodeMassTalkSave((res as HttpResponse<any>).body))
|
|
);
|
|
}
|
|
|
|
public transMassTalkDownload(
|
|
req: TransMassTalkDownloadRequest
|
|
): Observable<TransMassTalkDownloadResponse> {
|
|
return this.httpClient
|
|
.post<any>(
|
|
this.urls.transMassTalkDownload,
|
|
{},
|
|
{
|
|
params: encodeTransMassTalkDownload(req)
|
|
}
|
|
)
|
|
.pipe(map(res => decodeTransMassTalkDownload(res)));
|
|
}
|
|
|
|
public transMassTalkSave(
|
|
req: TransMassTalkSaveRequest
|
|
): Observable<TransMassTalkSaveResponse> {
|
|
return this.httpClient
|
|
.post<any>(
|
|
this.urls.transMassTalkSave,
|
|
{},
|
|
{
|
|
params: encodeTransMassTalkSave(req)
|
|
}
|
|
)
|
|
.pipe(map(res => decodeTransMassTalkSave(res)));
|
|
}
|
|
|
|
public translationReq(
|
|
req: TranslationReqRequest
|
|
): Observable<TranslationReqResponse> {
|
|
return this.httpClient
|
|
.post<any>(
|
|
this.urls.translationReq,
|
|
{},
|
|
{
|
|
params: encodeTranslationReq(req)
|
|
}
|
|
)
|
|
.pipe(map(res => decodeTranslationReq(res)));
|
|
}
|
|
|
|
public translationSave(
|
|
req: TranslationSaveRequest
|
|
): Observable<TranslationSaveResponse> {
|
|
const httpReq = new HttpRequest(
|
|
'POST',
|
|
this.urls.translationSave,
|
|
encodeTranslationSave(req),
|
|
{ reportProgress: true }
|
|
);
|
|
|
|
return this.httpClient.request(httpReq).pipe(
|
|
filter(event => {
|
|
if (event instanceof HttpResponse) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}),
|
|
map(res => decodeTranslationSave((res as HttpResponse<any>).body))
|
|
);
|
|
}
|
|
}
|