Daemon/service/CLI to help you download your Kobo/Audible/LibroFM purchases onto your computer or sync with your libraries like BookLore
  • Rust 89.6%
  • HTML 10.1%
  • Dockerfile 0.2%
  • Python 0.1%
Find a file
Jeremy Knope c705f48199
All checks were successful
CI / fmt (push) Successful in 13s
CI / clippy (push) Successful in 24s
CI / test (push) Successful in 37s
Release / build (linux/arm64, linux/arm64) (push) Successful in 2m25s
Release / build (linux/amd64, linux/amd64) (push) Successful in 3m43s
Release / merge (push) Successful in 7s
fix: race condition in account sync
2026-05-17 15:40:19 -04:00
.forgejo/workflows ci: don't use docker containers as they replace the default actions 2026-05-14 09:37:39 -04:00
book-auto-downloader fix: race condition in account sync 2026-05-17 15:40:19 -04:00
kobo-rust chore: bump to 0.2, bump deps 2026-05-17 11:32:03 -04:00
libation-rust chore: bump to 0.2, bump deps 2026-05-17 11:32:03 -04:00
librofm-rust chore: bump to 0.2, bump deps 2026-05-17 11:32:03 -04:00
.dockerignore fix: consistently toml now for config files & try to catch permission 2025-12-13 14:12:41 -05:00
.gitignore fix: issue with sync blocking control-c, not sorting by purchase/acquire date, add scan files on disk behavior, and more 2026-05-02 09:18:03 -04:00
Cargo.lock fix: download button getting caught by ad blockers 2026-05-17 15:36:28 -04:00
Cargo.toml feat: librofm downloading support 2026-03-16 12:55:42 -04:00
CLAUDE.md initial port of python kobo-book-downloader 2025-09-01 12:38:50 -04:00
Dockerfile fix: forgot ffmpeg in container 2026-05-16 16:07:14 -04:00
example-config.json initial port of python kobo-book-downloader 2025-09-01 12:38:50 -04:00
example-daemon.toml fix: issues with ENV sourced config & out of sync examples/readme 2026-05-13 10:04:12 -04:00
example.env fix: issues with ENV sourced config & out of sync examples/readme 2026-05-13 10:04:12 -04:00
m4b-chapters.py fix(librofm): chapter renaming not working 2026-03-16 13:18:36 -04:00
mise.toml chore: add tag-release mise task 2026-05-14 10:57:07 -04:00
README.md fix: issues with ENV sourced config & out of sync examples/readme 2026-05-13 10:04:12 -04:00

Book Auto-Downloader

A Rust workspace for automatically downloading and DRM-removing books from Kobo, Audible, and Libro.fm.

AI Disclaimer

This project used AI tools to port & generate the initial codebase & documentation. Future work may involve less AI as I get more comfortable returning to the old ways.

Workspace Structure

Crate Description
book-auto-downloader Main daemon and CLI tool
kobo-rust Kobo API client library
libation-rust Audible API client library (port of Libation)
librofm-rust Libro.fm audiobook API client library

Features

  • Kobo: Authenticate, list, and download eBooks with automatic KDRM removal
  • Audible: OAuth authentication and library listing (download/DRM support in progress)
  • Libro.fm: Password authentication, library listing, and audiobook downloads (MP3 or M4B)
  • Daemon: Runs continuously, checking for new Kobo books on a configurable schedule
  • Web UI: Browser-based account management, OAuth flows, and manual download triggers
  • BookLore Integration: Optionally upload books to a BookLore instance
  • SQLite: All credentials and download state stored in a local database
  • Docker: Containerized deployment with volume mounts for config and downloads
  • Libation Import: Import existing Audible credentials from a Libation config

Quick Start

Local Build

cargo build --release -p book-auto-downloader

# Authenticate a Kobo account
./target/release/book-auto-downloader auth your-email@example.com

# Run a one-time sync
./target/release/book-auto-downloader sync

# Run the daemon continuously
./target/release/book-auto-downloader daemon

Docker

# Build the image
docker build -t book-auto-downloader .

# Create config directory with correct permissions (container runs as UID 1000)
mkdir -p ./config
sudo chown -R 1000:1000 ./config

# Authenticate your Kobo account
docker run -it -v ./config:/config book-auto-downloader auth your-email@example.com

