v0.3.16b0
Pre-releaseWhat's new
Cover placeholder rejection (#71)
Two-layer defence against junk cover images being saved to the Calibre library:
Layer 1 — OpenLibrary ?default=false
OpenLibrary's cover CDN serves a full-size "image not available" placeholder JPEG with HTTP 200 when a cover is missing. Content inspection cannot reliably distinguish it from a real cover. Adding ?default=false to all OL cover URLs converts these into 404 responses, which are already rejected.
Layer 2 — _download_cover validation
Even when a URL returns HTTP 200 with image/*, the body is validated before saving:
- Content-type must start with
image/(rejects HTML error pages, JSON, etc.) - Body must be ≥ 1024 bytes (rejects blank GIF stubs)
- Pixel dimensions must be ≥ 100px in both axes (rejects 1×1 tracking pixels); unknown formats (WebP, etc.) fail open
The pixel sniffer parses PNG IHDR, GIF header, and JPEG SOF0/SOF2 segments from the first ~500 bytes — no imaging library required.
New tests
12 tests in tests/unit/test_cover_validation.py covering _image_dimensions(), _download_cover() validation paths, and OL URL ?default=false on both cover_i and ISBN fallback URLs.
Full diff: v0.3.15b0...v0.3.16b0