from adapters.hdhive_adapter import normalize_resource, search_resource, unlock_link from adapters.tmdb_adapter import get_media_detail, search_media from error_handling import AppServiceError def _extract_hdhive_items(hdhive_result): payload = (hdhive_result or {}).get("data") # HDHive openapi uses envelope: { success, data, ... } if isinstance(payload, dict) and isinstance(payload.get("data"), list): return payload.get("data") or [] if isinstance(payload, list): return payload if isinstance(payload, dict): return payload.get("items") or [] return [] def _extract_hdhive_unlock_data(unlock_result): payload = (unlock_result or {}).get("data") # HDHive unlock response is usually envelope with inner data object. if isinstance(payload, dict) and isinstance(payload.get("data"), dict): return payload.get("data") or {} if isinstance(payload, dict): return payload return {} def search_media_by_keyword(query, media_type): result = search_media(query, media_type) raw_items = result.get("items") or [] items = [] for item in raw_items: items.append( { "id": item.get("id"), "type": media_type, "title": item.get("title") or item.get("name"), "overview": item.get("overview") or "", "posterPath": item.get("poster_path") or "", "releaseDate": item.get("release_date") or item.get("first_air_date") or "", "voteAverage": item.get("vote_average"), } ) return {"items": items} def get_media_resources(media_type, tmdb_id): detail = get_media_detail(tmdb_id, media_type) hdhive = search_resource(media_type, tmdb_id) search_data = _extract_hdhive_items(hdhive) resources = [] for item in search_data: slug = (item or {}).get("slug") unlock_data = {} unlock_error = None if slug: try: unlock = unlock_link(slug) unlock_data = _extract_hdhive_unlock_data(unlock) except Exception as error: unlock_error = str(error) normalized = normalize_resource(item, unlock_data) normalized["unlockError"] = unlock_error resources.append(normalized) return { "media": detail.get("normalized"), "resources": resources, } def validate_media_query(query, media_type): if not query: raise AppServiceError( "query is required", category="validation", code="INVALID_INPUT", status=400, provider="api", ) validate_media_type(media_type) def validate_media_type(media_type): if media_type not in ("movie", "tv"): raise AppServiceError( "type must be movie or tv", category="validation", code="INVALID_INPUT", status=400, provider="api", )