One album or file quak cannot decrypt no longer stops a refresh or a backup (closes #181)
check / check (push) Waiting to run
check / check (push) Waiting to run
collectionsSince and filesSince put a row that does not decrypt or parse in an undecryptable list with the reason instead of throwing. The refresh leaves it out, an album with its files, and the store keeps the list in metadata.json until the server sends a copy that decrypts or deletes it, since the next refresh asks only for changes. lib.backup() records each such file in failures.json as "could not be decrypted: <reason>", unless a copy in another album decrypted, logs one line per such album and lists their IDs in undecryptableAlbums; quak backup exits 1 while any remain. Tests use a stand-in Ente server with real encryption. Model: opus-5-5
This commit is contained in:
@@ -127,19 +127,20 @@ matters.
|
||||
|
||||
### Exit codes
|
||||
|
||||
| Code | Meaning |
|
||||
| ---- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `0` | The backup is complete: every original is at its save path, and no file failed. |
|
||||
| `1` | The run finished with files in `failures.json`, or it stopped on another error, printed as one line `quak: <message>`. The next run tries again. |
|
||||
| `2` | Another backup of the same directory is running. This run sent no request and changed nothing. |
|
||||
| `3` | There is no usable session: none is saved, the saved one is corrupt, or the server no longer accepts it. Run `quak login` as the user the cron job runs as. |
|
||||
| Code | Meaning |
|
||||
| ---- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `0` | The backup is complete: every original is at its save path, and no file failed. |
|
||||
| `1` | The run finished with files in `failures.json` or an album it could not decrypt, or it stopped on another error, printed as one line `quak: <message>`. The next run tries again. |
|
||||
| `2` | Another backup of the same directory is running. This run sent no request and changed nothing. |
|
||||
| `3` | There is no usable session: none is saved, the saved one is corrupt, or the server no longer accepts it. Run `quak login` as the user the cron job runs as. |
|
||||
|
||||
After a `1`, the next run fetches each missing original again, fetches the ML
|
||||
data that is not cached, and rebuilds the album links. An original that a
|
||||
`--verify` run could not read, or put back with bytes that still do not match,
|
||||
stays at its save path. Only a later `--verify` run checks it again: a run
|
||||
without `--verify` leaves it as it is and takes the file out of `failures.json`,
|
||||
so that run can exit 0.
|
||||
data that is not cached, and rebuilds the album links. A file or album quak
|
||||
could not decrypt keeps the exit code at `1` until the server's copy changes
|
||||
(see "Backup layout"). An original that a `--verify` run could not read, or put
|
||||
back with bytes that still do not match, stays at its save path. Only a later
|
||||
`--verify` run checks it again: a run without `--verify` leaves it as it is and
|
||||
takes the file out of `failures.json`, so that run can exit 0.
|
||||
|
||||
## Examples
|
||||
|
||||
@@ -623,8 +624,10 @@ library. The read commands — `collections`, `files`, `get`, `get-thumb`,
|
||||
answer, so they report current account state rather than whatever the cache last
|
||||
held. If that round-trip fails, the command prints the error on one line and
|
||||
exits 1, or 3 when the server no longer accepts the saved session (see "Session
|
||||
handling"). `--cache-dir` overrides where the cache lives; without it each
|
||||
account gets its own directory under the per-user cache path.
|
||||
handling"). An album or file quak cannot decrypt does not fail it; the command
|
||||
answers without it (see "Default reads vs. fresh reads"). `--cache-dir`
|
||||
overrides where the cache lives; without it each account gets its own directory
|
||||
under the per-user cache path.
|
||||
|
||||
`get` and `get-thumb` resolve the file by ID directly, so `--collection` is
|
||||
accepted for backward compatibility but ignored. For a live photo, `get` writes
|
||||
@@ -734,6 +737,17 @@ succeeds, or once it is no longer in the library or in the backup's scope. The
|
||||
library's `lib.backup({ includeThumbnails: true })` also writes
|
||||
`thumbnails/<fileID>.jpg` beside `collections/`; `quak backup` does not.
|
||||
|
||||
A file the library could not decrypt (see "Default reads vs. fresh reads") goes
|
||||
into `failures.json` with an empty title, since its title is encrypted too, and
|
||||
an error that starts `could not be decrypted:` and gives the reason. A file in
|
||||
two albums is backed up as usual if its copy in the other album decrypted. An
|
||||
album the library could not decrypt has no name quak can read and no files it
|
||||
can list. Each run prints one line for it,
|
||||
`FAILED album <id>: could not be decrypted: <reason>`, and `--json` and the
|
||||
`BackupResult` list its ID in `undecryptableAlbums`. Every other file is backed
|
||||
up. Either kind keeps the exit code at 1, run after run, until the server sends
|
||||
a copy that decrypts or deletes it; the next run then drops it.
|
||||
|
||||
`backup.lock` keeps two backups of the same directory from running at once, such
|
||||
as a cron run that starts while the previous one is still going. A backup
|
||||
creates `<dir>` if it is missing and takes the lock before its refresh, and
|
||||
@@ -906,6 +920,15 @@ rejects the caller (default reads stay silent and keep serving the last good
|
||||
copy). The CLI's read commands use fresh reads (issue
|
||||
https://git.eeqj.de/sneak/quak/issues/75).
|
||||
|
||||
An album or file in the server's answer that quak cannot decrypt, or whose
|
||||
metadata is not JSON, does not fail the refresh. The refresh leaves it out, an
|
||||
album with all its files, and drops any older copy the cache held, so reads
|
||||
answer from what did decrypt. The library keeps a list of what it left out, with
|
||||
the reason, in `metadata.json`: the next refresh asks the server only for what
|
||||
changed, so it would not see the record again. A record stays on that list until
|
||||
a later refresh gets a copy that decrypts or learns that the server deleted it.
|
||||
`lib.backup()` reports each one (see "Backup layout").
|
||||
|
||||
### Read surface
|
||||
|
||||
- `lib.albums.list()` → `Album[]`, newest-updated first.
|
||||
|
||||
Reference in New Issue
Block a user