Skip to content

Repository files navigation

BookBot logo

BookBot

Declarative audiobook command center for collectors who care about clean metadata.

CI Docker PyPI Python versions License Code style Ruff Typing

BookBot is a Textual-powered terminal app and command-line toolkit for taming large audiobook libraries. Its core workflow is a safe, reviewable rename plan: scan a library, inspect the exact moves, apply them atomically, and undo them if needed.

Highlights

  • Safe-plan workflow with dry-runs, atomic file operations, transaction history, diffable JSON plans, and undo support.
  • Built-in profiles for safe, audiobookshelf, plex, prologue, and apple-books.
  • bookbot doctor checks your runtime, FFmpeg health, writable config/cache paths, and library integrity before changes land.
  • Unified matching via AdvancedMatcher, with article and Unicode normalization, shared title and author scoring across providers, series and volume extraction, and built-in plus user-supplied author_aliases.json support.
  • Identifier-first matching uses embedded ASIN and ISBN guesses when available, short-circuiting to deterministic lookups before falling back to fuzzy search.
  • Multi-provider matching queries every enabled provider concurrently, merges overlapping candidates by identifier or normalized author/title, boosts confidence when providers corroborate a result, and falls back from title+author+series to stripped-title, title-only, and author-only searches when needed.
  • Runtime cross-checking compares local duration against provider-reported audiobook length to reward exact matches and flag likely abridged or wrong-edition candidates.
  • Provider coverage includes Open Library by default, Audnexus enabled by default, and optional Google Books, LibriVox, Audible, and Hardcover providers when configured.
  • bookbot dedupe builds a reviewable quarantine plan for duplicate editions and byte-identical files using edition clustering plus staged hashing (size -> partial hash -> full hash), then reuses bookbot undo for rollback.
  • Dedupe never deletes files: --apply moves quarantined tracks into .bookbot-quarantine/<plan_id>/..., preserves relative paths, and can write the plan to JSON for review.
  • Mission-control TUI with scan, metadata review, preview, warnings, diff, and undo shortcuts in one interface.
  • Configurable templates and collector profiles so folders, file names, covers, and sidecars match the way your players expect them.
  • Optional M4B conversion pipeline with FFmpeg stream copy, loudness normalization, and chapter generation.
  • M4B tooling for merging, splitting, tagging, and chapter injection.
  • Chapter detection pipeline with silence analysis, cue file parsing, track boundaries, and Audnexus chapter data.
  • Audiobookshelf integration for searching, matching, progress tracking, and bidirectional sync.
  • Library health auditing to catch missing covers, inconsistent tags, orphaned files, duplicates, and series gaps.
  • Smart organizer for restructuring messy libraries into Plex, Audiobookshelf, or custom directory layouts.
  • Sidecar metadata support for OPF (Calibre), BookLore JSON, and NFO formats.
  • Audible authentication, DRM detection, and removal helpers for supported formats (AAX, AAXC, M4B, and more).

Installation

Docker is the fastest way to run BookBot with every dependency pre-baked. It keeps FFmpeg, optional DRM tooling, and Python libraries in one container so your host stays clean.

Docker (recommended)

docker run -it --rm \
  -v "/path/to/audiobooks:/data" \
  -v "$PWD/config:/config" \
  -e BOOKBOT_CONFIG_DIR=/config \
  ghcr.io/itsbryanman/bookbot:latest tui /data

Mount your library into /data and persist configuration under /config. Swap tui /data for commands like scan /data --plan /config/bookbot-plan.json, doctor /data, or convert /book --profile conversion.

Or use Docker Compose with the included docker-compose.yml:

docker compose up

You can also add a convenience alias:

alias bookbot-docker='docker run -it --rm -v "$PWD/config:/config" -e BOOKBOT_CONFIG_DIR=/config -v "$PWD:/data" ghcr.io/itsbryanman/bookbot:latest'

Then run bookbot-docker tui /data from any library directory.

pipx (alternative)

pipx install bookbot-cli

The package on PyPI is bookbot-cli, but the executable is bookbot. pipx keeps BookBot isolated and places bookbot on your PATH. If the executable is not found after install, add $HOME/.local/bin to your shell profile.

