- Rust 96.3%
- HTML 1.4%
- CSS 1%
- Nix 0.8%
- Dockerfile 0.5%
| little-hesinde | ||
| little-hesinde-macros | ||
| .containerignore | ||
| .envrc | ||
| .gitignore | ||
| .rustfmt.toml | ||
| Cargo.lock | ||
| Cargo.toml | ||
| Containerfile | ||
| flake.lock | ||
| flake.nix | ||
| README.md | ||
Little Hesinde
Simple OPDS server for a calibre library, with KOReader progress sync built in.
I wrote it very specifically for my own needs, your mileage may vary.
It lets you browse and download ebooks from any OPDS-compatible reader and syncs reading progress across KOReader devices. A web UI behind OIDC login lets you manage API keys for both.
The last version with the integrated HTML interface is found at tag 0.3.5.
Building
Use nix develop to get a shell with all dependencies. Otherwise, check
flake.nix for the required toolchain.
Setup
You need a calibre library, an OIDC provider (with PKCE enabled), and a database (SQLite by default; PostgreSQL and MySQL via feature flags). All secrets are read from files.
Generate a cookie encryption key and prepare the secret files:
openssl rand -hex 64 > cookie_key
echo "sqlite:///var/lib/little-hesinde/data.db?mode=rwc" > db_url
echo "your-oidc-client-secret" > oidc_secret
Start the server:
Usage: little-hesinde [OPTIONS] --oidc-issuer-url <URL> --oidc-redirect-url <URL>
--oidc-client-secret-file <PATH> --database-url-file <PATH>
--cookie-key-file <PATH> -- <LIBRARY_PATH>
Arguments:
<LIBRARY_PATH> Calibre library path [env: LIBRARY_PATH=]
Options:
-l, --listen-address <ADDR> Address to listen on [env: LISTEN_ADDRESS=] [default: [::1]:3000]
-c, --cache-path <PATH> Thumbnail cache path [env: CACHE_PATH=] [default: $TMP/little-hesinde]
-u, --oidc-issuer-url <URL> OIDC issuer URL [env: OIDC_ISSUER_URL=]
-r, --oidc-redirect-url <URL> Redirect URL after login [env: OIDC_REDIRECT_URL=]
-i, --oidc-client-id <ID> OIDC client ID [env: OIDC_CLIENT_ID=]
-s, --oidc-client-secret-file <PATH> File containing the OIDC client secret
-d, --database-url-file <PATH> File containing the database URL
-o, --cookie-key-file <PATH> File with 64-byte cookie encryption key
-m, --max-session-duration <SECS> Session lifetime [default: 31622400]
-h, --help Print help
-V, --version Print version
Container
All options can be set via environment variables (see --help for the env var names). Secrets are read
from files. so they have to be mounted into the container.
podman run \
-v /data/library:/library \
-v little_hesinde_cache:/tmp/cache \
-v ./oidc_secret:/run/secrets/oidc_secret:ro \
-v ./db_url:/run/secrets/db_url:ro \
-v ./cookie_key:/run/secrets/cookie_key:ro \
-e OIDC_ISSUER_URL=https://auth.example.com \
-e OIDC_REDIRECT_URL=https://hesinde.example.com/login/callback \
-e OIDC_CLIENT_ID=myapp \
-e OIDC_CLIENT_SECRET_FILE=/run/secrets/oidc_secret \
-e DATABASE_URL_FILE=/run/secrets/db_url \
-e COOKIE_KEY_FILE=/run/secrets/cookie_key \
-p 3000:3000 \
little-hesinde
Connecting clients
After starting the server, open http://localhost:3000 and log in via OIDC.
Create an API key on the key management page (/keys).
For both OPDS and sync, the API key acts as your credential.
OPDS
Point your reader to http://localhost:3000/opds/v1. Use the API
key as the username in HTTP Basic auth. The password field is required by
most clients but ignored by the server.
Sync
Point KOReader's progress sync to http://localhost:3000/sync.
Set user to your API key. Password has to be provided but can be anything (it
is ignored by the server).