ente/src/services/migrateThumbnailService.ts
Shailesh Pandit d5199acc43 Extract common types in upload service to upload types
Required for not including code required for upload service in other parts just requiring common types
e.g. ffmpegService is included in machine learning web worker while including downloadManager service
2021-12-08 11:53:34 +05:30

149 lines
4.9 KiB
TypeScript

import downloadManager from 'services/downloadManager';
import { fileAttribute, getLocalFiles } from 'services/fileService';
import { generateThumbnail } from 'services/upload/thumbnailService';
import { getToken } from 'utils/common/key';
import { logError } from 'utils/sentry';
import { getEndpoint } from 'utils/common/apiUtil';
import HTTPService from 'services/HTTPService';
import CryptoWorker from 'utils/crypto';
import uploadHttpClient from 'services/upload/uploadHttpClient';
import { UploadURL } from 'services/upload/uploadService';
import { SetProgressTracker } from 'components/FixLargeThumbnail';
import { getFileType } from './upload/readFileService';
import { getLocalTrash, getTrashedFiles } from './trashService';
import { EncryptionResult } from 'types/upload';
const ENDPOINT = getEndpoint();
const REPLACE_THUMBNAIL_THRESHOLD = 500 * 1024; // 500KB
export async function getLargeThumbnailFiles() {
try {
const token = getToken();
if (!token) {
return;
}
const resp = await HTTPService.get(
`${ENDPOINT}/files/large-thumbnails`,
{
threshold: REPLACE_THUMBNAIL_THRESHOLD,
},
{
'X-Auth-Token': token,
}
);
return resp.data.largeThumbnailFiles as number[];
} catch (e) {
logError(e, 'failed to get large thumbnail files');
throw e;
}
}
export async function replaceThumbnail(
setProgressTracker: SetProgressTracker,
largeThumbnailFileIDs: Set<number>
) {
let completedWithError = false;
try {
const token = getToken();
const worker = await new CryptoWorker();
const files = await getLocalFiles();
const trash = await getLocalTrash();
const trashFiles = getTrashedFiles(trash);
const largeThumbnailFiles = [...files, ...trashFiles].filter((file) =>
largeThumbnailFileIDs.has(file.id)
);
if (largeThumbnailFileIDs.size !== largeThumbnailFiles.length) {
logError(Error(), 'all large thumbnail files not found locally');
}
if (largeThumbnailFiles.length === 0) {
return completedWithError;
}
setProgressTracker({ current: 0, total: largeThumbnailFiles.length });
const uploadURLs: UploadURL[] = [];
await uploadHttpClient.fetchUploadURLs(
largeThumbnailFiles.length,
uploadURLs
);
for (const [idx, file] of largeThumbnailFiles.entries()) {
try {
setProgressTracker({
current: idx,
total: largeThumbnailFiles.length,
});
const originalThumbnail = await downloadManager.downloadThumb(
token,
file
);
const dummyImageFile = new globalThis.File(
[originalThumbnail],
file.metadata.title
);
const fileTypeInfo = await getFileType(worker, dummyImageFile);
const { thumbnail: newThumbnail } = await generateThumbnail(
worker,
dummyImageFile,
fileTypeInfo
);
const newUploadedThumbnail = await uploadThumbnail(
worker,
file.key,
newThumbnail,
uploadURLs.pop()
);
await updateThumbnail(file.id, newUploadedThumbnail);
} catch (e) {
logError(e, 'failed to replace a thumbnail');
completedWithError = true;
}
}
} catch (e) {
logError(e, 'replace Thumbnail function failed');
completedWithError = true;
}
return completedWithError;
}
export async function uploadThumbnail(
worker,
fileKey: string,
updatedThumbnail: Uint8Array,
uploadURL: UploadURL
): Promise<fileAttribute> {
const { file: encryptedThumbnail }: EncryptionResult =
await worker.encryptThumbnail(updatedThumbnail, fileKey);
const thumbnailObjectKey = await uploadHttpClient.putFile(
uploadURL,
encryptedThumbnail.encryptedData as Uint8Array,
() => {}
);
return {
objectKey: thumbnailObjectKey,
decryptionHeader: encryptedThumbnail.decryptionHeader,
};
}
export async function updateThumbnail(
fileID: number,
newThumbnail: fileAttribute
) {
try {
const token = getToken();
if (!token) {
return;
}
await HTTPService.put(
`${ENDPOINT}/files/thumbnail`,
{
fileID: fileID,
thumbnail: newThumbnail,
},
null,
{
'X-Auth-Token': token,
}
);
} catch (e) {
logError(e, 'failed to update thumbnail');
throw e;
}
}