pip / virtualenv (alternative)

python -m pip install bookbot-cli
python -m pip install "bookbot-cli[conversion]"

You still need a system FFmpeg binary for audio conversion and DRM extraction.

From source

git clone https://github.com/itsbryanman/BookBot.git
cd BookBot
python -m pip install -e .[dev]

The editable install gives you live reload while iterating on the app.

Quick start

# 1. Create a safe, reviewable rename plan
bookbot scan /path/to/audiobooks --plan ./bookbot-plan.json

# 2. Review or diff the plan before touching files
bookbot review ./bookbot-plan.json
bookbot plan diff ./bookbot-plan.json

# 3. Apply it atomically, then undo if needed
bookbot apply ./bookbot-plan.json
bookbot undo <transaction-id>

# 4. Check the host or a mounted library before a bigger run
bookbot doctor
bookbot doctor /path/to/audiobooks --profile audiobookshelf

# 5. Launch the Textual TUI for interactive review
bookbot tui /path/to/audiobooks

#    Stay offline by reusing existing sidecar metadata
bookbot tui /path/to/audiobooks --metadata-from-files

# 6. Convert a finished book to a single tagged M4B
bookbot convert /path/to/book -o /path/to/output --normalize --chapters auto

# 7. Authenticate with Audible once, then import books by ASIN
bookbot audible auth
bookbot audible import B01234567X --remove-drm

Prefer a desktop entry point? bookbot gui launches the same Textual application and falls back to the CLI if GUI dependencies are missing.

Core workflows

Organize safely

  • bookbot scan DIR --plan bookbot-plan.json
  • bookbot review bookbot-plan.json
  • bookbot apply bookbot-plan.json
  • bookbot undo <transaction-id>
  • The bookbot plan subgroup exposes the same flow explicitly: create, show, diff, validate, and apply.

Tailor metadata

  • Activate opinionated profiles with bookbot profile list, bookbot profile show audiobookshelf, and bookbot profile use plex.
  • Built-in collector profiles define folder layout, preferred packaged filename, cover behavior, sidecar output, M4B preference, and chapter style.
  • Customize templates or output behavior with bookbot config show, bookbot config set output.folder_template ..., and runtime --profile flags.

Diagnose first

  • bookbot doctor checks Python, FFmpeg, config/cache writability, and provider configuration.
  • bookbot doctor ./library --profile audiobookshelf validates plan compatibility, cover art, narrators, duplicate titles, broken chapters, suspiciously short tracks, unsupported formats, and Windows/Samba-hostile filenames.

Bring your own providers

  • Open Library and Audnexus are always on. Add Google Books, LibriVox, Audible, or Hardcover enrichment with:
    bookbot provider set-key googlebooks YOUR_API_KEY
    bookbot provider set-key hardcover YOUR_TOKEN
    bookbot provider enable librivox
    bookbot provider enable audible
    bookbot provider list
  • Audible marketplace defaults to US; switch with bookbot provider set-marketplace UK.

Convert and normalize

  • Install FFmpeg, then enable the conversion profile or pass --profile conversion.
  • Stream copy AAC sources when possible, or set bitrate/VBR/normalization flags per run.
  • Chapters can come from tags, track order, or custom names depending on your config.

DRM tooling

  • Detect protection on folders of files with bookbot drm detect ./library --recursive.
  • Store activation bytes once using bookbot drm set-activation-bytes DEADBEAF.
  • Remove DRM in place or to a clean output location using bookbot drm remove book.aax -o ./clean.

CLI cheat sheet

