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> |
||
|---|---|---|
| .. | ||
| src | ||
| tests | ||
| Cargo.toml | ||
| README.md | ||
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
searchnode. 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.