This commit is contained in:
Manav Rathi
2024-08-02 14:18:57 +05:30
parent 4335df1634
commit 8a2d3600e9
2 changed files with 94 additions and 84 deletions

View File

@@ -1,3 +1,4 @@
import log from "@/base/log";
import type { ParsedMetadataDate } from "@/media/file-metadata";
import { PhotoDateTimePicker } from "@/new/photos/components/PhotoDateTimePicker";
import {
@@ -5,6 +6,7 @@ import {
type FixOption,
} from "@/new/photos/services/fix-exif";
import { EnteFile } from "@/new/photos/types/file";
import { fileLogID } from "@/new/photos/utils/file";
import DialogBox from "@ente/shared/components/DialogBox/";
import {
Button,
@@ -252,3 +254,31 @@ const Footer = ({ step, startFix, ...props }) => {
)
);
};
type SetProgressTracker = React.Dispatch<
React.SetStateAction<{
current: number;
total: number;
}>
>;
const updateFiles = async (
enteFiles: EnteFile[],
fixOption: FixOption,
customDate: ParsedMetadataDate,
setProgressTracker: SetProgressTracker,
) => {
setProgressTracker({ current: 0, total: enteFiles.length });
let hadErrors = false;
for (const [i, enteFile] of enteFiles.entries()) {
try {
await updateEnteFileDate(enteFile, fixOption, customDate);
} catch (e) {
log.error(`Failed to update date of ${fileLogID(enteFile)}`, e);
hadErrors = true;
} finally {
setProgressTracker({ current: i + 1, total: enteFiles.length });
}
}
return hadErrors;
};

View File

@@ -1,15 +1,14 @@
import log from "@/base/log";
import type { ParsedMetadataDate } from "@/media/file-metadata";
import {
changeFileCreationTime,
updateExistingFilePubMetadata,
} from "@/media/file-metadata";
import { FileType } from "@/media/file-type";
import downloadManager from "@/new/photos/services/download";
import type { EnteFile } from "@/new/photos/types/file";
import { detectFileTypeInfo } from "@/new/photos/utils/detect-type";
import { validateAndGetCreationUnixTimeInMicroSeconds } from "@ente/shared/time";
import { getParsedExifData } from "@ente/shared/utils/exif-old";
import {
changeFileCreationTime,
updateExistingFilePubMetadata,
} from "utils/file";
const EXIF_TIME_TAGS = [
"DateTimeOriginal",
@@ -19,93 +18,74 @@ const EXIF_TIME_TAGS = [
"MetadataDate",
];
export type SetProgressTracker = React.Dispatch<
React.SetStateAction<{
current: number;
total: number;
}>
>;
export type FixOption =
| "date-time-original"
| "date-time-digitized"
| "metadata-date"
| "custom";
export async function updateDateTimeOfEnteFiles(
filesToBeUpdated: EnteFile[],
/**
* Update the date associated with a given {@link enteFile}.
*
* This is generally viewed as the creation date of the underlying asset
* (photo, video, live photo) that this file stores.
*
* - For images, this function allows us to update this date from the
* Exif and other metadata embedded in the file.
*
* - For all types of files (including images), this function allows us to
* update this date to an explicitly provided value.
*
* If an Exif-involving {@link FixOption} is passed for an non-image file,
* then that file is just skipped over.
*
* Note that the metadata associated with a file is immutable, and we
* instead modify the mutable metadata section associated with the file. See
* [Note: Metadatum] for more details.
*/
export const updateEnteFileDate = async (
file: EnteFile,
fixOption: FixOption,
customDate: ParsedMetadataDate,
setProgressTracker: SetProgressTracker,
) {
let completedWithError = false;
try {
if (filesToBeUpdated.length === 0) {
return completedWithError;
) => {
let correctCreationTime: number | null;
if (fixOption === "custom") {
correctCreationTime = customDate.timestamp;
} else {
if (file.metadata.fileType !== FileType.image) {
return;
}
setProgressTracker({ current: 0, total: filesToBeUpdated.length });
for (const [index, file] of filesToBeUpdated.entries()) {
try {
let correctCreationTime: number;
if (fixOption === "custom-time") {
correctCreationTime = customDate.getTime() * 1000;
} else {
if (file.metadata.fileType !== FileType.image) {
continue;
}
const fileStream = await downloadManager.getFile(file);
const fileBlob = await new Response(fileStream).blob();
const fileObject = new File(
[fileBlob],
file.metadata.title,
);
const fileTypeInfo = await detectFileTypeInfo(fileObject);
const exifData = await getParsedExifData(
fileObject,
fileTypeInfo,
EXIF_TIME_TAGS,
);
if (fixOption === "date-time-original") {
correctCreationTime =
validateAndGetCreationUnixTimeInMicroSeconds(
exifData?.DateTimeOriginal ??
exifData?.DateCreated,
);
} else if (fixOption === "date-time-digitized") {
correctCreationTime =
validateAndGetCreationUnixTimeInMicroSeconds(
exifData?.CreateDate,
);
} else if (fixOption === "metadata-date") {
correctCreationTime =
validateAndGetCreationUnixTimeInMicroSeconds(
exifData?.MetadataDate,
);
}
}
if (
correctCreationTime &&
correctCreationTime !== file.metadata.creationTime
) {
const updatedFile = await changeFileCreationTime(
file,
correctCreationTime,
);
updateExistingFilePubMetadata(file, updatedFile);
}
} catch (e) {
log.error("failed to updated a CreationTime With Exif", e);
completedWithError = true;
} finally {
setProgressTracker({
current: index + 1,
total: filesToBeUpdated.length,
});
}
const fileStream = await downloadManager.getFile(file);
const fileBlob = await new Response(fileStream).blob();
const fileObject = new File([fileBlob], file.metadata.title);
const fileTypeInfo = await detectFileTypeInfo(fileObject);
const exifData = await getParsedExifData(
fileObject,
fileTypeInfo,
EXIF_TIME_TAGS,
);
if (fixOption === "date-time-original") {
correctCreationTime = validateAndGetCreationUnixTimeInMicroSeconds(
exifData?.DateTimeOriginal ?? exifData?.DateCreated,
);
} else if (fixOption === "date-time-digitized") {
correctCreationTime = validateAndGetCreationUnixTimeInMicroSeconds(
exifData?.CreateDate,
);
} else if (fixOption === "metadata-date") {
correctCreationTime = validateAndGetCreationUnixTimeInMicroSeconds(
exifData?.MetadataDate,
);
}
} catch (e) {
log.error("update CreationTime With Exif failed", e);
completedWithError = true;
}
return completedWithError;
}
if (
correctCreationTime &&
correctCreationTime !== file.metadata.creationTime
) {
const updatedFile = await changeFileCreationTime(
file,
correctCreationTime,
);
updateExistingFilePubMetadata(file, updatedFile);
}
};