Command Purpose
bookbot scan DIR --plan PLAN.json Inspect directories, infer series/disc structure, and write a reviewable rename plan without touching files.
bookbot review PLAN.json Show the saved plan with warnings, conflicts, and exact file moves.
bookbot apply PLAN.json Apply a saved plan atomically and emit a transaction ID for undo.
bookbot plan create/show/diff/validate/apply Explicit safe-plan workflow for scripting and auditing.
bookbot doctor [DIR] Verify runtime dependencies and optionally inspect a library for compatibility problems.
bookbot profile use NAME Apply a collector profile such as safe, audiobookshelf, plex, prologue, or apple-books.
bookbot tui DIR... Launch the interactive Textual mission-control interface. Add --metadata-from-files to reuse local NFO/JSON sidecars instead of online providers.
bookbot convert DIR -o OUT Build single-file, chaptered M4B releases with optional normalization and artwork.
bookbot history --days 7 Review completed transactions and identify undo candidates.
bookbot undo ID Roll back an operation safely using its transaction identifier.
bookbot provider ... Enable, disable, and configure metadata providers and API keys.
bookbot config ... Manage global config, reset defaults, and inspect profile settings stored under ~/.config/bookbot.
bookbot health DIR Audit a library for missing covers, inconsistent tags, orphaned files, duplicates, and series gaps. Use --json-output for machine-readable output.
bookbot organize SOURCE Reorganize a library into a clean structure. Use --template abs|plex|default and --confirm to execute.
bookbot chapters detect DIR Detect chapters via silence analysis, cue files, track boundaries, or Audnexus data.
bookbot chapters apply DIR Write detected chapters as FFMETADATA1 or cue sidecar files.
bookbot m4b merge DIR -o OUT Merge audio files into a single M4B with optional chapter markers and cover art.
bookbot m4b split FILE -o DIR Split an M4B into individual files by chapter.
bookbot m4b chapters FILE Display embedded chapter markers.
bookbot m4b tag FILE Update metadata tags and cover art on an M4B file.
bookbot sidecar read DIR Display detected sidecar metadata (OPF, JSON, NFO).
bookbot sidecar write DIR Generate sidecar metadata from tags or matched identity.
bookbot abs login Authenticate with an Audiobookshelf server.
bookbot abs libraries List all libraries on the ABS server.
bookbot abs search LIB QUERY Search a library for audiobooks.
bookbot abs list LIB List items in a library.
bookbot abs show ITEM Show full item details with chapters and progress.
bookbot abs match ITEM Trigger metadata match for an item.
bookbot abs match-all LIB Batch match all items in a library.
bookbot abs progress ITEM Get or set playback progress.
bookbot abs stats Show listening statistics.
bookbot abs sync Synchronize playback progress with the server. Use --watch for continuous sync.
bookbot audible ... Authenticate, list your library, and download titles directly from Audible.
bookbot drm ... Detect DRM, save activation bytes, and convert protected files.
bookbot completions SHELL Generate shell completions (bash, zsh, fish, or all).

Use --help on any command or subgroup for the full option set.

Configuration directory layout

