mirror of
https://github.com/myronblair/kino-app
synced 2026-06-30 17:50:16 -05:00
89 lines
2.9 KiB
Python
89 lines
2.9 KiB
Python
"""TMDB API client. Uses v3 API with api_key query param."""
|
|
import requests
|
|
from typing import List, Dict, Optional
|
|
|
|
BASE = "https://api.themoviedb.org/3"
|
|
IMG = "https://image.tmdb.org/t/p"
|
|
|
|
|
|
def _img(path: Optional[str], size: str = "w500") -> str:
|
|
if not path:
|
|
return ""
|
|
return f"{IMG}/{size}{path}"
|
|
|
|
|
|
def search_movies(api_key: str, query: str) -> List[Dict]:
|
|
if not api_key or not query.strip():
|
|
return []
|
|
r = requests.get(f"{BASE}/search/movie", params={"api_key": api_key, "query": query}, timeout=15)
|
|
r.raise_for_status()
|
|
data = r.json().get("results", []) or []
|
|
out = []
|
|
for m in data[:20]:
|
|
year = None
|
|
if m.get("release_date"):
|
|
try: year = int(m["release_date"].split("-")[0])
|
|
except Exception: pass
|
|
out.append({
|
|
"tmdb_id": m["id"],
|
|
"title": m.get("title") or m.get("name") or "",
|
|
"year": year,
|
|
"overview": m.get("overview") or "",
|
|
"poster_url": _img(m.get("poster_path"), "w500"),
|
|
"backdrop_url": _img(m.get("backdrop_path"), "original"),
|
|
})
|
|
return out
|
|
|
|
|
|
def get_movie(api_key: str, tmdb_id: int) -> Dict:
|
|
"""Return rich movie details with cast/crew."""
|
|
r = requests.get(
|
|
f"{BASE}/movie/{tmdb_id}",
|
|
params={"api_key": api_key, "append_to_response": "credits"},
|
|
timeout=15,
|
|
)
|
|
r.raise_for_status()
|
|
m = r.json()
|
|
year = None
|
|
if m.get("release_date"):
|
|
try: year = int(m["release_date"].split("-")[0])
|
|
except Exception: pass
|
|
|
|
credits = m.get("credits", {}) or {}
|
|
cast = [c["name"] for c in (credits.get("cast") or [])[:8] if c.get("name")]
|
|
crew = credits.get("crew") or []
|
|
director = next((c["name"] for c in crew if c.get("job") == "Director"), "")
|
|
genres = [g["name"] for g in (m.get("genres") or []) if g.get("name")]
|
|
|
|
# Map TMDB certifications to our rating scale (best effort, US fallback)
|
|
rating = "NR"
|
|
try:
|
|
rel = requests.get(
|
|
f"{BASE}/movie/{tmdb_id}/release_dates",
|
|
params={"api_key": api_key}, timeout=10,
|
|
).json()
|
|
for r_country in rel.get("results", []):
|
|
if r_country.get("iso_3166_1") == "US":
|
|
for d in r_country.get("release_dates", []) or []:
|
|
cert = (d.get("certification") or "").strip()
|
|
if cert:
|
|
rating = cert
|
|
break
|
|
break
|
|
except Exception:
|
|
pass
|
|
|
|
return {
|
|
"tmdb_id": m["id"],
|
|
"title": m.get("title") or "",
|
|
"year": year,
|
|
"description": m.get("overview") or "",
|
|
"duration_minutes": m.get("runtime") or 0,
|
|
"rating": rating or "NR",
|
|
"genres": genres,
|
|
"cast": cast,
|
|
"director": director,
|
|
"poster_url": _img(m.get("poster_path"), "w500"),
|
|
"backdrop_url": _img(m.get("backdrop_path"), "original"),
|
|
}
|