You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This commit was created on GitHub.com and signed with GitHub’s verified signature.
New Features
Match Report Widget
Full per-book match report UI rendered after every run -- expandable cards in a 2-per-row grid showing local vs. matched metadata side by side
Each card shows: cover images (local + provider), title, author, narrator, series, sequence, genre, year, ASIN, duration comparison, the query used to find the match, and a score percentage badge
Searchable by title, author, series, or path; filterable by status (Matched, Goodreads, Manually Applied, Smart-skipped, Would write, Written, Skipped, Not Matched, Error)
Manually applied books show a dedicated badge and load their stored marker data so the report reflects what was actually written, not a re-matched result
Local cover loading now extracts the embedded cover from loose audio files directly via ffmpeg, so books without a folder-level cover.jpg get their own correct cover instead of sharing the parent folder's
Goodreads / Kindle Fallback (abs-tract)
Unmatched books automatically fall back to Goodreads via abs-tract for title, author, series, and sequence metadata
Kindle cover-only fallback for books that match on metadata but lack an Audible cover
Explicit opt-in flag in the UI (Goodreads fallback checkbox); manual provider selector also exposes Goodreads and Kindle for single-book review
Circuit breaker with cooldown protects against upstream Goodreads/Amazon rate-limit blocks; transient failures retry instead of failing silently
Goodreads matches are provider-aware: smart-skip only checks the fields Goodreads can actually supply (title, author, series, sequence) -- narrator, ASIN, year, and genre are never blanked by a Goodreads re-match
Settings Page
Dedicated /settings page consolidating preferences, Accounts, and cleanup controls into a left-nav sectioned layout
Publisher learning author/narrator guard: known author and narrator names are no longer incorrectly learned as publishers
Multi-file Grouping Improvements
Per-chapter .ogg books grouped as a single multi-file book
Leading-ordinal chapter splits (e.g. "01 - BookTitle Part 1.mp3") grouped correctly as one book
Sidecar cleanup endpoint: remove libraforge state files for a target folder
Fixes
Matching Quality
Cross-series matches blocked when series names share only a prefix word (e.g. Arena vs Arena Road)
Hard block on matches with a clearly different author
Four matching failures fixed: chapter-numbered titles, audio-author-prefixed filenames, format labels misread as immersion labels, Goodreads series queries
"Title - Series, N" filenames with a bare book number now parsed correctly
Grouped "Series N - Author" folder names no longer blocked from matching
Genre
Removed all "Audiobook" hardcodes from the fixer script -- genre now defaults to empty string instead of the format label
Genre field filtered through all candidate providers and surfaced in the match report card and manual review UI
_pick_genre() helper blocks format labels ("audiobook", "audiobooks") so they never appear as a real genre
Metadata Correctness
fill_missing no longer preserves stale fraction sequences (e.g. "1/1" from embedded MP4 track tags) when a fresh valid sequence is available
Relative target paths normalized correctly before being passed to the fixer
Target path validated before run starts with a clear 400 error instead of a silent failure
UI / UX
Score badge shows percentage (e.g. 87%) instead of a rounded 0 or 1
"Audiobook" genre no longer appears in manual review metadata fields
Path validation error surfaced clearly in the run UI