"""OMDb API Client — Fallback-Quelle für die Metadaten-Erkennung. Kommt zum Zug, wenn TMDB nichts (Sicheres) findet. Kostenloser Key von https://www.omdbapi.com/apikey.aspx (1000 Anfragen/Tag reichen fürs Heimlab). """ from typing import Dict, Optional import requests from cache import get, set as cache_set from config import settings OMDB_BASE_URL = "https://www.omdbapi.com/" def parse_runtime_minutes(runtime: str) -> int: """OMDb liefert '142 min' als Text → Minuten als Zahl (pure Funktion, testbar).""" if not runtime: return 0 teil = runtime.strip().split(" ")[0] return int(teil) if teil.isdigit() else 0 def parse_year(year: str) -> Optional[int]: """OMDb-Jahr kann '1999' oder '2005–2012' (Serie) sein → erstes Jahr.""" if not year: return None erste = year.strip()[:4] return int(erste) if erste.isdigit() else None class OMDbClient: def __init__(self): self.api_key = settings.omdb_api_key self.session = requests.Session() def lookup(self, title: str, year: Optional[int] = None) -> Optional[Dict]: """Sucht per Titel (t=), liefert normalisierte Metadaten oder None.""" if not self.api_key: return None cache_key = f"omdb:{title.lower()}:{year or ''}" cached = get(cache_key) if cached: return cached params = {"apikey": self.api_key, "t": title, "r": "json"} if year: params["y"] = str(year) try: response = self.session.get(OMDB_BASE_URL, params=params, timeout=10) response.raise_for_status() data = response.json() except Exception as e: print(f"OMDb API Error: {e}") return None if data.get("Response") != "True": return None ergebnis = { "type": "tv" if data.get("Type") == "series" else "movie", "id": data.get("imdbID", ""), "title": data.get("Title", title), "year": parse_year(data.get("Year", "")), "overview": data.get("Plot", ""), "poster_path": data.get("Poster", "") if data.get("Poster") != "N/A" else "", "backdrop_path": "", "runtime": parse_runtime_minutes(data.get("Runtime", "")), "genres": [g.strip() for g in data.get("Genre", "").split(",") if g.strip()], "source": "omdb", } cache_set(cache_key, ergebnis) return ergebnis