Files
wordarr/wordarr/metadata/audible.py
T

55 lines
1.9 KiB
Python

import asyncio
import os
import httpx
from .base import MetadataResult
# Comma-separated marketplace TLDs, first entries rank first in the results.
REGIONS = [r.strip() for r in os.environ.get("WORDARR_AUDIBLE_REGIONS", "de,com").split(",")]
async def _search_region(client: httpx.AsyncClient, tld: str, query: str) -> list[dict]:
params = {
"keywords": query,
"num_results": 10,
"response_groups": "media,contributors,product_desc,product_attrs",
"products_sort_by": "Relevance",
}
try:
resp = await client.get(f"https://api.audible.{tld}/1.0/catalog/products", params=params)
resp.raise_for_status()
return resp.json().get("products", [])
except httpx.HTTPError:
return []
async def search(query: str) -> list[MetadataResult]:
async with httpx.AsyncClient(timeout=15) as client:
region_results = await asyncio.gather(
*(_search_region(client, tld, query) for tld in REGIONS)
)
results = []
seen_asins = set()
for products in region_results:
for p in products:
asin = p.get("asin", "")
if asin in seen_asins:
continue
seen_asins.add(asin)
images = p.get("product_images") or {}
release = p.get("release_date") or ""
results.append(
MetadataResult(
media_type="audiobook",
title=p.get("title", ""),
authors=", ".join(a.get("name", "") for a in p.get("authors") or []),
narrator=", ".join(n.get("name", "") for n in p.get("narrators") or []),
external_id=asin,
year=int(release[:4]) if release[:4].isdigit() else None,
cover_url=next(iter(images.values()), ""),
)
)
return results