From 2f3a891d0944a3b200d3dda949475bf9e1742f56 Mon Sep 17 00:00:00 2001 From: Tyler Hoang Date: Sat, 9 May 2026 01:41:48 -0700 Subject: Add IMDb, Rotten Tomatoes, and Metacritic ratings to film detail Fetches ratings from OMDB API in parallel with TMDB context. Displays three side-by-side chips between the subtitle and watch log panels. Requires OMDB_API_KEY in .env; degrades silently if missing or no match. Co-Authored-By: Claude Sonnet 4.6 --- services/omdb.py | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 services/omdb.py (limited to 'services') diff --git a/services/omdb.py b/services/omdb.py new file mode 100644 index 0000000..8e574a1 --- /dev/null +++ b/services/omdb.py @@ -0,0 +1,51 @@ +import os + +import httpx + +OMDB_URL = "http://www.omdbapi.com/" + + +def _api_key() -> str | None: + return os.getenv("OMDB_API_KEY", "").strip() or None + + +async def fetch_ratings( + *, + title: str | None = None, + year: int | None = None, +) -> dict | None: + key = _api_key() + if not key or not title: + return None + + params: dict = {"apikey": key, "t": title} + if year: + params["y"] = str(year) + + try: + async with httpx.AsyncClient(timeout=5.0) as client: + response = await client.get(OMDB_URL, params=params) + data = response.json() + except Exception: + return None + + if data.get("Response") == "False": + return None + + result: dict = {} + for rating in data.get("Ratings", []): + source = rating.get("Source", "") + value = rating.get("Value", "") + if source == "Internet Movie Database": + result["imdb"] = value + elif source == "Rotten Tomatoes": + result["rt"] = value + elif source == "Metacritic": + result["metacritic"] = value + + if not result.get("imdb"): + raw = data.get("imdbRating", "") + if raw and raw != "N/A": + result["imdb"] = f"{raw}/10" + + return result or None -- cgit v1.3-2-g0d8e