Location Purpose
~/.config/bookbot/config.toml Primary configuration file persisted by the TUI and CLI.
~/.config/bookbot/profiles/*.toml Saved profiles, including the bundled safe, audiobookshelf, plex, prologue, apple-books, full, and conversion presets.
~/.cache/bookbot/ Cached metadata, cover art, and conversion plans. Delete to force fresh lookups.
~/.local/share/bookbot/logs/transaction_*.json Transaction history used for undo and audit logs.

Config files use TOML; edit by hand or via bookbot config commands.

Metadata providers

Provider Notes
Open Library Default, always enabled, free. Core search source for titles and authors.
Audnexus Enabled by default, free, no API key. Audiobook-specific metadata and chapter data via ASIN lookup. Supports regional marketplaces.
Google Books Requires an API key; adds richer descriptions and ISBN data.
LibriVox Public domain library; great for narrator and language hints.
Audible Requires authentication; unlocks commercial metadata and download tooling.
Hardcover Requires a Bearer token from your Hardcover account. GraphQL API for book metadata with audiobook duration matching.

Provider priorities and fallback logic are configurable through the ConfigManager. Combine multiple providers for higher confidence matches.

Conversion pipeline

The conversion subsystem lives in bookbot.convert and wraps FFmpeg (through ffmpeg-python) to build high quality, chaptered M4B files. Highlights:

  • Auto-detects when stream copy is safe to avoid re-encoding AAC tracks.
  • Supports bitrate or VBR quality targets with optional EBU R128 loudness normalization.
  • Generates chapter markers from track segmentation or existing tags.
  • Embeds cover art and metadata pulled from the selected provider record.
  • Writes conversion plans to disk so you can dry-run before touching anything (bookbot convert --dry-run).

DRM and Audible helpers

BookBot includes a focused DRM toolkit backed by ffmpeg and the audible Python package.

  1. Authenticate once with bookbot audible auth; credentials are stored securely via keyring.
  2. List your library (bookbot audible list --limit 50) or import specific titles by ASIN.
  3. Use bookbot drm detect to map protected files and bookbot drm remove to produce DRM-free audio. Activation bytes can be supplied per run or cached via bookbot drm set-activation-bytes.

Retrieving Activation Bytes

For DRM removal of Audible files, you'll need your account's activation bytes. BookBot can retrieve these for you.

Dependencies:

This feature requires selenium and chromedriver. If you are not using the Docker image, you will need to install them:

pip install selenium
# Make sure chromedriver is in your PATH

Usage:

Run the following command and follow the prompts to enter your Audible username and password:

bookbot audible get-activation-bytes

This will securely save your activation bytes for future use. After this one-time setup, you can remove DRM from your books without needing to provide the activation bytes every time.

These features depend on optional packages (audible, cryptography, keyring, selenium) that are already declared in pyproject.toml. Ensure FFmpeg is compiled with the modules required for Audible AAX/AAXC processing.

Audiobookshelf integration

BookBot can connect to an Audiobookshelf server for metadata matching, progress tracking, and library management.

  1. Authenticate with bookbot abs login --server https://abs.example.com --username admin.
  2. Browse your server with bookbot abs libraries, bookbot abs list LIB_ID, and bookbot abs search LIB_ID QUERY.
  3. Trigger metadata matching with bookbot abs match ITEM_ID or batch match an entire library.
  4. Sync playback progress bidirectionally with bookbot abs sync. Use --watch --interval 60 for continuous background sync.

Library health checks

Run bookbot health /path/to/library to audit for common issues:

  • Missing cover art (no embedded cover and no cover.jpg sidecar)
  • Inconsistent tags across tracks in the same book
  • Orphaned non-audio files
  • Duplicate editions (fuzzy title and author matching)
  • Series gaps (missing volumes in a numbered series)
  • Mixed audio formats within a single book
  • Bitrate anomalies (tracks with significantly different bitrates)

Use --json-output for machine-readable output or --verbose for file-level detail.

Smart organizer

The bookbot organize command restructures messy libraries into clean, player-compatible directory layouts:

# Preview proposed moves (default is dry-run)
bookbot organize /messy/library --template abs

# Execute the reorganization
bookbot organize /messy/library --template abs --target /clean/library --confirm

Built-in templates: default, abs (Audiobookshelf-compatible), plex (Plex Media Server).

Chapter detection

BookBot can detect and generate chapter markers using multiple strategies:

  1. Audnexus - fetch chapter data by ASIN from the Audnexus API
  2. Cue files - parse existing .cue sidecar files
  3. Track boundaries - treat each audio file as a chapter
  4. Silence detection - use FFmpeg to find silence gaps between chapters
bookbot chapters detect /path/to/book --method auto
bookbot chapters apply /path/to/book --format ffmetadata

Sidecar metadata

BookBot reads and writes sidecar metadata files for interoperability with other audiobook tools:

  • OPF (Dublin Core XML) - compatible with Calibre and Audiobookshelf
  • BookLore JSON - .metadata.json format
  • NFO - audiobook info files (XML or key-value)
bookbot sidecar read /path/to/book
bookbot sidecar write /path/to/book --format opf

Development

make install-dev   # install dev dependencies
make lint          # ruff + mypy
make format        # black
make test          # pytest
make pre-commit    # run the full formatting and lint bundle

Textual ships with a live reload server: run textual run --dev bookbot.tui.app:BookBotApp while editing the TUI.

Contributing

I welcome issues and pull requests. Please:

  1. Fork the repo and create a feature branch.
  2. Add or update tests under tests/ for any new functionality.
  3. Run make pre-commit before submitting to keep style and typing checks green.
  4. Document user-facing changes in this README or the changelog if applicable.

did you like bookbot?

Ko-fi

License

BookBot is released under the MIT License. See LICENSE for the full text.

About

audiobook organizer/renamer + DRM removal

Resources

Stars

37 stars

Watchers

2 watching

Forks

Releases

Packages

Contributors

Languages