mirror of
https://github.com/myronblair/kino-app
synced 2026-07-28 05:23:45 -05:00
auto-commit for 14921357-f5e2-4aba-b4c1-a07a52c800cc
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
"""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"),
|
||||
}
|
||||
Reference in New Issue
Block a user