Archived
- add uv configuration for the backend - update frontend to make auth work - add new auth endpoints - add bookmars feat - add reader feat
79 lines
2.3 KiB
Python
79 lines
2.3 KiB
Python
from __future__ import annotations
|
|
|
|
import logging
|
|
from datetime import datetime, timezone
|
|
|
|
from django.core.files.base import ContentFile
|
|
|
|
from apps.books.models import EBook
|
|
from apps.books.services.openlibrary import (
|
|
HIGH_CONFIDENCE,
|
|
download_cover,
|
|
fetch_metadata,
|
|
)
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def enrich_ebook_metadata(ebook: EBook) -> EBook:
|
|
"""Fetch Open Library metadata and update the ebook. Never raises to callers."""
|
|
user_title = ebook.title
|
|
user_author = ebook.author or ""
|
|
|
|
try:
|
|
result = fetch_metadata(user_title, user_author)
|
|
except Exception:
|
|
logger.exception("Open Library metadata fetch failed for ebook %s", ebook.pk)
|
|
return ebook
|
|
|
|
if result is None:
|
|
return ebook
|
|
|
|
now = datetime.now(timezone.utc).isoformat()
|
|
metadata = {
|
|
"source": "openlibrary",
|
|
"matched_at": now,
|
|
"match_language": result.match_language,
|
|
"match_score": result.match_score,
|
|
"match_status": result.match_status,
|
|
"user_input": {"title": user_title, "author": user_author},
|
|
"openlibrary": result.openlibrary,
|
|
}
|
|
ebook.metadata_json = metadata
|
|
|
|
update_fields = ["metadata_json", "updated_at"]
|
|
|
|
if result.match_status == "not_found":
|
|
ebook.save(update_fields=update_fields)
|
|
return ebook
|
|
|
|
ol = result.openlibrary
|
|
cover_id = ol.get("cover_id")
|
|
|
|
cover_missing = (
|
|
not ebook.cover_image
|
|
or not ebook.cover_image.name
|
|
or not ebook.cover_image.storage.exists(ebook.cover_image.name)
|
|
)
|
|
if cover_id and cover_missing:
|
|
if ebook.cover_image:
|
|
ebook.cover_image.delete(save=False)
|
|
cover_bytes = download_cover(int(cover_id))
|
|
if cover_bytes:
|
|
filename = f"ol_cover_{ebook.pk}_{cover_id}.jpg"
|
|
ebook.cover_image.save(filename, ContentFile(cover_bytes), save=False)
|
|
update_fields.append("cover_image")
|
|
|
|
if result.match_score >= HIGH_CONFIDENCE:
|
|
ol_title = ol.get("title")
|
|
ol_authors = ol.get("authors") or []
|
|
if ol_title:
|
|
ebook.title = ol_title[:512]
|
|
update_fields.append("title")
|
|
if ol_authors:
|
|
ebook.author = ol_authors[0][:256]
|
|
update_fields.append("author")
|
|
|
|
ebook.save(update_fields=list(dict.fromkeys(update_fields)))
|
|
return ebook
|