Add book covers

This commit is contained in:
2026-03-30 19:37:51 +02:00
parent be43fe8a0a
commit 93e3397553
14 changed files with 645 additions and 19 deletions

72
docs/cover-images.md Normal file
View File

@@ -0,0 +1,72 @@
# Book Cover Images Setup
HXBooks now supports book cover images using static file storage with nginx/caddy for production.
## Architecture
**Development**: Flask serves covers via `/media/covers/<filename>` route
**Production**: nginx serves covers directly from filesystem for optimal performance
## File Structure
```
/app/
├── src/hxbooks/static/ # App assets (CSS, JS) -> served at /static/
├── media/covers/ # Book covers -> served at /media/
└── instance/ # Database, config
```
## Production Deployment
### Docker Setup
```bash
# Build and run with nginx + gunicorn
docker-compose up --build
# Or build manually
docker build -f Dockerfile.production -t hxbooks .
docker run -p 8080:80 -v ./media:/app/media -v ./instance:/app/instance hxbooks
```
### nginx Configuration
- Static files: nginx serves `/static/` and `/media/` directly
- Dynamic requests: proxied to gunicorn on port 8080
- Proper caching headers for performance
## Cover Image Features
### CLI
```bash
# Import with cover download (default)
hxbooks book import "9780123456789"
# Skip cover download
hxbooks book import "9780123456789" --no-cover
```
### Web Interface
- Book cards display covers when available
- Fallback to book emoji for books without covers
- Google Books API integration provides cover URLs
## Storage Details
- **Images downloaded from**: Google Books API (thumbnail/smallThumbnail)
- **Filename format**: `book_{id}.{extension}`
- **Security**: HTTP URLs converted to HTTPS
- **Fallback**: graceful handling if download fails
- **Database**: `cover_image_path` field stores relative filename
## Performance
**nginx serves static files directly** (bypassing Python completely):
- ✅ ~1ms response time for images
- ✅ Proper browser caching
- ✅ Gzip compression
- ✅ No Python memory usage for images
vs. database BLOB storage through Python:
- ❌ ~50-200ms response time
- ❌ Limited caching options
- ❌ High memory usage
- ❌ Database file bloat