Conversation
EditionSelector.SelectMostRated and SelectRepresentativeFallback picked purely by native-format match then per-edition vote count, with no language awareness. MetadataProfile.AllowedLanguages only filters candidates when explicitly configured, so on the common unconfigured profile every language passes through untouched, and a translated edition with more votes on its own edition row can outrank the original English one for the same work. This selector is shared by both the provisional pick made when an author's full back-catalog is first converted from provider data (BookInfoProxy) and the final pick made once a metadata profile is available (AuthorLibraryService) - unmonitored bibliography stub books never get re-picked after the provisional pass, so they stay mislabeled with the foreign edition's title/narrators permanently. Add a language-preference tiebreak ahead of votes: explicit English wins, unset/unknown language is treated neutrally (an edition missing a language tag isn't punished), any other explicit language loses. This only reorders within an already-filtered candidate pool, so a library-wide non-English AllowedLanguages restriction still narrows correctly upstream, and a foreign-only candidate pool still falls back to picking by votes exactly as before.
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.
Bug
When an import list discovers a new author from one shelved book, Chaptarr pulls in that author's entire back-catalog as unmonitored stub
Bookrows. For each work,EditionSelectorhas to pick one edition to represent it in the local catalog — and that pick had no language preference at all: it ranked candidates purely by native-format match, then per-edition vote count.MetadataProfile.AllowedLanguagesonly filters the candidate pool when it's explicitly configured. On the common unconfigured profile, every language passes through untouched, and a translated edition can end up with more votes on its own edition row than the original English one for the same work (e.g. all Spanish-reader votes on one edition row, while English votes are split across several English edition rows). The higher-voted foreign edition then wins and gets stored as the book's sole representative edition.Concretely, this produced local catalog rows like:
"<Title> [Spanish Edition]", its stored edition carrying Spanish narrator credits, despite an English edition of the same work being available"<Title> – <German subtitle>", similarly mismatchedBoth cases trace to the same author-bibliography-refresh timestamp in the DB, confirming the bulk back-catalog path, not a one-off manual add.
This selector (
EditionSelector.SelectByNativeFormatThenRatings, viaSelectMostRated/SelectRepresentativeFallback) is shared by two call sites:BookInfoProxy.SelectBestEditionAsMonitored— the provisional pick made when converting an author's full back-catalog from provider data, explicitly commented as provisional ("Language ... filtering happen[s] later once the metadata profile is available")AuthorLibraryService.SelectMonitoredEditionsForMediaType— the later, profile-aware pickUnmonitored bibliography stub books never get promoted to the second pass, so they stay stuck with whatever the language-blind provisional pick chose — permanently.
Fix
Add a language-preference tiebreak ahead of vote count in
SelectMostRatedandSelectRepresentativeFallback: an edition with explicit English language wins, an edition with no language tag is treated neutrally (not punished for missing metadata), and any other explicit language loses. It's a soft default ordering key, not an exclusionary filter — a foreign-only candidate pool still falls back to picking by votes exactly as before, and a library whereAllowedLanguagesis explicitly restricted to something else still narrows correctly upstream inEditionMetadataProfileFilter.Added tests in
EditionSelectorLanguageFilteringFixturecovering: English winning over a more-voted foreign edition for both audiobook and ebook media types, and the no-English-available fallback still picking by votes.Testing
Ran
dotnet test(net10.0) locally: full suite passes, 3023/3023, 0 failures — including the 3 new tests inEditionSelectorLanguageFilteringFixture.🤖 Generated with Claude Code