# Run the daemon
mkdir -p ./downloads
docker run -d \
  --name book-downloader \
  -v ./config:/config \
  -v ./downloads:/downloads \
  --restart unless-stopped \
  book-auto-downloader daemon

CLI Reference

book-auto-downloader [COMMAND]
Command Description
daemon (default) Run the daemon continuously
sync Perform a one-time sync and exit
status Show daemon status and download statistics
config Show current configuration
auth <email> Authenticate a Kobo account interactively
auth-audible <email> Authenticate an Audible account (web UI recommended)
auth-librofm <email> Authenticate a Libro.fm account interactively
import-libation <file> Import accounts from a Libation config.json
import-csv <file> Import a CSV of books to mark as already downloaded
list-tracked List all tracked books for an account
remove-tracked <title> Remove books from the tracker by title search
backfill-metadata Fill in missing metadata from the Kobo library
booklore-check Report which Kobo books are missing from BookLore

Configuration

Configuration is loaded from daemon.toml. Copy the example and edit:

cp example-daemon.toml ~/.config/book-auto-downloader/daemon.toml

In Docker, the config file lives at /config/.config/book-auto-downloader/daemon.toml (or the simplified /config/daemon.toml path when built with the docker feature).

Key Settings

check_interval = "1h"           # How often to check for new books
download_path = "./book_downloads"
max_concurrent_downloads = 3
log_level = "info"

[booklore]
enabled = false
url = ""
username = ""
password = ""
skip_existing = true
upload_enabled = true
upload_mode = "bookdrop"        # "bookdrop" or "direct"

[web]
enabled = true
port = 8080
bind_address = "0.0.0.0"

Environment Variables

All settings can be overridden with BOOKDL_ prefixed environment variables. Nested sections (e.g. [booklore], [web]) are separated from the field name with a double underscore, so that field names containing single underscores parse unambiguously:

BOOKDL_CHECK_INTERVAL=1h                       # top-level: check_interval
BOOKDL_BOOKLORE__ENABLED=true                  # [booklore] enabled
BOOKDL_BOOKLORE__DELETE_AFTER_UPLOAD=false     # [booklore] delete_after_upload
BOOKDL_WEB__PORT=8080                          # [web] port
Variable Description
BOOKDL_CHECK_INTERVAL e.g. "1h", "30m", "2h30m"
BOOKDL_EBOOKS_PATH Ebooks directory (default: ./books)
BOOKDL_AUDIOBOOKS_PATH Audiobooks directory (default: ./audiobooks)
BOOKDL_MAX_CONCURRENT_DOWNLOADS Default: 3
BOOKDL_LOG_LEVEL trace, debug, info, warn, error
BOOKDL_AUTO_SYNC "true" (default) or "false"
BOOKDL_BOOKLORE__ENABLED "true" or "false"
BOOKDL_BOOKLORE__URL e.g. "http://host.docker.internal:8080"
BOOKDL_BOOKLORE__USERNAME BookLore username
BOOKDL_BOOKLORE__PASSWORD BookLore password
BOOKDL_BOOKLORE__SKIP_EXISTING Skip books already in BookLore
BOOKDL_BOOKLORE__UPLOAD_ENABLED Upload books after download
BOOKDL_BOOKLORE__DELETE_AFTER_UPLOAD Delete local EPUB after upload
BOOKDL_BOOKLORE__MAX_UPLOAD_RETRIES Retry cap for failed uploads (default: 3)
BOOKDL_BOOKLORE__UPLOAD_MODE "bookdrop" or "direct"
BOOKDL_BOOKLORE__LIBRARY_ID Library ID for direct mode
BOOKDL_BOOKLORE__PATH_ID Path ID for direct mode
BOOKDL_KOBO__AUTO_DOWNLOAD Auto-download new Kobo titles on sync (default: false)
BOOKDL_AUDIBLE__AUTO_DOWNLOAD Auto-download new Audible titles on sync (default: false)
BOOKDL_LIBROFM__AUTO_DOWNLOAD Auto-download new Libro.fm titles on sync (default: false)
BOOKDL_LIBROFM__FORMAT "m4b" (default) or "mp3"
BOOKDL_LIBROFM__RENAME_CHAPTERS Rename MP3 / update M4B chapters (default: true)
BOOKDL_AUDIOBOOKSHELF__ENABLED Enable ABS scan trigger
BOOKDL_AUDIOBOOKSHELF__URL ABS base URL
BOOKDL_AUDIOBOOKSHELF__API_KEY ABS API token
BOOKDL_AUDIOBOOKSHELF__EBOOK_LIBRARY_ID ABS library ID for ebook scans
BOOKDL_AUDIOBOOKSHELF__AUDIOBOOK_LIBRARY_ID ABS library ID for audiobook scans
BOOKDL_WEB__ENABLED Enable the web UI (default: true)
BOOKDL_WEB__PORT Web server port (default: 8080)
BOOKDL_WEB__BIND_ADDRESS Bind address (default: 0.0.0.0)
BOOKDL_WEB__LIBRARY_CACHE_TTL Library-page cache TTL (default: "15m")

