google-photos-migrate
Version:
A tool to fix EXIF data and recover filenames from a Google Photos takeout.
90 lines (89 loc) • 4.05 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.migrateMediaFile = migrateMediaFile;
const path_1 = require("path");
const extensions_1 = require("../config/extensions");
const NoMetaFileError_1 = require("../meta/NoMetaFileError");
const apply_meta_errors_1 = require("../meta/apply-meta-errors");
const apply_meta_file_1 = require("../meta/apply-meta-file");
const find_meta_file_1 = require("../meta/find-meta-file");
const read_meta_title_1 = require("../meta/read-meta-title");
const InvalidExtError_1 = require("./InvalidExtError");
const save_to_dir_1 = require("./save-to-dir");
function applyExt(path, from, to) {
return path.slice(0, path.length - from.length) + to;
}
async function renameExt(migCtx, file, from, to) {
const destDir = (0, path_1.dirname)(file.path);
const saveBase = applyExt((0, path_1.basename)(file.path), from, to);
file.path = await (0, save_to_dir_1.saveToDir)(file.path, destDir, migCtx, true, saveBase);
return file.path;
}
function getOutExtRename(ext, metaTitle) {
const renames = (ext.aliases ?? []).filter((x) => typeof x === 'object');
return renames.find((r) => metaTitle.endsWith(r.suffix));
}
async function migrateMediaFile(originalPath, migCtx) {
const mediaFileInfo = {
originalPath,
path: originalPath,
};
const ext = extensions_1.supportedExtensions.reduce((longestMatch, cur) => {
if (!originalPath.endsWith(cur.suffix))
return longestMatch;
if (longestMatch === null)
return cur;
return cur.suffix.length > longestMatch.suffix.length
? cur
: longestMatch;
}, null);
if (!ext) {
mediaFileInfo.path = await (0, save_to_dir_1.saveToDir)(originalPath, migCtx.errorDir, migCtx);
return new InvalidExtError_1.InvalidExtError(mediaFileInfo);
}
const jsonPath = await (0, find_meta_file_1.findMetaFile)(originalPath, ext, migCtx);
if (!jsonPath) {
mediaFileInfo.path = await (0, save_to_dir_1.saveToDir)(originalPath, migCtx.errorDir, migCtx);
return new NoMetaFileError_1.NoMetaFileError(mediaFileInfo);
}
mediaFileInfo.jsonPath = jsonPath;
const metaBase = (await (0, read_meta_title_1.readMetaTitle)(mediaFileInfo)) ?? (0, path_1.basename)(mediaFileInfo.path);
const outExtRename = getOutExtRename(ext, metaBase ?? (0, path_1.basename)(mediaFileInfo.path));
const outBase = outExtRename
? applyExt(metaBase, outExtRename.suffix, outExtRename.out)
: metaBase;
mediaFileInfo.path = await (0, save_to_dir_1.saveToDir)(originalPath, migCtx.outputDir, migCtx, false, outBase);
const mediaFile = {
...mediaFileInfo,
ext,
jsonPath,
};
const err = await (0, apply_meta_file_1.applyMetaFile)(mediaFile, migCtx);
return handleApplyMetaErr(mediaFile, migCtx, err, outExtRename);
}
async function handleApplyMetaErr(mediaFile, migCtx, err, outExtRename) {
if (err) {
if (err instanceof apply_meta_errors_1.WrongExtensionError) {
if (migCtx.skipCorrections) {
return mediaFile;
}
if (outExtRename) {
migCtx.warnLog(`Extension ${err.currentExt} should be ${err.actualExt}, but was forcibly set: ${mediaFile.path}`);
return mediaFile;
}
await renameExt(migCtx, mediaFile, err.currentExt, err.actualExt);
migCtx.warnLog(`Renamed wrong extension ${err.currentExt} to ${err.actualExt}: ${mediaFile.path}`);
err = await (0, apply_meta_file_1.applyMetaFile)(mediaFile, migCtx);
if (!err) {
return mediaFile;
}
}
const savedPaths = await Promise.all([
(0, save_to_dir_1.saveToDir)(mediaFile.path, migCtx.errorDir, migCtx, true),
(0, save_to_dir_1.saveToDir)(mediaFile.jsonPath, migCtx.errorDir, migCtx),
]);
mediaFile.path = savedPaths[0];
return err;
}
return mediaFile;
}