From 99066b8fea4f7890d5b404da0cf2ad6d91d3c5ad Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Sat, 27 Jul 2024 19:59:57 +0530 Subject: [PATCH] Use --- web/packages/media/file-metadata.ts | 12 +++----- web/packages/new/photos/services/exif.ts | 38 +++++++++++++----------- 2 files changed, 24 insertions(+), 26 deletions(-) diff --git a/web/packages/media/file-metadata.ts b/web/packages/media/file-metadata.ts index bfcd4128fd..528696e977 100644 --- a/web/packages/media/file-metadata.ts +++ b/web/packages/media/file-metadata.ts @@ -117,16 +117,12 @@ export interface ParsedMetadata { /** The height of the image, in pixels. */ height?: number; /** - * The date (and time) when this photo was taken. + * The date/time when this photo was taken. * - * This in the local timezone of the place where the photo was taken, but it - * also has additional fields we need. - * - * See: [Note: Photos are always in local date/time] + * Logically this is a date in local timezone of the place where the photo + * was taken. See: [Note: Photos are always in local date/time]. */ - creationMetadataDate?: ParsedMetadataDate /** TODO: Exif */; - /** The time when this photo was taken. */ - creationTime?: number; + creationDate?: ParsedMetadataDate; /** The GPS coordinates where the photo was taken. */ location?: { latitude: number; longitude: number }; } diff --git a/web/packages/new/photos/services/exif.ts b/web/packages/new/photos/services/exif.ts index 70ac7c5eca..4bc8e7289d 100644 --- a/web/packages/new/photos/services/exif.ts +++ b/web/packages/new/photos/services/exif.ts @@ -1,6 +1,10 @@ import { isDevBuild } from "@/base/env"; import log from "@/base/log"; -import type { ParsedMetadata } from "@/media/file-metadata"; +import { + parseMetadataDate, + type ParsedMetadata, + type ParsedMetadataDate, +} from "@/media/file-metadata"; import ExifReader from "exifreader"; import type { ParsedExtractedMetadata } from "../types/metadata"; import { isInternalUser } from "./feature-flags"; @@ -13,13 +17,13 @@ export const cmpNewLib = ( newLib: ParsedMetadata, ) => { if ( - oldLib.creationTime == newLib.creationTime && + oldLib.creationTime == newLib.creationDate?.timestamp && oldLib.location.latitude == newLib.location?.latitude && oldLib.location.longitude == newLib.location?.longitude ) { if (oldLib.width == newLib.width && oldLib.height == newLib.height) log.info("Exif migration ✅"); - else log.info("Exif migration 🟢"); + else log.info("Exif migration ✅✨"); log.debug(() => ["exif/cmp", { oldLib, newLib }]); } else { log.info("Exif migration - Potential mismatch ❗️🚩"); @@ -63,7 +67,7 @@ export const parseExif = (tags: RawExifTags) => { const dimensions = parseDimensions(tags); const metadata: ParsedMetadata = dimensions ?? {}; - if (creationDate) metadata.creationTime = creationDate.getTime() * 1000; + if (creationDate) metadata.creationDate = creationDate; if (location) metadata.location = location; return metadata; }; @@ -102,10 +106,10 @@ const parseCreationDate = (tags: RawExifTags) => { * correspond to the three Exif DateTime* tags, and the XMP MetadataDate tag. */ interface ParsedExifDates { - DateTimeOriginal: Date | undefined; - DateTimeDigitized: Date | undefined; - DateTime: Date | undefined; - MetadataDate: Date | undefined; + DateTimeOriginal: ParsedMetadataDate | undefined; + DateTimeDigitized: ParsedMetadataDate | undefined; + DateTime: ParsedMetadataDate | undefined; + MetadataDate: ParsedMetadataDate | undefined; } /** @@ -119,15 +123,13 @@ export const extractExifDates = (file: File): Promise => * grouping them into chunks that somewhat reflect the Exif ontology. */ const parseDates = (tags: RawExifTags) => { - // Ignore 0 and NaN + // Ignore dates whose epoch is 0. // // Some customers (not sure how prevalent this is) reported photos with Exif - // dates set to "0000:00:00 00:00:00". So we ignore any date whose epoch is - // 0, and try with a subsequent (possibly correct) date in the sequence. - // - // If the string we used to construct the date is invalid, then `getTime` - // will return `NaN`. Ignore these too. - const valid = (d: Date | undefined) => (d?.getTime() ? d : undefined); + // dates set to "0000:00:00 00:00:00". Ignore any date whose timestamp is 0 + // so that we try with a subsequent (possibly correct) date in the sequence. + const valid = (d: ParsedMetadataDate | undefined) => + d?.timestamp ? d : undefined; const exif = parseExifDates(tags); const iptc = parseIPTCDates(tags); @@ -258,7 +260,7 @@ const parseExifDate = ( // // For details see [Note: Exif dates] - return new Date( + return parseMetadataDate( dateString.replace(":", "-").replace(":", "-").replace(" ", "T") + (subSecString ? "." + subSecString : "") + (offsetString ?? ""), @@ -311,7 +313,7 @@ const parseXMPDate = (xmpTag: ExifReader.XmpTag | undefined) => { const s = xmpTag.value; if (typeof s != "string") return undefined; - return new Date(s); + return parseMetadataDate(s); }; /** @@ -374,7 +376,7 @@ const parseIPTCDate = ( if (timeTag) s = s + "T" + timeTag.description; - return new Date(s); + return parseMetadataDate(s); }; /**