This commit is contained in:
Manav Rathi
2024-07-27 19:59:57 +05:30
parent 487fd62feb
commit 99066b8fea
2 changed files with 24 additions and 26 deletions

View File

@@ -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 };
}

View File

@@ -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<ParsedExifDates> =>
* 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);
};
/**