Files
media_crawler/backend/adapters/hdhive_adapter.py
renjue 82581d2949 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>
2026-05-09 16:16:18 +08:00

61 lines
2.0 KiB
Python

from config import Config
from http_client import request_json
def _headers():
headers = {
"Accept": "application/json",
"X-API-Key": Config.HDHIVE_API_KEY,
}
if Config.HDHIVE_ACCESS_TOKEN:
headers["Authorization"] = f"Bearer {Config.HDHIVE_ACCESS_TOKEN}"
return headers
def search_resource(media_type, tmdb_id):
url = f"{Config.HDHIVE_BASE_URL}/api/open/resources/{media_type}/{tmdb_id}"
return request_json(
url,
headers=_headers(),
max_retry=Config.MAX_RETRY,
retry_delay_ms=Config.RETRY_DELAY_MS,
provider="hdhive",
)
def unlock_link(slug):
url = f"{Config.HDHIVE_BASE_URL}/api/open/resources/unlock"
return request_json(
url,
method="POST",
payload={"slug": slug},
headers={**_headers(), "Content-Type": "application/json"},
max_retry=Config.MAX_RETRY,
retry_delay_ms=Config.RETRY_DELAY_MS,
provider="hdhive",
)
def normalize_resource(search_data, unlock_data):
resolution = (search_data or {}).get("video_resolution")
source = (search_data or {}).get("source")
subtitle_language = (search_data or {}).get("subtitle_language")
return {
"resourceTitle": (search_data or {}).get("title", ""),
"quality": ", ".join(resolution) if isinstance(resolution, list) else "",
"size": (search_data or {}).get("share_size", ""),
"diskType": (search_data or {}).get("pan_type", ""),
"source": ", ".join(source) if isinstance(source, list) else "",
"subtitleLanguage": ", ".join(subtitle_language)
if isinstance(subtitle_language, list)
else "",
"slug": (search_data or {}).get("slug", ""),
"unlockUrl": (unlock_data or {}).get("full_url")
or (unlock_data or {}).get("url")
or "",
"availability": "available"
if ((unlock_data or {}).get("full_url") or (unlock_data or {}).get("url"))
else "unknown",
"raw": {"searchData": search_data, "unlockData": unlock_data},
}