Decrypt and persist all file metadata layers
Extends RawEnteFile and EnteFile with optional magicMetadata and pubMagicMetadata fields. Both are secretstream blobs under the file key, decrypted to arbitrary JSON (Record<string, unknown>). pubMagicMetadata carries ML-derived data from the Ente clients: camera make/model, image dimensions, datetime with timezone offset, and (when present) captions, editedName, face labels, keywords. magicMetadata carries private mutable fields like visibility. Backup now writes per-file JSON at originals/<fileID>.json containing all three metadata layers (basic + magic + pubMagic). Live-tested: all 11 files in the dev account have pubMagicMetadata with SONY DSC-RX1RM3 camera info and 3000x2000 dimensions.
This commit is contained in:
@@ -116,6 +116,24 @@ export const runBackup = async (
|
||||
}
|
||||
}
|
||||
|
||||
// Write per-file metadata JSON alongside the original
|
||||
const metaJsonPath = join(originalsDir, `${file.id}.json`);
|
||||
if (!existsSync(metaJsonPath)) {
|
||||
const fileMeta: Record<string, unknown> = {
|
||||
id: file.id,
|
||||
collectionID: file.collectionID,
|
||||
ownerID: file.ownerID,
|
||||
metadata: file.metadata,
|
||||
};
|
||||
if (file.magicMetadata) {
|
||||
fileMeta.magicMetadata = file.magicMetadata;
|
||||
}
|
||||
if (file.pubMagicMetadata) {
|
||||
fileMeta.pubMagicMetadata = file.pubMagicMetadata;
|
||||
}
|
||||
writeFileSync(metaJsonPath, JSON.stringify(fileMeta, null, 2));
|
||||
}
|
||||
|
||||
if (!existsSync(linkPath) && existsSync(origPath)) {
|
||||
const target = relative(colDir, origPath);
|
||||
symlinkSync(target, linkPath);
|
||||
|
||||
Reference in New Issue
Block a user