google-photos-migrate
Version:
A tool to fix EXIF data and recover filenames from a Google Photos takeout.
51 lines (50 loc) • 2.17 kB
JavaScript
import { mkdir, readdir } from 'fs/promises';
import { basename, join } from 'path';
import { untitledDirs } from '../config/langs.js';
import { migrateDirFlatGen } from './migrate-flat.js';
async function* _restructureAndProcess(folders, processingAlbums, // true for Albums, false for Photos
migCtx) {
for (const folder of folders) {
processingAlbums && migCtx.log(`Processing album ${folder}...`);
let albumName = processingAlbums ? basename(folder) : 'Photos';
for (const untitledName of untitledDirs) {
if (albumName.startsWith(`${untitledName}(`)) {
albumName = untitledName;
}
}
const outDir = `${migCtx.outputDir}/${albumName}`;
const errDir = `${migCtx.errorDir}/${albumName}`;
await mkdir(outDir, { recursive: true });
await mkdir(errDir, { recursive: true });
yield* migrateDirFlatGen({
...migCtx,
inputDir: folder,
outputDir: outDir,
errorDir: errDir,
});
}
}
export async function* restructureAndProcess(sourceDir, migCtx) {
// before
// $rootdir/My Album 1/*
// $rootdir/My Album 2/*
// $rootdir/Photos from 2008/*
// after
// $rootdir/AlbumsProcessed/My Album 1/*
// $rootdir/AlbumsProcessed/My Album 2/*
// $rootdir/PhotosProcessed/*
const dirents = await readdir(sourceDir, { withFileTypes: true });
const allDirs = dirents.filter((f) => f.isDirectory());
// move the "Photos from $YEAR" directories to Photos/
migCtx.log('Processing photos...');
const photosFromDirs = new Set(allDirs
.filter((f) => f.name === 'Photos' || f.name.startsWith('Photos from '))
.map((f) => join(f.parentPath, f.name)));
yield* _restructureAndProcess([...photosFromDirs], false, migCtx);
// move everythingg else to Albums/, so we end up with two top level folders
migCtx.log('Processing albums...');
const albumDirs = allDirs
.filter((f) => !photosFromDirs.has(join(f.parentPath, f.name)))
.map((f) => join(f.parentPath, f.name));
yield* _restructureAndProcess(albumDirs, true, migCtx);
}