richard-loafle f6727a61c8 refactoring
2020-02-17 14:39:38 +09:00

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))
);
}
}