Use
This commit is contained in:
@@ -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 };
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user