Fix #3: Old cover shown after updating book cover
All checks were successful
CI / quality-checks (push) Successful in 1m10s

Caddy is set up to serve static files with aggressive caching, which is
great for performance but can cause issues when updating book covers. To
ensure users see the updated cover immediately, we need implement a
cache-busting strategy. This involves generating a unique filename for
each cover image based on its content, using a hash of the image data.
By doing this, when a cover is updated, it will have a new filename,
prompting browsers to fetch the new image instead of using the cached
version.
This commit is contained in:
2026-04-01 11:03:36 +02:00
parent dc73de6799
commit 206b2a9d5b

View File

@@ -5,6 +5,7 @@ Clean service layer for book management, reading tracking, and wishlist operatio
Separated from web interface concerns to enable both CLI and web access. Separated from web interface concerns to enable both CLI and web access.
""" """
import hashlib
import logging import logging
from collections import defaultdict from collections import defaultdict
from collections.abc import Sequence from collections.abc import Sequence
@@ -1013,32 +1014,27 @@ def download_book_cover(book: Book, image_url: str) -> bool:
return False return False
# Load image directly from file # Load image directly from file
with Image.open(source_path) as image: source = source_path
processed_image = _process_cover_image(image)
# Generate filename
extension = ".jpg" # Always save as JPEG
filename = f"book_{book.id}{extension}"
cover_path = covers_dir / filename
# Save processed image
processed_image.save(cover_path, "JPEG", quality=85)
else: else:
# Handle HTTP(S) URLs # Handle HTTP(S) URLs
response = requests.get(image_url, timeout=10, stream=True) response = requests.get(image_url, timeout=10, stream=True)
response.raise_for_status() response.raise_for_status()
# Load image from response content # Load image from response content
with Image.open(response.raw) as image: source = response.raw
processed_image = _process_cover_image(image)
# Generate filename with Image.open(source) as image:
extension = ".jpg" # Always save as JPEG processed_image = _process_cover_image(image)
filename = f"book_{book.id}{extension}"
cover_path = covers_dir / filename
# Save processed image # Generate filename
processed_image.save(cover_path, "JPEG", quality=85) extension = ".jpg" # Always save as JPEG
# Hash the image to create a unique filename based on content
image_hash = hashlib.md5(processed_image.tobytes()).hexdigest()
filename = f"book_{book.id}_{image_hash}{extension}"
cover_path = covers_dir / filename
# Save processed image
processed_image.save(cover_path, "JPEG", quality=85)
# Update book record # Update book record
book.cover_image_path = filename book.cover_image_path = filename