Authentication

Kobo

book-auto-downloader auth your-email@example.com

This opens a browser-based activation flow at kobo.com/activate. Credentials are saved to the local SQLite database.

Audible

Audible uses OAuth 2.0 with PKCE. The web UI provides the full flow:

  1. Start the daemon with the web UI enabled (default)
  2. Visit http://localhost:8080/auth/audible
  3. Complete the Amazon login in your browser
  4. Credentials are saved automatically

Alternatively, import credentials from an existing Libation installation:

book-auto-downloader import-libation /path/to/libation/config.json

Libro.fm

Libro.fm uses a simple email/password login. Either use the CLI:

book-auto-downloader auth-librofm your-email@example.com

Or via the web UI at http://localhost:8080/auth/librofm.

Web UI

When running with web.enabled = true (the default), the daemon exposes a web interface at http://localhost:8080 for:

  • Viewing configured accounts and download status
  • Adding Kobo accounts (web-based activation flow)
  • Adding Audible accounts (full OAuth flow)
  • Adding Libro.fm accounts (email/password login)
  • Browsing Audible and Libro.fm libraries and triggering manual downloads
  • Managing accounts without restarting the daemon

Docker: docker-compose

Copy example.env to .env and customize, then:

# docker-compose.yml
services:
  book-downloader:
    image: book-auto-downloader
    container_name: book-downloader
    volumes:
      - ./config:/config
      - ./downloads:/downloads
    env_file:
      - .env
    ports:
      - "8080:8080"   # Web UI
    restart: unless-stopped
docker-compose up -d

Useful Docker Commands

# View logs
docker logs -f book-downloader

# One-time sync
docker run --rm -v ./config:/config -v ./downloads:/downloads book-auto-downloader sync

# Check status
docker exec book-downloader book-auto-downloader status

Volume Mounts

Mount Purpose
/config Persistent config and SQLite database
/downloads Downloaded books

Permission Note

The container runs as UID 1000. If you encounter Permission denied errors:

sudo chown -R 1000:1000 ./config

Credential Storage

All credentials (Kobo tokens, Audible OAuth tokens, Libro.fm access tokens) and download state are stored in a SQLite database at:

  • Local: ~/.local/share/book-auto-downloader/books.db (platform default)
  • Docker: /config/.local/share/book-auto-downloader/books.db

Supported Formats

  • Kobo eBooks: EPUB with KDRM removal
  • Kobo Audiobooks: Multi-file download to subdirectory
  • Audible: Library listing complete; download and DRM removal planned
  • Libro.fm: MP3 (ZIP-extracted tracks) and M4B (single file)

Development

# Build all crates
cargo build

# Run tests
cargo test

# Check without building
cargo check

# Format
cargo fmt

# Lint
cargo clippy

Requirements

  • Rust 1.70+
  • Kobo account with email login
  • Audible/Amazon account (for Audible features)
  • Libro.fm account (for Libro.fm features)
  • Internet connection

Limitations

  • Adobe DRM not supported (Kobo KDRM only)
  • Audible download and DRM removal not yet implemented
  • Audible auth requires the web UI for the full OAuth flow
  • Libro.fm downloads are triggered manually via the web UI; no daemon auto-sync

Contributing

Contributions welcome! Please:

  1. Fork the repository
  2. Create a feature branch
  3. Ensure cargo test passes
  4. Submit a pull request

License

MIT OR Apache-2.0

Acknowledgments

Disclaimer

This tool is for personal use only. Please respect the Terms of Service of Kobo, Audible, and Libro.fm, and only download books you have legally purchased.