metadata: incremental beets import, event-driven album art re-fetch (#270) #272

Merged
mysticalsoap merged 3 commits from metadata/art-sync-event-driven into trunk 2026-09-19 12:54:18 -04:00
Owner

Problem

Closes #270. The nightly whole-library beet import re-autotags every album and replaces its items, so any run where MusicBrainz answers short demotes a matched album to as-is and wipes its ids; album_art_sync.py then drops the album from tracking with no log line or notification. The 14-day recheck compounded it: it re-rolled the archive lookup for static art, and its resolved-URL comparison never matched anyway until #269.

Separately, both beets profiles set state:, which isn't a beets option (statefile is), so the retag profile's "separate state" was never separate.

Fix

  • beets import: incremental: yes — existing dirs are never re-autotagged; new dirs still import; music_retag.py already refreshes a retagged album explicitly via beet update.
  • state: → statefile: in both profiles.
  • album_art_sync.py: no interval recheck. A matched album is re-fetched only when its source changes or its cover.jpg is gone. Vanished covers are detected before run_beets, because fetchart backfills a missing cover with its own per-release guess first and the release-group cover should win. ALBUM_RECHECK_INTERVAL_DAYS is retired (the line in media/metadata/.env is now ignored and can go).
  • Maintenance.md: describes the new behaviour and how to re-roll a single as-is album by hand (beet import -q -I <dir>), since that no longer happens on its own.

Verification

All on the live stack (bind-mounted), 2026-09-19:

  • Seeded beets' import history with all 106 album dirs via ImportState.history_add so the first incremental run didn't re-roll everything once more (there was no state.pickle at all before — history is only written when incremental is on). Full run afterwards: beets skipped every dir, whole sync 5 s.
  • One-time non-incremental repair (beet import -q -I) of the 34 albums without a release-group id: Discovery and Grace re-matched (both had been demoted again by the 00:00 nightly run on the old config, after being restored yesterday — the flapping, live); the other 31 stayed as-is, so they're the retag backlog, not flapping victims. Release-group count 72 → 74.
  • Vanished-cover path: removed Rubber Soul's cover.jpg, ran the sync — fetchart backfilled it first, then the script reported 1 refetch, UPDATED: The Beatles/Rubber Soul, and the file is the 120 KB release-group thumbnail again with the state's resolved key unchanged. Grace and Discovery came in as 2 new.
  • Dry run with nothing missing: processing 0 this run (0 new, 0 refetch, 0 retry queued).
## Problem Closes #270. The nightly whole-library `beet import` re-autotags every album and replaces its items, so any run where MusicBrainz answers short demotes a matched album to as-is and wipes its ids; `album_art_sync.py` then drops the album from tracking with no log line or notification. The 14-day recheck compounded it: it re-rolled the archive lookup for static art, and its resolved-URL comparison never matched anyway until #269. Separately, both beets profiles set `state:`, which isn't a beets option (`statefile` is), so the retag profile's "separate state" was never separate. ## Fix - beets `import: incremental: yes` — existing dirs are never re-autotagged; new dirs still import; `music_retag.py` already refreshes a retagged album explicitly via `beet update`. - `state:` → `statefile:` in both profiles. - `album_art_sync.py`: no interval recheck. A matched album is re-fetched only when its source changes or its `cover.jpg` is gone. Vanished covers are detected *before* `run_beets`, because fetchart backfills a missing cover with its own per-release guess first and the release-group cover should win. `ALBUM_RECHECK_INTERVAL_DAYS` is retired (the line in `media/metadata/.env` is now ignored and can go). - Maintenance.md: describes the new behaviour and how to re-roll a single as-is album by hand (`beet import -q -I <dir>`), since that no longer happens on its own. ## Verification All on the live stack (bind-mounted), 2026-09-19: - Seeded beets' import history with all 106 album dirs via `ImportState.history_add` so the first incremental run didn't re-roll everything once more (there was no `state.pickle` at all before — history is only written when incremental is on). Full run afterwards: beets skipped every dir, whole sync 5 s. - One-time non-incremental repair (`beet import -q -I`) of the 34 albums without a release-group id: Discovery and Grace re-matched (both had been demoted again by the 00:00 nightly run on the old config, after being restored yesterday — the flapping, live); the other 31 stayed as-is, so they're the retag backlog, not flapping victims. Release-group count 72 → 74. - Vanished-cover path: removed Rubber Soul's `cover.jpg`, ran the sync — fetchart backfilled it first, then the script reported `1 refetch`, `UPDATED: The Beatles/Rubber Soul`, and the file is the 120 KB release-group thumbnail again with the state's resolved key unchanged. Grace and Discovery came in as `2 new`. - Dry run with nothing missing: `processing 0 this run (0 new, 0 refetch, 0 retry queued)`.
Both profiles silently fell through to beets' default, $BEETSDIR/state.pickle.
Same file the main profile meant, so no behaviour change there, but the
retag profile's "separate state" never was.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The nightly whole-library `beet import` re-autotags every album and
replaces its items; any run where MusicBrainz answers short demotes a
matched album to asis and wipes its ids, and album_art_sync then drops
it silently (#270). Incremental skips dirs already in the import history,
so an existing album is never re-rolled. New dirs still import, and
music_retag.py refreshes a retagged album explicitly via `beet update`.

The flip side: an album beets has as-is stays as-is until re-imported
with -I by hand (Maintenance.md).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Album art is static; the interval recheck only re-rolled the archive
lookup. A matched album is now touched again only when its source
changes (override edit, beets re-match) or its cover.jpg is gone, e.g.
Lidarr rebuilding the folder on a quality upgrade. Vanished covers are
detected before run_beets, because fetchart backfills a missing cover
with its own per-release guess first and the release-group cover should
win, same as on first fetch. ALBUM_RECHECK_INTERVAL_DAYS is retired.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
mysticalsoap deleted branch metadata/art-sync-event-driven 2026-09-19 12:54:18 -04:00
Sign in to join this conversation.
No description provided.