feat(metadata): automatic blank-only "fill missing from online" for books with files - #942
Draft
kevinheneveld wants to merge 1 commit into
Draft
Conversation
…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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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.
MetadataAutoBackfillServicehosted 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 throughIAsinLookupService), 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 viaIImageCacheService, 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.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 withdotnet ef migrations add. Adds nullableAudiobooks.MetadataBackfillAttemptedAtandApplicationSettings.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.FeaturesSection.spec.tscovers the new toggle.Full backend suite run locally; the only failures are the pre-existing
AudiobookContentMoveServiceTestsclass, which fails identically on cleancanaryon this macOS host.🤖 Generated with Claude Code
https://claude.ai/code/session_012A3PhZjAJkCP4Cvo9gC551