diff --git a/bin/quak.ts b/bin/quak.ts index 4ac077a..1d9e48d 100644 --- a/bin/quak.ts +++ b/bin/quak.ts @@ -340,23 +340,26 @@ program "Dump all decrypted account metadata to a directory of JSON files", ) .argument("", "Output directory") - .option( - "--ml", - "Include ML data (face detections, CLIP embeddings) from the Ente server", - ) + .option("--no-ml", "Skip ML data (face detections, CLIP embeddings)") .option( "--exif", "Download each file and extract full EXIF/IPTC/XMP metadata (slow)", ) - .action(async (dir: string, opts: { ml?: boolean; exif?: boolean }) => { - await init(); - const client = requireSession(); - await runMetadataBackup(client, dir, { - mlData: opts.ml, - exif: opts.exif, - onProgress: (msg) => stderr.write(msg + "\n"), - }); - }); + .option("--all", "Alias for --exif") + .action( + async ( + dir: string, + opts: { ml?: boolean; exif?: boolean; all?: boolean }, + ) => { + await init(); + const client = requireSession(); + await runMetadataBackup(client, dir, { + mlData: opts.ml, + exif: opts.exif || opts.all, + onProgress: (msg) => stderr.write(msg + "\n"), + }); + }, + ); program .command("backup") diff --git a/src/metadata-backup.ts b/src/metadata-backup.ts index 26034cd..b44f47f 100644 --- a/src/metadata-backup.ts +++ b/src/metadata-backup.ts @@ -120,7 +120,7 @@ export const runMetadataBackup = async ( opts?: MetadataBackupOptions, ): Promise => { const log = opts?.onProgress ?? (() => {}); - const wantML = opts?.mlData ?? false; + const wantML = opts?.mlData ?? true; const wantExif = opts?.exif ?? false; mkdirSync(outDir, { recursive: true }); diff --git a/test/cli/metadata-backup.test.ts b/test/cli/metadata-backup.test.ts index c6aae7a..09cc746 100644 --- a/test/cli/metadata-backup.test.ts +++ b/test/cli/metadata-backup.test.ts @@ -587,8 +587,8 @@ describe("quak backup-metadata", () => { expect(fileMeta.mlData.clip.embedding).toEqual([0.5, 0.6, 0.7]); }); - it("does not include ML data when --ml is not set", async () => { - const outDir = join(testDir, "no-ml"); + it("includes ML data by default", async () => { + const outDir = join(testDir, "ml-default"); const client = await Client.login({ email: TEST_EMAIL, password: TEST_PASSWORD, @@ -597,6 +597,28 @@ describe("quak backup-metadata", () => { await runMetadataBackup(client, outDir); + const collDirs = readdirSync(join(outDir, "collections")); + const vacDir = collDirs.find((d) => d.includes("Vacation"))!; + const fileMeta = JSON.parse( + readFileSync( + join(outDir, "collections", vacDir, "100.json"), + "utf-8", + ), + ); + expect(fileMeta.mlData).toBeDefined(); + expect(fileMeta.mlData.face.faces[0].faceID).toBe("face-abc"); + }); + + it("excludes ML data when mlData: false", async () => { + const outDir = join(testDir, "no-ml"); + const client = await Client.login({ + email: TEST_EMAIL, + password: TEST_PASSWORD, + apiOptions: { fetch: buildMetaFetch(mock) }, + }); + + await runMetadataBackup(client, outDir, { mlData: false }); + const collDirs = readdirSync(join(outDir, "collections")); const vacDir = collDirs.find((d) => d.includes("Vacation"))!; const fileMeta = JSON.parse(