142 lines
4.9 KiB
TypeScript
142 lines
4.9 KiB
TypeScript
import { File, FILE_TYPE } from 'services/fileService';
|
|
import { sleep } from 'utils/common';
|
|
import { handleUploadError, CustomError } from 'utils/common/errorUtil';
|
|
import { decryptFile } from 'utils/file';
|
|
import { logError } from 'utils/sentry';
|
|
import { fileAlreadyInCollection } from 'utils/upload';
|
|
import UploadHttpClient from './uploadHttpClient';
|
|
import UIService from './uiService';
|
|
import { FileUploadResults, FileWithCollection } from './uploadManager';
|
|
import UploadService, {
|
|
BackupedFile,
|
|
EncryptedFile,
|
|
FileInMemory,
|
|
FileWithMetadata,
|
|
MetadataObject,
|
|
UploadFile,
|
|
} from './uploadService';
|
|
import uploadService from './uploadService';
|
|
import { FileTypeInfo, getFileType } from './readFileService';
|
|
|
|
const TwoSecondInMillSeconds = 2000;
|
|
const FIVE_GB_IN_BYTES = 5 * 1024 * 1024 * 1024;
|
|
interface UploadResponse {
|
|
fileUploadResult: FileUploadResults;
|
|
file?: File;
|
|
}
|
|
export default async function uploader(
|
|
worker: any,
|
|
existingFilesInCollection: File[],
|
|
fileWithCollection: FileWithCollection
|
|
): Promise<UploadResponse> {
|
|
const { file: rawFile, collection } = fileWithCollection;
|
|
|
|
UIService.setFileProgress(rawFile.name, 0);
|
|
|
|
let file: FileInMemory = null;
|
|
let encryptedFile: EncryptedFile = null;
|
|
let metadata: MetadataObject = null;
|
|
let fileTypeInfo: FileTypeInfo = null;
|
|
let fileWithMetadata: FileWithMetadata = null;
|
|
|
|
try {
|
|
if (rawFile.size >= FIVE_GB_IN_BYTES) {
|
|
UIService.setFileProgress(
|
|
rawFile.name,
|
|
FileUploadResults.TOO_LARGE
|
|
);
|
|
// wait two second before removing the file from the progress in file section
|
|
await sleep(TwoSecondInMillSeconds);
|
|
return { fileUploadResult: FileUploadResults.TOO_LARGE };
|
|
}
|
|
fileTypeInfo = await getFileType(worker, rawFile);
|
|
if (fileTypeInfo.fileType === FILE_TYPE.OTHERS) {
|
|
throw Error(CustomError.UNSUPPORTED_FILE_FORMAT);
|
|
}
|
|
metadata = await uploadService.getFileMetadata(
|
|
rawFile,
|
|
collection,
|
|
fileTypeInfo
|
|
);
|
|
|
|
if (fileAlreadyInCollection(existingFilesInCollection, metadata)) {
|
|
UIService.setFileProgress(rawFile.name, FileUploadResults.SKIPPED);
|
|
// wait two second before removing the file from the progress in file section
|
|
await sleep(TwoSecondInMillSeconds);
|
|
return { fileUploadResult: FileUploadResults.SKIPPED };
|
|
}
|
|
|
|
file = await UploadService.readFile(worker, rawFile, fileTypeInfo);
|
|
if (file.hasStaticThumbnail) {
|
|
metadata.hasStaticThumbnail = true;
|
|
}
|
|
fileWithMetadata = {
|
|
filedata: file.filedata,
|
|
thumbnail: file.thumbnail,
|
|
metadata,
|
|
};
|
|
|
|
encryptedFile = await UploadService.encryptFile(
|
|
worker,
|
|
fileWithMetadata,
|
|
collection.key
|
|
);
|
|
|
|
const backupedFile: BackupedFile = await UploadService.uploadToBucket(
|
|
encryptedFile.file
|
|
);
|
|
|
|
const uploadFile: UploadFile = UploadService.getUploadFile(
|
|
collection,
|
|
backupedFile,
|
|
encryptedFile.fileKey
|
|
);
|
|
|
|
const uploadedFile = await UploadHttpClient.uploadFile(uploadFile);
|
|
const decryptedFile = await decryptFile(uploadedFile, collection);
|
|
|
|
UIService.setFileProgress(rawFile.name, FileUploadResults.UPLOADED);
|
|
UIService.increaseFileUploaded();
|
|
return {
|
|
fileUploadResult: FileUploadResults.UPLOADED,
|
|
file: decryptedFile,
|
|
};
|
|
} catch (e) {
|
|
logError(e, 'file upload failed', {
|
|
fileFormat: fileTypeInfo.exactType,
|
|
});
|
|
const error = handleUploadError(e);
|
|
switch (error.message) {
|
|
case CustomError.ETAG_MISSING:
|
|
UIService.setFileProgress(
|
|
rawFile.name,
|
|
FileUploadResults.BLOCKED
|
|
);
|
|
return { fileUploadResult: FileUploadResults.BLOCKED };
|
|
case CustomError.UNSUPPORTED_FILE_FORMAT:
|
|
UIService.setFileProgress(
|
|
rawFile.name,
|
|
FileUploadResults.UNSUPPORTED
|
|
);
|
|
return { fileUploadResult: FileUploadResults.UNSUPPORTED };
|
|
|
|
case CustomError.FILE_TOO_LARGE:
|
|
UIService.setFileProgress(
|
|
rawFile.name,
|
|
FileUploadResults.TOO_LARGE
|
|
);
|
|
return { fileUploadResult: FileUploadResults.TOO_LARGE };
|
|
default:
|
|
UIService.setFileProgress(
|
|
rawFile.name,
|
|
FileUploadResults.FAILED
|
|
);
|
|
return { fileUploadResult: FileUploadResults.FAILED };
|
|
}
|
|
} finally {
|
|
file = null;
|
|
fileWithMetadata = null;
|
|
encryptedFile = null;
|
|
}
|
|
}
|