github vavallee/bindery v1.16.1

6 hours ago

A getting-started / onboarding friction pass plus a batch of fixes from user reports. No breaking changes.

Added

  • Test a download client / indexer before saving — the Add and Edit forms for download clients and indexers now have an inline Test button that probes the unsaved host/port/URL/credentials, so a wrong value can be caught and fixed in place instead of having to save a broken entry, find Test on the saved row, reopen the editor, fix, and re-save. Backed by two new admin-only test-by-config endpoints (POST /downloadclient/test and POST /indexer/test) that validate and probe a posted config without persisting it; the response shape mirrors the existing test-by-id endpoints so the UI reuses one rendering path.
  • Bulk "Refresh metadata" action on the Authors page — refresh the catalogues of many selected authors at once (metadata fetch only, never an auto-download). Recovers authors imported with empty catalogues without clicking per-author Refresh one at a time (internal/api/bulk.go, web/src/pages/AuthorsPage.tsx).
  • First-run onboarding guidance on empty Authors/Books pages — when a brand-new instance has no authors/books and no indexers or download clients configured, the empty state now shows a short "Getting started" block linking to Settings → Indexers and Settings → Download Clients, explaining they must be configured first (without them, adding an author or searching silently does nothing). The block only appears when both are empty and falls back to the normal empty state if the checks fail. Settings tabs are now deep-linkable via ?tab=indexers / ?tab=clients.

Changed

  • A page crash no longer blanks the whole app — page render errors are now caught by a route-scoped error boundary that shows the error inline while keeping the nav/header usable, and clears itself when you navigate to another page (no reload needed). Previously the only boundary was the root one, whose full-screen dark-mode fallback took over the entire viewport and required a manual reload to recover.

Fixed

  • Re-bind metadata "Re-bind anyway" override was unreachable — when re-binding a book to a provider whose record belongs to a different author, the API returns a 409 carrying force_required so the UI can offer an override. The web API client discarded the HTTP status and JSON body on error, so RebindModal never saw the flag and rendered the raw author mismatch text with no way forward. The client now throws a structured ApiError (status + body); the amber "Re-bind anyway" confirmation works as intended. Note: forcing past the mismatch re-points the book's metadata to the new record but keeps it filed under its current author.
  • Audiobook downloads could hang in "downloading" forever (qBittorrent) — the main import poll (checkQbittorrentDownloads) queried only the client's ebook Category, so torrents grabbed under CategoryAudiobook were never returned and their downloads never matched (logged as download not found in torrent list), leaving them stuck. The #700 fix that polls both categories had only been applied to the stall/health adapters, not this poll. It now polls every category the client may have grabbed under via CategoriesToPoll. Transmission and Deluge are unaffected (Transmission does not split audiobooks by category/dir; Deluge polls all torrents).
  • Grab errors name the missing download-client protocol — grabbing a usenet (NZB) release when only a torrent client is enabled (or vice versa) returned a generic "no enabled download client configured", sending users to re-check the client they had already verified. The error now names the release's protocol and, when a client of the other protocol is enabled, spells out the mismatch and which client to add (internal/api/queue.go).
  • SABnzbd connection test validates the configured category — the SABnzbd test only checked reachability and discarded the category list, so a typo'd category passed; downloads then landed silently in SAB's default category and the poller never found them. The test now verifies that each configured category (and audiobook category, if set) exists in SABnzbd, returning an actionable error otherwise — mirroring the existing NZBGet behaviour (internal/downloader/sabnzbd/client.go, internal/downloader/adapter.go).
  • CSV author import now always populates each newly-created author's book catalogue — instead of only doing so for rows with an explicit searchOnAdd=true third column. Plain-name and two-column rows previously created authors with empty catalogues, so the library scan matched no files and the library looked empty after import. The fetch never auto-downloads (internal/migrate/csv.go).
  • Library scan surfaces the paths it walked and explains zero/unmatched results — the manual library scan now records the resolved library and audiobook roots, plus an explicit zero-files signal, in its persisted result. The Settings → General "Library Scan" section shows which paths were scanned, warns by name when no book files were found under the configured directory (a common BINDERY_LIBRARY_DIR misconfiguration), and hints when files were found but none matched a book (the author's book catalogue needs populating first). Additive, backward-compatible result fields (library_dir, audiobook_dir, scanned_paths, no_files_found); the matching logic is unchanged.
  • Helm chart shipped unusable defaultsvalues.yaml defaulted BINDERY_LIBRARY_DIR to a maintainer-specific path (/media/BOOKS/incoming) and enabled a /downloads:/media path remap, so a fresh helm install pointed the library at a path that didn't exist in the pod and silently rewrote download paths. Library dir now defaults to /books (matching the Docker image) and the remap is commented out by default. The chart's ingress was also Traefik-IngressRoute-only; it now supports ingress.type: standard to render a portable networking.k8s.io/v1 Ingress (with className/annotations/tls) for nginx-ingress, GKE, EKS, etc. type defaults to traefik, so existing installs are unchanged.

Docs

  • Added docs/QUICKSTART.md — an in-repo zero-to-first-download walkthrough (run → first login → indexer → download client → author → grab) with the SSRF localhost-rejection gotcha and protocol-matching/category troubleshooting callouts. Linked from the README documentation table.
  • Fixed doc/code drift: Unraid template Overview now says MIT (was "Apache 2.0"); BINDERY_AUDIOBOOK_DOWNLOAD_DIR added to the README env table; BINDERY_TRUSTED_PROXY and BINDERY_TELEMETRY_DISABLED added to the DEPLOYMENT env-var reference; the broken #reverse-proxy anchor in DEPLOYMENT.md now points at the Reverse-proxy wiki; README "full reference" wording corrected to point OIDC/forward-auth vars at docs/auth-oidc.md / docs/auth-proxy.md.

Don't miss a new bindery release

NewReleases is sending notifications on new releases.