Date download() and backup by the album copy photo.savePath uses
Export `representative` from records.ts: the album's copy of a file that its record is read from. `store.getFileByID` now returns that copy, so `download()` writes under the date `photo.savePath` names. `lib.backup()` takes each file's copy by the same rule from all of its albums, and every album links that one path. Tests cover one file in two albums whose copies carry different edited dates, for `download()` and for `lib.backup()`. Model: opus-5-5
This commit is contained in:
@@ -608,6 +608,57 @@ describe("lib.backup", () => {
|
||||
await lib.close();
|
||||
});
|
||||
|
||||
it("saves a file in two albums at its photo's save path and links it from both", async () => {
|
||||
// The date edited in Ente has reached Work's copy, synced later, but
|
||||
// Vacation's copy still has an earlier edit.
|
||||
const older = file(100, 1, "beach.jpg");
|
||||
older.pubMagicMetadata = {
|
||||
editedTime: new Date(2026, 1, 1, 12).getTime() * 1000,
|
||||
};
|
||||
const newer = file(100, 2, "beach.jpg");
|
||||
newer.updationTime = 2;
|
||||
newer.pubMagicMetadata = {
|
||||
editedTime: new Date(2026, 3, 15, 12).getTime() * 1000,
|
||||
};
|
||||
class SharedFileClient extends MockClient {
|
||||
override async filesSince(args: {
|
||||
collectionID: number;
|
||||
}): Promise<FilesPage> {
|
||||
const files = [args.collectionID === 1 ? older : newer];
|
||||
return { files, deleted: [], cursor: 1 };
|
||||
}
|
||||
}
|
||||
const outDir = join(root, "backup");
|
||||
const lib = await Library.open({
|
||||
client: new SharedFileClient(),
|
||||
cacheDirectory: join(root, "cache"),
|
||||
downloadDirectory: outDir,
|
||||
contentSource: stubSource(),
|
||||
refreshIntervalSeconds: 3600,
|
||||
precacheThumbnails: false,
|
||||
precacheOriginals: false,
|
||||
});
|
||||
const photo = lib.photos.byID({ fileID: 100 })!;
|
||||
|
||||
const result = await lib.backup();
|
||||
|
||||
expect(result.totalFiles).toBe(1);
|
||||
expect(result.downloaded).toBe(1);
|
||||
expect(result.failed).toBe(0);
|
||||
expect(photo.savePath).toBe(
|
||||
join(outDir, "2026", "2026-04", "2026-04-15", "2026-04-15.100.jpg"),
|
||||
);
|
||||
expect(photo.isLocal).toBe(true);
|
||||
expect(existsSync(join(outDir, "2026", "2026-02"))).toBe(false);
|
||||
const target = "../../2026/2026-04/2026-04-15/2026-04-15.100.jpg";
|
||||
for (const album of ["Vacation", "Work"]) {
|
||||
expect(
|
||||
readlinkSync(join(outDir, "collections", album, "beach.jpg")),
|
||||
).toBe(target);
|
||||
}
|
||||
await lib.close();
|
||||
});
|
||||
|
||||
it("fsyncs an original copied from the cache before the rename and its directory after", async () => {
|
||||
const lib = await openLibrary(stubSource());
|
||||
const outDir = join(root, "backup");
|
||||
|
||||
@@ -416,7 +416,7 @@ describe("Photo save path, local copy, content and EXIF", () => {
|
||||
await lib.close();
|
||||
});
|
||||
|
||||
it("dates the save path by the membership its takenAt comes from", async () => {
|
||||
it("dates the save path and download() by the membership its takenAt comes from", async () => {
|
||||
// One file in two albums. The date edited in Ente has reached album 2's
|
||||
// copy, synced later, but album 1 still has an earlier edit.
|
||||
const older = file(1, 1);
|
||||
@@ -457,6 +457,12 @@ describe("Photo save path, local copy, content and EXIF", () => {
|
||||
"2026-04-15.1.jpg",
|
||||
),
|
||||
);
|
||||
|
||||
// download() writes to that same path, so the photo is then local.
|
||||
const saved = await photo.download();
|
||||
expect(saved.path).toBe(photo.savePath);
|
||||
expect(photo.isLocal).toBe(true);
|
||||
expect(existsSync(join(root, "backup", "2026", "2026-02"))).toBe(false);
|
||||
await lib.close();
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user