# CalibreSync Automatically sync eBooks from a remote Linux host to your [Calibre-Web](https://github.com/janeczku/calibre-web) library. CalibreSync connects to a remote host over SFTP, downloads new zip archives, extracts the RAR files inside them, and uploads the resulting epub/pdf files to Calibre-Web — skipping anything already uploaded. A web dashboard lets you monitor runs, browse uploaded books, and configure everything including the sync schedule. ## Features - **Incremental sync** — tracks processed archives in SQLite, never re-downloads or re-uploads - **Duplicate prevention** — SHA-256 hash check before every upload - **Automatic schedule** — configure a run interval (e.g. every 60 minutes) from the dashboard - **SSH key auth** — paste your private key directly in the UI, never written to disk - **Dark web dashboard** — live stats, sync history, books table, settings - **Docker ready** — single `docker compose up` to get started ## Screenshots | Dashboard | Settings | |-----------|----------| | Stats, recent runs, zip history | SSH, Calibre-Web, schedule | ## Requirements - Docker (recommended) **or** Python 3.12+ with `unrar-free` / `unrar` installed - A running [Calibre-Web](https://github.com/janeczku/calibre-web) instance with uploads enabled - SSH access to the remote host holding the zip archives ## Quick start with Docker ```bash git clone https://git.skitnerdig.com/YOUR_USERNAME/calibresync.git cd calibresync docker compose up -d ``` Open [http://localhost:8000](http://localhost:8000) and go to **Settings** to configure: 1. **Remote host** — hostname, port, username, SSH key or password, remote zip directory path 2. **Calibre-Web** — URL, username, password 3. **Schedule** — how often to run automatically (in minutes, 0 = manual only) Then click **Run Sync Now** on the dashboard, or wait for the scheduler to fire. The SQLite database is stored in `./data/` and survives container restarts. ## Running without Docker ```bash # Debian / Ubuntu sudo apt install unrar-free pip install -r requirements.txt uvicorn main:app --reload ``` Open [http://localhost:8000](http://localhost:8000) and follow the same setup steps. > **RAR5 archives:** `unrar-free` handles RAR4. For RAR5 you need the non-free `unrar` package. > See the comment in the [Dockerfile](Dockerfile) for instructions. ## How it works ``` Remote host (SFTP, read-only) └── *.zip └── *.rar ├── book.epub └── book.pdf └── Calibre-Web (/upload) ``` 1. **SFTP scan** — recursively lists all `.zip` files under the configured remote path 2. **Filter** — skips any zip already recorded in the local SQLite database 3. **Download** — fetches new zips to a local work directory 4. **Extract** — unzips, then unrars, collects all `.epub` and `.pdf` files 5. **Upload** — checks SHA-256 hash against the database; uploads new files to Calibre-Web 6. **Cleanup** — removes local temporary files after each zip is processed Remote files are **never modified or deleted**. ## Project structure ``` calibresync/ ├── main.py # FastAPI app — dashboard, settings, sync trigger ├── sync.py # Orchestration loop ├── sftp.py # SFTP connection and download ├── extractor.py # unzip + unrar ├── uploader.py # Calibre-Web API client ├── db.py # SQLite schema and helpers ├── config.py # Settings loader/saver ├── templates/ # Jinja2 HTML templates ├── static/ # CSS ├── Dockerfile └── docker-compose.yml ``` ## Dashboard pages | Page | URL | Description | |------|-----|-------------| | Dashboard | `/` | Stats, recent sync runs, recent zip archives | | Books | `/books` | All uploaded books with status and source | | Settings | `/settings` | All configuration | | API status | `/api/status` | JSON status endpoint | | API docs | `/docs` | Auto-generated FastAPI docs | ## License MIT