Implement full media crawler workflow with Flask backend and Vue frontend.
Add TMDB search and media detail pages, HDHive resource ingestion flow, unified error handling, Docker single-container runtime, and project docs/config updates for local deployment. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
56
backend/adapters/tmdb_adapter.py
Normal file
56
backend/adapters/tmdb_adapter.py
Normal file
@@ -0,0 +1,56 @@
|
||||
from config import Config
|
||||
from http_client import request_json
|
||||
from urllib.parse import quote
|
||||
|
||||
|
||||
def _headers():
|
||||
headers = {"Content-Type": "application/json"}
|
||||
if Config.TMDB_TOKEN:
|
||||
headers["Authorization"] = f"Bearer {Config.TMDB_TOKEN}"
|
||||
return headers
|
||||
|
||||
|
||||
def search_media(query, media_type="movie", page=1):
|
||||
normalized_type = "tv" if media_type == "tv" else "movie"
|
||||
url = (
|
||||
f"{Config.TMDB_BASE_URL}/search/{normalized_type}"
|
||||
f"?language=zh-CN&query={quote(str(query))}&page={page}"
|
||||
)
|
||||
result = request_json(
|
||||
url,
|
||||
headers=_headers(),
|
||||
max_retry=Config.MAX_RETRY,
|
||||
retry_delay_ms=Config.RETRY_DELAY_MS,
|
||||
provider="tmdb",
|
||||
)
|
||||
data = result.get("data") or {}
|
||||
result["items"] = data.get("results") if isinstance(data, dict) else []
|
||||
return result
|
||||
|
||||
|
||||
def get_media_detail(tmdb_id, media_type):
|
||||
normalized_type = "tv" if media_type == "tv" else "movie"
|
||||
url = f"{Config.TMDB_BASE_URL}/{normalized_type}/{tmdb_id}?language=zh-CN"
|
||||
result = request_json(
|
||||
url,
|
||||
headers=_headers(),
|
||||
max_retry=Config.MAX_RETRY,
|
||||
retry_delay_ms=Config.RETRY_DELAY_MS,
|
||||
provider="tmdb",
|
||||
)
|
||||
data = result.get("data") or {}
|
||||
normalized = {
|
||||
"tmdbId": tmdb_id,
|
||||
"type": normalized_type,
|
||||
"title": data.get("title") or data.get("name") or "",
|
||||
"originalTitle": data.get("original_title") or data.get("original_name") or "",
|
||||
"overview": data.get("overview") or "",
|
||||
"year": (data.get("release_date") or data.get("first_air_date") or "")[:4],
|
||||
"rating": data.get("vote_average"),
|
||||
"posterPath": data.get("poster_path") or "",
|
||||
"genres": [g.get("name") for g in data.get("genres", []) if g.get("name")],
|
||||
"seasons": len(data.get("seasons", [])) if isinstance(data.get("seasons"), list) else 0,
|
||||
"raw": data,
|
||||
}
|
||||
result["normalized"] = normalized
|
||||
return result
|
||||
Reference in New Issue
Block a user