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:
60
backend/adapters/hdhive_adapter.py
Normal file
60
backend/adapters/hdhive_adapter.py
Normal file
@@ -0,0 +1,60 @@
|
||||
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},
|
||||
}
|
||||
Reference in New Issue
Block a user