ente/src/utils/upload/index.ts
2022-04-14 12:38:01 +05:30

95 lines
3.2 KiB
TypeScript

import { ElectronFile, FileWithCollection, Metadata } from 'types/upload';
import { EnteFile } from 'types/file';
import { convertBytesToHumanReadable } from 'utils/billing';
import { formatDateTime } from 'utils/file';
import { getLogs, saveLogLine } from 'utils/storage';
import { A_SEC_IN_MICROSECONDS } from 'constants/upload';
const TYPE_JSON = 'json';
const DEDUPE_COLLECTION = new Set(['icloud library', 'icloudlibrary']);
export function fileAlreadyInCollection(
existingFilesInCollection: EnteFile[],
newFileMetadata: Metadata
): boolean {
for (const existingFile of existingFilesInCollection) {
if (areFilesSame(existingFile.metadata, newFileMetadata)) {
return true;
}
}
return false;
}
export function shouldDedupeAcrossCollection(collectionName: string): boolean {
// using set to avoid unnecessary regex for removing spaces for each upload
return DEDUPE_COLLECTION.has(collectionName.toLocaleLowerCase());
}
export function areFilesSame(
existingFile: Metadata,
newFile: Metadata
): boolean {
/*
* The maximum difference in the creation/modification times of two similar files is set to 1 second.
* This is because while uploading files in the web - browsers and users could have set reduced
* precision of file times to prevent timing attacks and fingerprinting.
* Context: https://developer.mozilla.org/en-US/docs/Web/API/File/lastModified#reduced_time_precision
*/
if (
existingFile.fileType === newFile.fileType &&
Math.abs(existingFile.creationTime - newFile.creationTime) <
A_SEC_IN_MICROSECONDS &&
Math.abs(existingFile.modificationTime - newFile.modificationTime) <
A_SEC_IN_MICROSECONDS &&
existingFile.title === newFile.title
) {
return true;
} else {
return false;
}
}
export function segregateMetadataAndMediaFiles(
filesWithCollectionToUpload: FileWithCollection[]
) {
const metadataJSONFiles: FileWithCollection[] = [];
const mediaFiles: FileWithCollection[] = [];
filesWithCollectionToUpload.forEach((fileWithCollection) => {
const file = fileWithCollection.file;
if (file.name.startsWith('.')) {
// ignore files with name starting with . (hidden files)
return;
}
if (file.name.toLowerCase().endsWith(TYPE_JSON)) {
metadataJSONFiles.push(fileWithCollection);
} else {
mediaFiles.push(fileWithCollection);
}
});
return { mediaFiles, metadataJSONFiles };
}
export function logUploadInfo(log: string) {
saveLogLine({
type: 'upload',
timestamp: Date.now(),
logLine: log,
});
}
export function getUploadLogs() {
return getLogs()
.filter((log) => log.type === 'upload')
.map((log) => `[${formatDateTime(log.timestamp)}] ${log.logLine}`);
}
export function getFileNameSize(file: File | ElectronFile) {
return `${file.name}_${convertBytesToHumanReadable(file.size)}`;
}
export function areFileWithCollectionsSame(
firstFile: FileWithCollection,
secondFile: FileWithCollection
): boolean {
return firstFile.localID === secondFile.localID;
}