Integrate

This commit is contained in:
Manav Rathi
2024-08-07 14:37:12 +05:30
parent 0a3182be53
commit 1fdeebed28
2 changed files with 35 additions and 34 deletions

View File

@@ -1,18 +1,22 @@
/** @file Dealing with the JSON metadata in Google Takeouts */
/** @file Dealing with the JSON metadata sidecar files */
import { ensureElectron } from "@/base/electron";
import { nameAndExtension } from "@/base/file";
import log from "@/base/log";
import type { UploadItem } from "@/new/photos/services/upload/types";
import { NULL_LOCATION } from "@/new/photos/services/upload/types";
import type { Location } from "@/new/photos/types/metadata";
import { readStream } from "@/new/photos/utils/native-stream";
/**
* The data we read from the JSON metadata sidecar files.
*
* Originally these were used to read the JSON metadata sidecar files present in
* a Google Takeout. However, during our own export, we also write out files
* with a similar structure.
*/
export interface ParsedMetadataJSON {
creationTime: number;
modificationTime: number;
latitude: number;
longitude: number;
creationTime?: number;
modificationTime?: number;
location?: { latitude: number; longitude: number };
}
export const MAX_FILE_NAME_LENGTH_GOOGLE_EXPORT = 46;
@@ -100,19 +104,13 @@ const uploadItemText = async (uploadItem: UploadItem) => {
}
};
const NULL_PARSED_METADATA_JSON: ParsedMetadataJSON = {
creationTime: null,
modificationTime: null,
...NULL_LOCATION,
};
const parseMetadataJSONText = (text: string) => {
const metadataJSON: object = JSON.parse(text);
if (!metadataJSON) {
return undefined;
}
const parsedMetadataJSON = { ...NULL_PARSED_METADATA_JSON };
const parsedMetadataJSON: ParsedMetadataJSON = {};
// The metadata provided by Google does not include the time zone where the
// photo was taken, it only has an epoch seconds value.
@@ -129,6 +127,7 @@ const parseMetadataJSONText = (text: string) => {
parsedMetadataJSON.creationTime =
metadataJSON["creationTime"]["timestamp"] * 1e6;
}
if (
metadataJSON["modificationTime"] &&
metadataJSON["modificationTime"]["timestamp"]
@@ -137,24 +136,26 @@ const parseMetadataJSONText = (text: string) => {
metadataJSON["modificationTime"]["timestamp"] * 1e6;
}
let locationData: Location = { ...NULL_LOCATION };
if (
metadataJSON["geoData"] &&
(metadataJSON["geoData"]["latitude"] !== 0.0 ||
metadataJSON["geoData"]["longitude"] !== 0.0)
) {
locationData = metadataJSON["geoData"];
parsedMetadataJSON.location = {
latitude: metadataJSON["geoData"]["latitude"],
longitude: metadataJSON["geoData"]["longitude"],
};
} else if (
metadataJSON["geoDataExif"] &&
(metadataJSON["geoDataExif"]["latitude"] !== 0.0 ||
metadataJSON["geoDataExif"]["longitude"] !== 0.0)
) {
locationData = metadataJSON["geoDataExif"];
}
if (locationData !== null) {
parsedMetadataJSON.latitude = locationData.latitude;
parsedMetadataJSON.longitude = locationData.longitude;
parsedMetadataJSON.location = {
latitude: metadataJSON["geoDataExif"]["latitude"],
longitude: metadataJSON["geoDataExif"]["longitude"],
};
}
return parsedMetadataJSON;
};

View File

@@ -763,14 +763,20 @@ const extractImageOrVideoMetadata = async (
const hash = await computeHash(uploadItem, worker);
const modificationTime = lastModifiedMs * 1000;
const parsedMetadataJSON = matchTakeoutMetadata(
fileName,
collectionID,
parsedMetadataJSONMap,
);
const modificationTime =
parsedMetadataJSON.modificationTime ?? lastModifiedMs * 1000;
const creationTime =
parsedMetadataJSON.creationTime ??
parsedMetadata.creationTime ??
tryParseEpochMicrosecondsFromFileName(fileName) ??
modificationTime;
const { width: w, height: h, location } = parsedMetadata;
const metadata: Metadata = {
fileType,
title: fileName,
@@ -778,25 +784,19 @@ const extractImageOrVideoMetadata = async (
modificationTime,
hash,
};
const location = parsedMetadataJSON.location ?? parsedMetadata.location;
if (location) {
metadata.latitude = location.latitude;
metadata.longitude = location.longitude;
}
const { width: w, height: h } = parsedMetadata;
const publicMagicMetadata: PublicMagicMetadata = {};
if (w) publicMagicMetadata.w = w;
if (h) publicMagicMetadata.h = h;
const takeoutMetadata = matchTakeoutMetadata(
fileName,
collectionID,
parsedMetadataJSONMap,
);
if (takeoutMetadata)
for (const [key, value] of Object.entries(takeoutMetadata))
if (value) metadata[key] = value;
return { metadata, publicMagicMetadata };
};