Skip to content

feat(metadata): automatic blank-only "fill missing from online" for books with files - #942

Draft
kevinheneveld wants to merge 1 commit into
Listenarrs:canaryfrom
kevinheneveld:feat/auto-metadata-backfill
Draft

feat(metadata): automatic blank-only "fill missing from online" for books with files#942
kevinheneveld wants to merge 1 commit into
Listenarrs:canaryfrom
kevinheneveld:feat/auto-metadata-backfill

Conversation

@kevinheneveld

Copy link
Copy Markdown
Contributor

Summary

Books that hold files but lack core metadata (description, cover, publisher, language, release date) currently need a manual trip through the per-book metadata rescan or the edit modal. This adds an unattended, blank-only backfill worker so a library's gaps close themselves over time.

  • New MetadataAutoBackfillService hosted worker (Settings → Features → Fill missing metadata from online sources automatically, off by default). Every 15 minutes it takes up to 25 candidate books, looks each up by its own ASIN (ISBN falls back through IAsinLookupService), waits 3 s between lookups, and fills only the fields the record lacks.
  • AudiobookBlankFieldBackfill (application layer) is the blank-only counterpart of the rescan's overwrite patch: a populated field is never touched, so manual edits and existing series placement survive. Covers are cached into library storage via IImageCacheService, same as the rescan.
  • Audiobook.MetadataBackfillAttemptedAt (new column) lets the worker rotate through candidates and retry provider misses weekly instead of every cycle. Books with an unresolved move are skipped without being stamped.
  • Applies under the per-audiobook exclusive lock and the move-queue mutation fence, mirroring LibraryMetadataRescanWorkflow.

Candidate query (GetMetadataBackfillCandidatesAsync): has files ∧ has ASIN/ISBN identifier ∧ (description ∨ cover ∨ publisher ∨ language ∨ published date blank) ∧ not attempted in the last 7 days; never-attempted first.

Migration

20260904174436_AddMetadataAutoBackfill — scaffolded with dotnet ef migrations add. Adds nullable Audiobooks.MetadataBackfillAttemptedAt and ApplicationSettings.MetadataAutoBackfillEnabled (default false).

Tests

  • AudiobookBlankFieldBackfillTests — blank-only semantics (populated fields kept, whitespace/empty treated as blank, provider blanks never blank the record, legacy single author/narrator fallback, existing series placement kept).
  • MetadataAutoBackfillProcessorTests — fills blanks + cover and leaves populated fields alone; disabled setting never looks up; wishlist (no files) and complete books are not candidates; provider miss stamps the attempt and is not retried within the window; unresolved move skips without stamping.
  • FE: FeaturesSection.spec.ts covers the new toggle.

Full backend suite run locally; the only failures are the pre-existing AudiobookContentMoveServiceTests class, which fails identically on clean canary on this macOS host.

🤖 Generated with Claude Code

https://claude.ai/code/session_012A3PhZjAJkCP4Cvo9gC551

…ooks with files

Books that hold files but lack core metadata (description, cover, publisher,
language, release date) currently need a manual trip through the per-book
rescan or the edit modal. A new MetadataAutoBackfillService worker (Settings →
Features → "Fill missing metadata from online sources automatically", off by
default) looks such books up by their own ASIN — ISBN falls back through the
ASIN converter — 25 per 15-minute cycle, 3 s apart, and fills ONLY the blank
fields via the new AudiobookBlankFieldBackfill helper. A populated field is
never overwritten, so manual edits and existing series placement survive; the
cover is cached into library storage like the rescan does.

Audiobook.MetadataBackfillAttemptedAt (new column) lets the worker rotate
through candidates and retry provider misses weekly instead of every cycle;
books with an unresolved move are skipped without being stamped. Applies under
the per-audiobook exclusive lock and the move-queue mutation fence.

Migration 20260904174436_AddMetadataAutoBackfill scaffolded with dotnet ef.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012A3PhZjAJkCP4Cvo9gC551
kevinheneveld added a commit to kevinheneveld/Listenarr that referenced this pull request Sep 4, 2026
…-branch follow-up to Listenarrs#942)

On this branch the verification engine (Listenarrs#728) exists, so the automatic
metadata backfill only considers books whose audio passed verification
(agent or manual): a grab that may still be rejected as wrong content never
costs a provider lookup. Also records the new migration in the fork's
migration-history schema test, adds the CHANGELOG entry, and words the
settings toggle accordingly. Fold into Listenarrs#942 once Listenarrs#728 lands upstream.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012A3PhZjAJkCP4Cvo9gC551
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant