No description
  • Go 65.3%
  • TypeScript 23.2%
  • CSS 10.8%
  • Dockerfile 0.5%
  • HTML 0.2%
Find a file
Adam Bibby d3d063599e
All checks were successful
Build and Deploy / docker (push) Successful in 1m21s
golangci-lint / lint (push) Successful in 58s
oxlint / Lint (Oxlint) (push) Successful in 8s
fix workflows
2026-10-20 05:52:33 -04:00
.github/workflows fix workflows 2026-10-20 05:52:33 -04:00
.vscode add upload button and linters 2026-07-19 06:35:33 -04:00
app use cloudlibrary info to search 2026-10-18 09:02:10 -04:00
config download books from cloudlibrary 2026-10-18 08:51:54 -04:00
migrations migrations 2026-10-12 07:01:11 -04:00
resources migrate to salusa 2026-07-15 03:51:54 -04:00
routes download books from cloudlibrary 2026-10-18 08:51:54 -04:00
services fix workflows 2026-10-20 05:52:33 -04:00
test remove calibre 2026-10-12 06:37:51 -04:00
tests/integration remove calibre 2026-10-12 06:37:51 -04:00
ui use cloudlibrary info to search 2026-10-18 09:02:10 -04:00
.air.toml migrate to salusa 2026-07-15 03:51:54 -04:00
.dockerignore add node build step 2026-07-16 09:10:28 -04:00
.env.example download books from cloudlibrary 2026-10-18 08:51:54 -04:00
.gitignore download books from cloudlibrary 2026-10-18 08:51:54 -04:00
AGENTS.md remove calibre 2026-10-12 06:37:51 -04:00
compose.yaml download books from cloudlibrary 2026-10-18 08:51:54 -04:00
Dockerfile add cloudlibrary 2026-10-18 07:55:05 -04:00
go.mod remove calibre 2026-10-12 06:37:51 -04:00
go.sum remove calibre 2026-10-12 06:37:51 -04:00
main.go remove calibre 2026-10-12 06:37:51 -04:00
README.md download books from cloudlibrary 2026-10-18 08:51:54 -04:00
spice.yml migrate to salusa 2026-07-15 03:51:54 -04:00

Page

Page stores its book catalogue in SQLite using Salusa's database connection, transactions, and migrations. Calibre and calibredb are no longer required.

Set DATABASE_PATH to Page's SQLite database (default ./db.sqlite) and LIBRARY_PATH to the directory containing the library files. Existing CALIBRE_LIBRARY settings remain supported when LIBRARY_PATH is unset. The Docker image keeps the existing /config, /calibre, and /downloads mounts, with the catalogue at /config/db.sqlite.

To run with Docker Compose, copy .env.example to .env, set LIBRARY_PATH to your host library directory, and configure any integrations you use. Start Page with:

docker compose up -d --build

Page is available at http://localhost:2303 by default; PORT changes the host port and BASE_PATH sets its public URL. Compose stores the database, daemon state, and Adobe activation data in the page-config volume. The library is mounted at /calibre, using LIBRARY_PATH (or CALIBRE_LIBRARY as a fallback) on the host. Set DOWNLOADS_PATH in .env to your host download directory; it defaults to ./downloads and is mounted at /downloads.

Integration URLs such as QBIT_URL and JACKETT_URL must be reachable from the container; localhost refers to the Page container itself. If qBittorrent reports paths other than /downloads, set DOCKER_PATH_MAP in .env, for example DOCKER_PATH_MAP=/data/downloads=/downloads. Compose uses this instead of the host-oriented PATH_MAP setting.

When Page first opens a library containing a Calibre metadata.db, it imports that catalogue into its own database in one transaction. Book IDs, identifiers, metadata, and existing file paths are preserved. The source database is opened read-only, and existing folders and files are neither renamed nor moved. Audio tracks stored alongside books by older Page versions are included too. A failed import rolls back and is retried when the library is next opened.

Keep DATABASE_PATH separate from the original metadata.db. After migration, Page's database is authoritative: later changes made through Calibre are not synchronized. Persist and back up both Page's database and the library files. An existing Page catalogue cannot be combined automatically with another Calibre catalogue because their book IDs may overlap.

New authors use their names as folder names, for example Ada Author/Book (43). Existing author paths such as Ada Author (9) are reused, including when adding another book by that author. Characters that cannot safely form a filename are replaced with underscores. Book directories retain an ID suffix to distinguish books with the same title. Existing ebook formats are preserved on repeat imports; audiobook tracks are stored by filename.

Every five minutes, page:scan runs a library scan to register book folders that exist under LIBRARY_PATH but are missing from Page's catalogue. The scan expects Author/Book/ folders, includes audio tracks in subfolders, and leaves all files and paths in place. It reads metadata.opf or embedded EPUB metadata, falling back to folder names when metadata is unavailable. It does not need Hardcover or qBittorrent. Indexed book folders are skipped, so scans do not overwrite catalogue edits or synchronize new formats into existing books. Symlinks and unrelated files are ignored; failed folders are reported and retried on the next scan. DRY_RUN prevents the scan from writing catalogue entries.

Book search supports plain text and the title:, authors:, series:, isbn:, tags:, id:, and identifiers:type:value prefixes. Calibre's advanced Boolean search expressions and custom columns are not imported or interpreted.

Run the checks with:

go test ./...
golangci-lint run ./...
CGO_ENABLED=0 go build .