mirror of
https://github.com/markbeep/AudioBookRequest.git
synced 2026-01-07 06:00:04 -06:00
add audimeta metadata server
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import asyncio
|
||||
import logging
|
||||
import time
|
||||
from datetime import datetime
|
||||
from typing import Any, Literal, Optional
|
||||
@@ -10,10 +11,22 @@ from sqlmodel import Session, col, select
|
||||
|
||||
from app.internal.models import BookRequest
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
REFETCH_TTL = 60 * 60 * 24 * 7 # 1 week
|
||||
|
||||
audible_region_type = Literal[
|
||||
"us", "ca", "uk", "au", "fr", "de", "jp", "it", "in", "es"
|
||||
"us",
|
||||
"ca",
|
||||
"uk",
|
||||
"au",
|
||||
"fr",
|
||||
"de",
|
||||
"jp",
|
||||
"it",
|
||||
"in",
|
||||
"es",
|
||||
"br",
|
||||
]
|
||||
audible_regions: dict[audible_region_type, str] = {
|
||||
"us": ".com",
|
||||
@@ -26,10 +39,11 @@ audible_regions: dict[audible_region_type, str] = {
|
||||
"it": ".it",
|
||||
"in": ".in",
|
||||
"es": ".es",
|
||||
"br": ".com.br",
|
||||
}
|
||||
|
||||
|
||||
async def get_audnexus_book(
|
||||
async def _get_audnexus_book(
|
||||
session: ClientSession,
|
||||
asin: str,
|
||||
region: audible_region_type,
|
||||
@@ -41,6 +55,9 @@ async def get_audnexus_book(
|
||||
f"https://api.audnex.us/books/{asin}?region={region}"
|
||||
) as response:
|
||||
if not response.ok:
|
||||
logger.warning(
|
||||
f"Failed to fetch book with ASIN {asin} from Audnexus: {response.status}: {response.reason}"
|
||||
)
|
||||
return None
|
||||
book = await response.json()
|
||||
return BookRequest(
|
||||
@@ -55,6 +72,51 @@ async def get_audnexus_book(
|
||||
)
|
||||
|
||||
|
||||
async def _get_audimeta_book(
|
||||
session: ClientSession,
|
||||
asin: str,
|
||||
region: audible_region_type,
|
||||
) -> Optional[BookRequest]:
|
||||
"""
|
||||
https://audimeta.de/api-docs/#/book/get_book__asin_
|
||||
"""
|
||||
async with session.get(
|
||||
f"https://audimeta.de/book/{asin}?region={region}"
|
||||
) as response:
|
||||
if not response.ok:
|
||||
logger.warning(
|
||||
f"Failed to fetch book with ASIN {asin} from Audimeta: {response.status}: {response.reason}"
|
||||
)
|
||||
return None
|
||||
book = await response.json()
|
||||
return BookRequest(
|
||||
asin=book["asin"],
|
||||
title=book["title"],
|
||||
subtitle=book.get("subtitle"),
|
||||
authors=[author["name"] for author in book["authors"]],
|
||||
narrators=[narrator["name"] for narrator in book["narrators"]],
|
||||
cover_image=book.get("imageUrl"),
|
||||
release_date=datetime.fromisoformat(book["releaseDate"]),
|
||||
runtime_length_min=book["lengthMinutes"] or 0,
|
||||
)
|
||||
|
||||
|
||||
async def get_book_by_asin(
|
||||
session: ClientSession,
|
||||
asin: str,
|
||||
audible_region: audible_region_type = "us",
|
||||
) -> Optional[BookRequest]:
|
||||
book = await _get_audimeta_book(session, asin, audible_region)
|
||||
if book:
|
||||
return book
|
||||
book = await _get_audnexus_book(session, asin, audible_region)
|
||||
if book:
|
||||
return book
|
||||
logger.warning(
|
||||
f"Failed to fetch book with ASIN {asin} from both Audnexus and Audimeta. "
|
||||
)
|
||||
|
||||
|
||||
class CacheQuery(pydantic.BaseModel, frozen=True):
|
||||
query: str
|
||||
num_results: int
|
||||
@@ -160,7 +222,7 @@ async def list_audible_books(
|
||||
asins.remove(key)
|
||||
|
||||
# book ASINs we do not have => fetch and store
|
||||
coros = [get_audnexus_book(client_session, asin, audible_region) for asin in asins]
|
||||
coros = [get_book_by_asin(client_session, asin, audible_region) for asin in asins]
|
||||
new_books = await asyncio.gather(*coros)
|
||||
new_books = [b for b in new_books if b]
|
||||
store_new_books(session, new_books)
|
||||
|
||||
@@ -17,7 +17,7 @@ from app.internal import book_search
|
||||
from app.internal.book_search import (
|
||||
audible_region_type,
|
||||
audible_regions,
|
||||
get_audnexus_book,
|
||||
get_book_by_asin,
|
||||
list_audible_books,
|
||||
)
|
||||
from app.internal.models import (
|
||||
@@ -159,7 +159,7 @@ async def add_request(
|
||||
region: Annotated[audible_region_type, Form()],
|
||||
num_results: Annotated[int, Form()] = 20,
|
||||
):
|
||||
book = await get_audnexus_book(client_session, asin, region)
|
||||
book = await get_book_by_asin(client_session, asin, region)
|
||||
if not book:
|
||||
raise HTTPException(status_code=404, detail="Book not found")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user