crabidy/absdy
Test User f4309aa327 Add the audiobookshelf provider (`/abs`)
New `absdy` crate mounted at `/abs`: browse, search, and play audiobooks
from a self-hosted audiobookshelf server. Shaped on the fyyd provider --
an `Abs` reqwest seam faked in tests (14 unit tests, no network), an
in-memory per-library search-term store, and a `library -> book -> tracks`
tree with a per-library `search` subtree.

audiobookshelf-specific decisions:

- Credentials + a secret. A missing/incomplete abs.toml (no base_url or
  api_key) disables `/abs` non-fatally. The api_key and the `?token=`
  stream URL are secrets: Settings and AbsApi have manual redacting Debug,
  and the token is built only in `Abs::stream_url` -- never logged, never
  handed to a reqwest call in absdy (browse auth is a bearer header).

- Playback needs no API call: a track's stream URL is fully derivable from
  its path (item id + ino) plus the token. Verified live that `?token=`
  auth returns 200 and the file endpoint honors HTTP range (206), so the
  windowed-HTTP player streams it directly.

- Per-library search (ABS search is per-library); the reserved `search`
  segment splits the search branch from item ids. A book's queueability
  comes from the summary's numAudioFiles, so ebook-only items show but are
  not queueable. Root lists only book libraries.

Wired through the orchestrator and settings exactly like the other
providers (dispatch arms, root child, ALL_PROVIDERS, ProviderToggles).
An `#[ignore]`d live test (absdy/tests/live.rs) validates the DTOs against
a real server end-to-end. Docs: architecture/, quality/, plan/, READMEs.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-23 23:22:52 +02:00
..
src Add the audiobookshelf provider (`/abs`) 2026-07-23 23:22:52 +02:00
tests Add the audiobookshelf provider (`/abs`) 2026-07-23 23:22:52 +02:00
Cargo.toml Add the audiobookshelf provider (`/abs`) 2026-07-23 23:22:52 +02:00
README.md Add the audiobookshelf provider (`/abs`) 2026-07-23 23:22:52 +02:00

README.md

absdy — audiobookshelf provider

Mounts a self-hosted audiobookshelf (ABS) server at /abs, so you can browse, search, and play your audiobooks from crabidy. See the design doc for the design and decisions.

Configuration — ~/.config/crabidy/abs.toml

The provider needs your server URL and an API key. Without both, /abs does not mount (the rest of the server is unaffected).

# Required.
base_url = "https://audiobookshelf.example.com"
api_key  = "<your audiobookshelf API key>"

# Optional (defaults shown).
items_per_library = 200   # books listed per library
search_results    = 50    # books listed per search term
call_timeout_secs = 30     # per-request timeout

Create an API key in audiobookshelf under Settings → Users → (your user) → API Keys (or Settings → API Keys on older versions). The key is a secret: it is redacted from logs and never printed, but keep abs.toml private anyway.

The library tree

/abs
└── <library>                     one node per "book" library
    ├── search                    create a search term with `%`
    │   └── <term>                books matching the term
    │       └── <book>            the book's audio files as tracks
    └── <book>                    an audiobook; its files are tracks
        └── <file>                a track (one audio file)
  • A library lists its books plus a creatable search node. Search is per-library — a term created under one library does not appear under another.
  • A book lists its audio files as tracks; queue or capture (W) the whole book, or a single file. An ebook-only item (no audio) is shown but is not queueable.
  • Podcast libraries are not shown (audiobooks only, for now).

Notes

  • Playback streams each file directly from ABS with a per-file token URL and HTTP range requests — no transcoding session.
  • Listings are capped (see the config) and fetched fresh; only your typed search terms are remembered, in memory, until the server restarts.