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(