|
@@ -29,6 +29,35 @@ from app.auth import (
|
|
|
from app.services.stats import ReadingStatsService
|
|
from app.services.stats import ReadingStatsService
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
+def extract_author_name(metadata: dict) -> str:
|
|
|
|
|
+ """
|
|
|
|
|
+ Extract author name from Audiobookshelf metadata.
|
|
|
|
|
+
|
|
|
|
|
+ Tries multiple fields in order:
|
|
|
|
|
+ 1. authorName (string field)
|
|
|
|
|
+ 2. authors array (extract first author's name)
|
|
|
|
|
+ 3. Falls back to "Unknown"
|
|
|
|
|
+ """
|
|
|
|
|
+ # Try authorName field first
|
|
|
|
|
+ author_name = metadata.get("authorName")
|
|
|
|
|
+ if author_name:
|
|
|
|
|
+ return author_name
|
|
|
|
|
+
|
|
|
|
|
+ # Try authors array
|
|
|
|
|
+ authors = metadata.get("authors", [])
|
|
|
|
|
+ if authors and len(authors) > 0:
|
|
|
|
|
+ # Authors can be objects with 'name' field or just strings
|
|
|
|
|
+ first_author = authors[0]
|
|
|
|
|
+ if isinstance(first_author, dict):
|
|
|
|
|
+ author_name = first_author.get("name")
|
|
|
|
|
+ if author_name:
|
|
|
|
|
+ return author_name
|
|
|
|
|
+ elif isinstance(first_author, str):
|
|
|
|
|
+ return first_author
|
|
|
|
|
+
|
|
|
|
|
+ return "Unknown"
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
@asynccontextmanager
|
|
@asynccontextmanager
|
|
|
async def lifespan(app: FastAPI):
|
|
async def lifespan(app: FastAPI):
|
|
|
"""Initialize database on startup."""
|
|
"""Initialize database on startup."""
|
|
@@ -324,7 +353,7 @@ async def sync_with_audiobookshelf(
|
|
|
book = Book(
|
|
book = Book(
|
|
|
id=book_id,
|
|
id=book_id,
|
|
|
title=metadata.get("title", "Unknown"),
|
|
title=metadata.get("title", "Unknown"),
|
|
|
- author=metadata.get("authorName", "Unknown"),
|
|
|
|
|
|
|
+ author=extract_author_name(metadata),
|
|
|
narrator=metadata.get("narratorName"),
|
|
narrator=metadata.get("narratorName"),
|
|
|
description=metadata.get("description"),
|
|
description=metadata.get("description"),
|
|
|
genres=json.dumps(metadata.get("genres", [])),
|
|
genres=json.dumps(metadata.get("genres", [])),
|
|
@@ -336,7 +365,7 @@ async def sync_with_audiobookshelf(
|
|
|
else:
|
|
else:
|
|
|
# Update existing book
|
|
# Update existing book
|
|
|
book.title = metadata.get("title", book.title)
|
|
book.title = metadata.get("title", book.title)
|
|
|
- book.author = metadata.get("authorName", book.author)
|
|
|
|
|
|
|
+ book.author = extract_author_name(metadata)
|
|
|
if local_cover_url: # Only update if download succeeded
|
|
if local_cover_url: # Only update if download succeeded
|
|
|
book.cover_url = local_cover_url
|
|
book.cover_url = local_cover_url
|
|
|
book.updated_at = datetime.now()
|
|
book.updated_at = datetime.now()
|