Prepare for inlining
This commit is contained in:
@@ -4,7 +4,7 @@ import { validateAndGetCreationUnixTimeInMicroSeconds } from "@ente/shared/time"
|
||||
import { NULL_LOCATION } from "constants/upload";
|
||||
import exifr from "exifr";
|
||||
import piexif from "piexifjs";
|
||||
import { Location } from "types/upload";
|
||||
import { Location, type ParsedExtractedMetadata } from "types/upload";
|
||||
|
||||
type ParsedEXIFData = Record<string, any> &
|
||||
Partial<{
|
||||
@@ -34,6 +34,60 @@ type RawEXIFData = Record<string, any> &
|
||||
ImageHeight: number;
|
||||
}>;
|
||||
|
||||
const EXIF_TAGS_NEEDED = [
|
||||
"DateTimeOriginal",
|
||||
"CreateDate",
|
||||
"ModifyDate",
|
||||
"GPSLatitude",
|
||||
"GPSLongitude",
|
||||
"GPSLatitudeRef",
|
||||
"GPSLongitudeRef",
|
||||
"DateCreated",
|
||||
"ExifImageWidth",
|
||||
"ExifImageHeight",
|
||||
"ImageWidth",
|
||||
"ImageHeight",
|
||||
"PixelXDimension",
|
||||
"PixelYDimension",
|
||||
"MetadataDate",
|
||||
];
|
||||
|
||||
/**
|
||||
* Read EXIF data from an image and use that to construct and return an
|
||||
* {@link ParsedExtractedMetadata}. This function is tailored for use when we
|
||||
* upload files.
|
||||
*
|
||||
* @param fileOrData The image {@link File}, or its contents.
|
||||
*/
|
||||
export const parseImageMetadata = async (
|
||||
fileOrData: File | Uint8Array,
|
||||
fileTypeInfo: FileTypeInfo,
|
||||
): Promise<ParsedExtractedMetadata> => {
|
||||
/*
|
||||
if (!(receivedFile instanceof File)) {
|
||||
receivedFile = new File(
|
||||
[await receivedFile.blob()],
|
||||
receivedFile.name,
|
||||
{
|
||||
lastModified: receivedFile.lastModified,
|
||||
},
|
||||
);
|
||||
}
|
||||
*/
|
||||
const exifData = await getParsedExifData(
|
||||
fileOrData,
|
||||
fileTypeInfo,
|
||||
EXIF_TAGS_NEEDED,
|
||||
);
|
||||
|
||||
return {
|
||||
location: getEXIFLocation(exifData),
|
||||
creationTime: getEXIFTime(exifData),
|
||||
width: exifData?.imageWidth ?? null,
|
||||
height: exifData?.imageHeight ?? null,
|
||||
};
|
||||
};
|
||||
|
||||
export async function getParsedExifData(
|
||||
receivedFile: File,
|
||||
{ extension }: FileTypeInfo,
|
||||
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
import type { DataStream } from "@ente/shared/utils/data-stream";
|
||||
import { Remote } from "comlink";
|
||||
import { FILE_READER_CHUNK_SIZE, NULL_LOCATION } from "constants/upload";
|
||||
import { getEXIFLocation, getEXIFTime, getParsedExifData } from "services/exif";
|
||||
import { parseImageMetadata } from "services/exif";
|
||||
import * as ffmpegService from "services/ffmpeg";
|
||||
import { getElectronFileStream, getFileStream } from "services/readerService";
|
||||
import { FilePublicMagicMetadataProps } from "types/file";
|
||||
@@ -30,24 +30,6 @@ import {
|
||||
} from "./takeout";
|
||||
import { getFileName } from "./uploadService";
|
||||
|
||||
const EXIF_TAGS_NEEDED = [
|
||||
"DateTimeOriginal",
|
||||
"CreateDate",
|
||||
"ModifyDate",
|
||||
"GPSLatitude",
|
||||
"GPSLongitude",
|
||||
"GPSLatitudeRef",
|
||||
"GPSLongitudeRef",
|
||||
"DateCreated",
|
||||
"ExifImageWidth",
|
||||
"ExifImageHeight",
|
||||
"ImageWidth",
|
||||
"ImageHeight",
|
||||
"PixelXDimension",
|
||||
"PixelYDimension",
|
||||
"MetadataDate",
|
||||
];
|
||||
|
||||
const NULL_EXTRACTED_METADATA: ParsedExtractedMetadata = {
|
||||
location: NULL_LOCATION,
|
||||
creationTime: null,
|
||||
@@ -84,6 +66,45 @@ export const extractAssetMetadata = async (
|
||||
);
|
||||
};
|
||||
|
||||
async function extractLivePhotoMetadata(
|
||||
worker: Remote<DedicatedCryptoWorker>,
|
||||
parsedMetadataJSONMap: Map<string, ParsedMetadataJSON>,
|
||||
collectionID: number,
|
||||
fileTypeInfo: FileTypeInfo,
|
||||
livePhotoAssets: LivePhotoAssets2,
|
||||
): Promise<ExtractMetadataResult> {
|
||||
const imageFileTypeInfo: FileTypeInfo = {
|
||||
fileType: FILE_TYPE.IMAGE,
|
||||
extension: fileTypeInfo.imageType,
|
||||
};
|
||||
const {
|
||||
metadata: imageMetadata,
|
||||
publicMagicMetadata: imagePublicMagicMetadata,
|
||||
} = await extractFileMetadata(
|
||||
worker,
|
||||
parsedMetadataJSONMap,
|
||||
collectionID,
|
||||
imageFileTypeInfo,
|
||||
livePhotoAssets.image,
|
||||
);
|
||||
const videoHash = await getFileHash(
|
||||
worker,
|
||||
/* TODO(MR): ElectronFile changes */
|
||||
livePhotoAssets.video as File | ElectronFile,
|
||||
);
|
||||
return {
|
||||
metadata: {
|
||||
...imageMetadata,
|
||||
title: getFileName(livePhotoAssets.image),
|
||||
fileType: FILE_TYPE.LIVE_PHOTO,
|
||||
imageHash: imageMetadata.hash,
|
||||
videoHash: videoHash,
|
||||
hash: undefined,
|
||||
},
|
||||
publicMagicMetadata: imagePublicMagicMetadata,
|
||||
};
|
||||
}
|
||||
|
||||
async function extractFileMetadata(
|
||||
worker: Remote<DedicatedCryptoWorker>,
|
||||
parsedMetadataJSONMap: Map<string, ParsedMetadataJSON>,
|
||||
@@ -152,7 +173,6 @@ async function getImageMetadata(
|
||||
receivedFile: File | ElectronFile,
|
||||
fileTypeInfo: FileTypeInfo,
|
||||
): Promise<ParsedExtractedMetadata> {
|
||||
let imageMetadata = NULL_EXTRACTED_METADATA;
|
||||
try {
|
||||
if (!(receivedFile instanceof File)) {
|
||||
receivedFile = new File(
|
||||
@@ -163,22 +183,11 @@ async function getImageMetadata(
|
||||
},
|
||||
);
|
||||
}
|
||||
const exifData = await getParsedExifData(
|
||||
receivedFile,
|
||||
fileTypeInfo,
|
||||
EXIF_TAGS_NEEDED,
|
||||
);
|
||||
|
||||
imageMetadata = {
|
||||
location: getEXIFLocation(exifData),
|
||||
creationTime: getEXIFTime(exifData),
|
||||
width: exifData?.imageWidth ?? null,
|
||||
height: exifData?.imageHeight ?? null,
|
||||
};
|
||||
return await parseImageMetadata(receivedFile, fileTypeInfo);
|
||||
} catch (e) {
|
||||
log.error("getExifData failed", e);
|
||||
log.error("Failed to parse image metadata", e);
|
||||
return NULL_EXTRACTED_METADATA;
|
||||
}
|
||||
return imageMetadata;
|
||||
}
|
||||
|
||||
// tries to extract date from file name if available else returns null
|
||||
@@ -237,45 +246,6 @@ async function getVideoMetadata(file: File | ElectronFile) {
|
||||
return videoMetadata;
|
||||
}
|
||||
|
||||
async function extractLivePhotoMetadata(
|
||||
worker: Remote<DedicatedCryptoWorker>,
|
||||
parsedMetadataJSONMap: Map<string, ParsedMetadataJSON>,
|
||||
collectionID: number,
|
||||
fileTypeInfo: FileTypeInfo,
|
||||
livePhotoAssets: LivePhotoAssets2,
|
||||
): Promise<ExtractMetadataResult> {
|
||||
const imageFileTypeInfo: FileTypeInfo = {
|
||||
fileType: FILE_TYPE.IMAGE,
|
||||
extension: fileTypeInfo.imageType,
|
||||
};
|
||||
const {
|
||||
metadata: imageMetadata,
|
||||
publicMagicMetadata: imagePublicMagicMetadata,
|
||||
} = await extractFileMetadata(
|
||||
worker,
|
||||
parsedMetadataJSONMap,
|
||||
collectionID,
|
||||
imageFileTypeInfo,
|
||||
livePhotoAssets.image,
|
||||
);
|
||||
const videoHash = await getFileHash(
|
||||
worker,
|
||||
/* TODO(MR): ElectronFile changes */
|
||||
livePhotoAssets.video as File | ElectronFile,
|
||||
);
|
||||
return {
|
||||
metadata: {
|
||||
...imageMetadata,
|
||||
title: getFileName(livePhotoAssets.image),
|
||||
fileType: FILE_TYPE.LIVE_PHOTO,
|
||||
imageHash: imageMetadata.hash,
|
||||
videoHash: videoHash,
|
||||
hash: undefined,
|
||||
},
|
||||
publicMagicMetadata: imagePublicMagicMetadata,
|
||||
};
|
||||
}
|
||||
|
||||
async function getFileHash(
|
||||
worker: Remote<DedicatedCryptoWorker>,
|
||||
file: File | ElectronFile,
|
||||
|
||||
Reference in New Issue
Block a user