UNPKG

google-photos-migrate

Version:

A tool to fix EXIF data and recover filenames from a Google Photos takeout.

80 lines (79 loc) 3.36 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.applyMetaFile = applyMetaFile; const promises_1 = require("fs/promises"); const ts_1 = require("../ts"); const MetaType_1 = require("./MetaType"); const apply_meta_errors_1 = require("./apply-meta-errors"); async function applyMetaFile(mediaFile, migCtx) { const metaJson = (await (0, promises_1.readFile)(mediaFile.jsonPath)).toString(); const meta = JSON.parse(metaJson); // time const timeTakenTimestamp = meta?.photoTakenTime?.timestamp; if (timeTakenTimestamp === undefined) return new apply_meta_errors_1.MissingMetaError(mediaFile, 'photoTakenTime'); const timeTaken = new Date(parseInt(timeTakenTimestamp) * 1000); // always UTC as per https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString const timeTakenUTC = timeTaken.toISOString(); const tags = {}; switch (mediaFile.ext.metaType) { case MetaType_1.MetaType.EXIF: tags.SubSecDateTimeOriginal = timeTakenUTC; tags.SubSecCreateDate = timeTakenUTC; tags.SubSecModifyDate = timeTakenUTC; break; case MetaType_1.MetaType.QUICKTIME: tags.DateTimeOriginal = timeTakenUTC; tags.CreateDate = timeTakenUTC; tags.ModifyDate = timeTakenUTC; tags.TrackCreateDate = timeTakenUTC; tags.TrackModifyDate = timeTakenUTC; tags.MediaCreateDate = timeTakenUTC; tags.MediaModifyDate = timeTakenUTC; break; case MetaType_1.MetaType.NONE: break; default: (0, ts_1.exhaustiveCheck)(mediaFile.ext.metaType); } tags.ModifyDate = timeTakenUTC; // description const description = meta?.description; tags.Description = description; tags['Caption-Abstract'] = description; tags.ImageDescription = description; // gps const [alt, lat, lon] = [ meta?.geoData?.altitude, meta?.geoData?.latitude, meta?.geoData?.longitude, ]; if (![alt, lat, lon].some((axis) => axis === undefined)) { tags.GPSAltitude = alt; tags.GPSAltitudeRef = `${alt}`; tags.GPSLatitude = lat; tags.GPSLatitudeRef = `${lat}`; tags.GPSLongitude = lon; tags.GPSLongitudeRef = `${lon}`; } try { await migCtx.exiftool.write(mediaFile.path, tags, { writeArgs: migCtx.exiftoolArgs, }); // Set file modification times to the photo taken timestamp await (0, promises_1.utimes)(mediaFile.path, timeTaken, timeTaken); } catch (e) { if (e instanceof Error) { const wrongExtMatch = e.message.match(/Not a valid (?<current>\w+) \(looks more like a (?<actual>\w+)\)/); const current = wrongExtMatch?.groups?.['current']; const actual = wrongExtMatch?.groups?.['actual']; if (current !== undefined && actual !== undefined) { return new apply_meta_errors_1.WrongExtensionError(mediaFile, `.${current.toLowerCase()}`, `.${actual.toLowerCase()}`); } return new apply_meta_errors_1.ExifToolError(mediaFile, e); } return new apply_meta_errors_1.ExifToolError(mediaFile, new Error(`${e}`)); } return null; }