v4.0.19 — cover quality + focused cover-picker UI
Suggested release title:
v4.0.19 — better cover sources + a focused cover-picker UI
How to ship this release
After PRs #65 and #66 merge to main:
cd repo
git checkout main && git pull
MERGE_SHA=$(git rev-parse HEAD)
gh release create v4.0.19 \
--repo new-usemame/Calibre-Web-NextGen \
--target "$MERGE_SHA" \
--title "v4.0.19 — better cover sources + a focused cover-picker UI" \
--notes-file ../notes/release-v4.0.19-draft.mdPublishing the GitHub release fires .github/workflows/docker-image-build-release.yml, which builds the multi-arch image and pushes to ghcr.io/new-usemame/calibre-web-nextgen:v4.0.19 and :latest.
Identity: every git command runs under new-usemame <248195428+new-usemame@users.noreply.github.com>. The gh CLI uses the active GitHub auth which is already new-usemame.
If the release pipeline fails, do NOT delete the release — investigate the workflow logs and re-run failed jobs via gh run rerun. Deleting the release would also delete the tag.
Release body (paste below the divider into gh release create)
This release is all about covers — getting better ones from more sources, and giving you a focused UI to pick the one you want without the metadata-fetch modal getting in the way.
Get it
docker pull ghcr.io/new-usemame/calibre-web-nextgen:v4.0.19
Same volume layout as previous releases — no migration needed. The cover-lock table (book_cover_lock in app.db) is created automatically on first boot.
What's new
Cover quality — Amazon image-CDN booster + Apple Books provider (#65)
The cover-fetch pipeline now reaches more sources and gets edition-correct covers more often.
- Amazon image CDN as a booster path. When any provider returns a record with an ISBN, the booster probes Amazon's public CloudFront-fronted image CDN (
m.media-amazon.com/images/P/<ISBN>.01._SCRM_SL2000_.jpg) and rewrites the cover URL when a high-resolution version exists. Edition-keyed by ISBN-10/ASIN, so we get the right cover for the right edition — including the Wordsworth Classics editions where the cover is a famous painting. No scraping; this is the public CORS-enabled CDN withaccess-control-allow-origin: *. - Apple Books as a first-class metadata provider. Surfaces in the metadata-search modal and the new cover picker as its own provider rows, with full title / authors / description / genres / published-date and 1500-px artwork. Ships with the standard provider auto-discovery — toggle it like any other source.
- Tighter iTunes wrong-edition guard. The cover booster's iTunes title-search no longer fires when the record already has an ISBN that didn't match Apple's catalog, and rejects hits whose release year diverges from the record's by more than ±20 years. Fixes a class of "1992 Wordsworth print → 2008 Penguin ebook cover" silent substitutions.
- Knobs.
CWA_COVER_BOOST_AMAZON_CDN=0disables only the new Amazon CDN path; the existingCWA_COVER_BOOST=0still kills the entire booster.
33 new unit tests cover the booster path order, ISBN-13→10 conversion, the placeholder-filter for Amazon's 43-byte image/gif for unknown ASINs, and the Apple Books provider.
Focused cover-picker UI (#66)
A new page dedicated to swapping covers, separate from the metadata-search modal which keeps doing what it does.
/book/<id>/cover— entry buttons added on the book detail page and the edit-metadata page. Layout: current cover left, candidate grid right.- Multi-source candidate grid. Every enabled metadata provider contributes covers to the grid, with provider badges, pixel dimensions, and a low-res warning. Adding a new provider to
cps/metadata_provider/automatically contributes candidates here too — no picker-side code changes needed. - Inline panels for paste-URL (live preview before commit), file upload, and API key management (reused from the existing
/metadata/keysflow). - Embedded-cover candidate — the cover stored inside the book file (EPUB / CBZ / PDF) shows up as a first-class candidate alongside the network sources. Resolves the recurring "regenerate cover from the file" ask.
- Side-by-side confirm modal before the swap commits. Resolves the highest-signal cover-related upstream issue (janeczku/calibre-web#2165, 8 hearts) — "don't clobber my cover when fetching metadata."
- Per-book cover lock. Toggle from the picker page. When on, the metadata-fetch save path skips cover assignment with a clear flash message instead of silently overwriting.
Reliable inline cover-URL preview on the edit page
The existing cover_url field on the edit-metadata page got a debounced live preview.
POST /metadata/cover/preview— runs the same SSRF-guarded HEAD probe the save path uses. Returns dimensions + size + content-type + structured error.- The field shows a thumbnail and meta line as you type. Failure (SSRF blocked / not an image / too small / too large) is visible at paste time, not after a full form-save round-trip.
Architecture notes
- No new dependencies. Pillow / lxml / Wand /
cw_advocateare all already in the production image. - No new env vars required for first boot. Optional knobs:
CWA_COVER_PICKER_TIMEOUT/CWA_COVER_PICKER_WORKERS/CWA_COVER_PICKER_MAX_CANDIDATESfor the picker;CWA_COVER_BOOST_AMAZON_CDNfor the new booster path. - No bundlers, no transpilers, no new build steps. Plain ES2017+ JS, plain CSS, dropped into the existing
cps/static/{js,css}/. - Plugin-friendly. New cover sources extend the existing provider auto-discovery (
cps/metadata_provider/<source>.py).
Tests
69 new unit tests across the two PRs:
tests/unit/test_cover_booster.py(22)tests/unit/test_apple_books_provider.py(11)tests/unit/test_cover_url_validator.py(14)tests/unit/test_cover_picker_service.py(10)tests/unit/test_cover_extract.py(12; 3 EPUB tests skipped withoutlxmlin dev env, run in production)
Both PRs were end-to-end verified on a real Calibre-Web instance against the live Amazon CDN, the live Apple Books search, the live Open Library search, and the deployed Flask test client through the full WSGI stack.
Credits
Cover work designed and implemented for users who said "the modal does too much when I just want a different cover." The 8-heart cover-lock signal came from janeczku/calibre-web#2165.
What's next
The cover-fetch pipeline is now plumbed for easy expansion — Edelweiss, Penguin Random House, Barnes & Noble's prodimage.images-bn.com, and the Calibre google_images.py last-resort search are all viable additions. Drop a file in cps/metadata_provider/, no other registration code needed.