Each run now writes .failures.json in the backup directory: the last
reason every photo failed and the wiki pages that use it, dropping any
photo that has since arrived. A new --report mode reads the wiki index
and that file and lists every page whose photo is not on disk, with the
reason or "not yet attempted", calling neither flickr nor immich. That is
what tells a wiki editor which photos have gone from flickr and need
replacing.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Flickr's limit is an hourly window, so backing off one photo for a couple
of minutes and then hitting the next photo at the old rate just fails
again, which is how a full fetch gave up on photos after six attempts. A
429 on a paced request now doubles the pace for every later flickr call,
up to ten seconds, and the pace relaxes back to the configured value only
after twenty untroubled requests. The per-request backoff also starts at
fifteen seconds instead of five, caps at fifteen minutes, and gets eight
attempts, so a single photo can wait out a short window on its own.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Load only the credentials the requested phases need, run fetch then sync,
and exit 1 when any photo failed so cron mails. A quiet clean run prints
nothing; a quiet failing run prints the failure list at the end.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
List what immich already holds by checksum, upload only what is missing,
then bring every matched asset up to date: the marked description block,
coordinates and capture date where absent, the RGL album, and licence and
photographer tags. Album membership and descriptions are read-compare-write;
uploaded assets are re-read from immich after the album and tag stage so a
duplicate answer or a late metadata job never sees a blank slate. Tag
assignments are re-sent each run and immich reports the duplicates.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Carry over immich-sync's client, which lists assets by checksum and drives
albums and tags, and add a hand-rolled multipart upload with the checksum
header so immich can answer duplicate without receiving the bytes twice,
plus a per-asset update for description, date and coordinates.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Walk the grouped index, ask flickr for each new photo, download the best
size that actually serves, and write the sidecar only once the file is
renamed into place. Photos already complete cost no flickr calls; a change
in which pages use one rewrites just the sidecar. Every failure is
recorded with the pages affected and the run carries on.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Immich has no copyright or source fields, so the photographer, licence,
flickr page and every wiki page using the photo go into a marked block in
the description. The marker lets a later run find and replace only that
block, leaving anything written by hand alone. Tags mirror licence and
photographer for filtering.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The sidecar is what makes the directory a backup on its own and what the
immich phase reads, so it is written atomically and a photo only counts as
done when the sidecar, its file and no .part remain.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Two unsigned json calls per photo: getInfo for title, owner, dates and
licence, getSizes for the renditions. Sizes come back ordered best-first so
a missing original can fall through to the next. Not-found and permission
errors become PhotoGone so the run can name the wiki pages affected.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
One json request to the wiki's index carries every node's image fields, so
no per-page scraping is needed. Nodes are grouped by flickr photo id, taken
from the thumbnail filename or the photo page, so a photo used on several
pages is fetched once and its description can list them all.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
One place decides what is worth another attempt: 429, 5xx and network
errors, with jittered exponential backoff and Retry-After honoured. Other
4xx responses fail at once. Downloads stream to disk under the same policy,
refuse a body over the size cap, and only flickr calls and photo downloads
are paced; the api key is redacted from debug output.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Reuse the flickr key flickrtouchr already holds and the immich url and key
immich-sync uses, so nothing secret is duplicated. Everything else comes
from a typed settings file with flag > environment > file > default
precedence, so a cron line can be the bare script.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Start the script that will back up the Randomness Guide to London's photos
to disk and Immich. This commit holds the constants, error classes and
quiet-aware output helpers every later section relies on, plus the test
loader for an extensionless script.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>