mirror of
https://github.com/ente-io/ente.git
synced 2025-08-08 07:28:26 +00:00
Localize
This commit is contained in:
parent
142a1bd684
commit
8505383827
@ -5,7 +5,10 @@ import { ensureElectron } from "@/base/electron";
|
||||
import { basename, nameAndExtension } from "@/base/file-name";
|
||||
import log from "@/base/log";
|
||||
import { CustomErrorMessage } from "@/base/types/ipc";
|
||||
import { detectFileTypeInfoFromChunk } from "@/gallery/utils/detect-type";
|
||||
import {
|
||||
detectFileTypeInfoFromChunk,
|
||||
isFileTypeNotSupportedError,
|
||||
} from "@/gallery/utils/detect-type";
|
||||
import { readStream } from "@/gallery/utils/native-stream";
|
||||
import {
|
||||
EncryptedMagicMetadata,
|
||||
@ -539,8 +542,19 @@ export const uploader = async (
|
||||
* (tee will not work for strictly sequential reads of large streams).
|
||||
*/
|
||||
|
||||
const { fileTypeInfo, fileSize, lastModifiedMs } =
|
||||
await readAssetDetails(uploadAsset);
|
||||
let assetDetails: ReadAssetDetailsResult;
|
||||
|
||||
try {
|
||||
assetDetails = await readAssetDetails(uploadAsset);
|
||||
} catch (e) {
|
||||
if (isFileTypeNotSupportedError(e)) {
|
||||
log.error(`Not uploading ${fileName}`, e);
|
||||
return { uploadResult: UPLOAD_RESULT.UNSUPPORTED };
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
|
||||
const { fileTypeInfo, fileSize, lastModifiedMs } = assetDetails;
|
||||
|
||||
const maxFileSize = 4 * 1024 * 1024 * 1024; /* 4 GB */
|
||||
if (fileSize >= maxFileSize)
|
||||
@ -637,8 +651,6 @@ export const uploader = async (
|
||||
} catch (e) {
|
||||
if (e.message == CustomError.UPLOAD_CANCELLED) {
|
||||
log.info(`Upload for ${fileName} cancelled`);
|
||||
} else if (e.message == CustomError.UNSUPPORTED_FILE_FORMAT) {
|
||||
log.info(`Not uploading ${fileName}: unsupported file format`);
|
||||
} else {
|
||||
log.error(`Upload failed for ${fileName}`, e);
|
||||
}
|
||||
@ -647,8 +659,6 @@ export const uploader = async (
|
||||
switch (error.message) {
|
||||
case CustomError.ETAG_MISSING:
|
||||
return { uploadResult: UPLOAD_RESULT.BLOCKED };
|
||||
case CustomError.UNSUPPORTED_FILE_FORMAT:
|
||||
return { uploadResult: UPLOAD_RESULT.UNSUPPORTED };
|
||||
case CustomError.FILE_TOO_LARGE:
|
||||
return {
|
||||
uploadResult: UPLOAD_RESULT.LARGER_THAN_AVAILABLE_STORAGE,
|
||||
|
@ -5,21 +5,14 @@ import {
|
||||
KnownNonMediaFileExtensions,
|
||||
type FileTypeInfo,
|
||||
} from "@/media/file-type";
|
||||
import { CustomError } from "@ente/shared/error";
|
||||
import FileTypeDetect from "file-type";
|
||||
|
||||
/**
|
||||
* Read the file's initial contents or use the file's name to detect its type.
|
||||
*
|
||||
* This function first reads an initial chunk of the file and tries to detect
|
||||
* the file's {@link FileTypeInfo} from it. If that doesn't work, it then falls
|
||||
* back to using the file's name to detect it.
|
||||
*
|
||||
* If neither of these two approaches work, it throws an exception.
|
||||
*
|
||||
* If we were able to detect the file type, but it is explicitly not a media
|
||||
* (image or video) format that we support, this function throws an error with
|
||||
* the message `CustomError.UNSUPPORTED_FILE_FORMAT`.
|
||||
* This is a more convenient to use abstraction over
|
||||
* {@link detectFileTypeInfoFromChunk} for use when we already have a
|
||||
* {@link File} object. See that method's documentation for more details.
|
||||
*
|
||||
* @param file A {@link File} object
|
||||
*
|
||||
@ -37,7 +30,18 @@ export const detectFileTypeInfo = async (file: File): Promise<FileTypeInfo> =>
|
||||
* However, this lower level function is also exposed for use in cases like
|
||||
* during upload where we might not have a File object and would like to provide
|
||||
* the initial chunk of the file's contents in a different way.
|
||||
|
||||
* This function first reads an initial chunk of the file and tries to detect
|
||||
* the file's {@link FileTypeInfo} from it. If that doesn't work, it then falls
|
||||
* back to using the file's name to detect it.
|
||||
*
|
||||
* If neither of these two approaches work, it throws an exception.
|
||||
*
|
||||
* If we were able to detect the file type, but it is explicitly not a media
|
||||
* (image or video) format that we support, then also this function will throw
|
||||
* an exception. Such exceptions can be identified using the
|
||||
* {@link isFileTypeNotSupportedError} predicate.
|
||||
*
|
||||
* @param readInitialChunk A function to call to read the initial chunk of the
|
||||
* file's data. There is no strict requirement for the size of the chunk this
|
||||
* function should return, generally the first few KBs should be good.
|
||||
@ -63,7 +67,8 @@ export const detectFileTypeInfoFromChunk = async (
|
||||
} else if (mimeType.startsWith("video/")) {
|
||||
fileType = FileType.video;
|
||||
} else {
|
||||
throw new Error(CustomError.UNSUPPORTED_FILE_FORMAT);
|
||||
// This string should satisfy `isFileTypeNotSupportedError`.
|
||||
throw new Error(`Unsupported file format (MIME type ${mimeType})`);
|
||||
}
|
||||
|
||||
return {
|
||||
@ -78,13 +83,18 @@ export const detectFileTypeInfoFromChunk = async (
|
||||
const known = KnownFileTypeInfos.find((f) => f.extension == extension);
|
||||
if (known) return known;
|
||||
|
||||
if (extension && KnownNonMediaFileExtensions.includes(extension))
|
||||
throw Error(CustomError.UNSUPPORTED_FILE_FORMAT);
|
||||
if (extension && KnownNonMediaFileExtensions.includes(extension)) {
|
||||
// This string should satisfy `isFileTypeNotSupportedError`.
|
||||
throw new Error(`Unsupported file format (extension ${extension})`);
|
||||
}
|
||||
|
||||
throw e;
|
||||
}
|
||||
};
|
||||
|
||||
export const isFileTypeNotSupportedError = (e: unknown) =>
|
||||
e instanceof Error && e.message.startsWith("Unsupported file format");
|
||||
|
||||
const readInitialChunkOfFile = async (file: File) => {
|
||||
const chunkSizeForTypeDetection = 4100;
|
||||
const chunk = file.slice(0, chunkSizeForTypeDetection);
|
||||
|
@ -24,7 +24,6 @@ export function isApiErrorResponse(object: any): object is ApiErrorResponse {
|
||||
export const CustomError = {
|
||||
ETAG_MISSING: "no header/etag present in response body",
|
||||
KEY_MISSING: "encrypted key missing from localStorage",
|
||||
UNSUPPORTED_FILE_FORMAT: "unsupported file format",
|
||||
FILE_TOO_LARGE: "file too large",
|
||||
SUBSCRIPTION_EXPIRED: "subscription expired",
|
||||
STORAGE_QUOTA_EXCEEDED: "storage quota exceeded",
|
||||
|
Loading…
x
Reference in New Issue
Block a user