"""Client for consuming Xtream Codes API from provider.""" import aiohttp import asyncio from typing import Any import logging logger = logging.getLogger(__name__) class XtreamClient: def __init__(self, base_url: str, username: str, password: str): self.base_url = base_url.rstrip("/") self.username = username self.password = password def _api_url(self) -> str: return f"{self.base_url}/player_api.php" async def _get(self, params: dict) -> Any: params = {"username": self.username, "password": self.password, **params} timeout = aiohttp.ClientTimeout(total=30) async with aiohttp.ClientSession(timeout=timeout) as session: async with session.get(self._api_url(), params=params, ssl=False) as resp: resp.raise_for_status() return await resp.json(content_type=None) async def get_user_info(self) -> dict: return await self._get({}) async def get_live_categories(self) -> list[dict]: return await self._get({"action": "get_live_categories"}) async def get_live_streams(self, category_id: str | None = None) -> list[dict]: params = {"action": "get_live_streams"} if category_id: params["category_id"] = category_id return await self._get(params) async def get_vod_categories(self) -> list[dict]: return await self._get({"action": "get_vod_categories"}) async def get_vod_streams(self, category_id: str | None = None) -> list[dict]: params = {"action": "get_vod_streams"} if category_id: params["category_id"] = category_id return await self._get(params) async def get_series_categories(self) -> list[dict]: return await self._get({"action": "get_series_categories"}) async def get_series(self, category_id: str | None = None) -> list[dict]: params = {"action": "get_series"} if category_id: params["category_id"] = category_id return await self._get(params) async def get_series_info(self, series_id: str) -> dict: return await self._get({"action": "get_series_info", "series_id": series_id}) async def get_vod_info(self, vod_id: str) -> dict: return await self._get({"action": "get_vod_info", "vod_id": vod_id}) async def get_epg(self, stream_id: str | None = None) -> dict: params = {"action": "get_short_epg"} if stream_id: params["stream_id"] = stream_id return await self._get(params) def build_live_stream_url(self, stream_id: str, ext: str = "ts") -> str: return f"{self.base_url}/{self.username}/{self.password}/{stream_id}.{ext}" def build_vod_stream_url(self, stream_id: str, ext: str = "mkv") -> str: return f"{self.base_url}/movie/{self.username}/{self.password}/{stream_id}.{ext}" def build_series_stream_url(self, stream_id: str, ext: str = "mkv") -> str: return f"{self.base_url}/series/{self.username}/{self.password}/{stream_id}.{ext}" def get_xmltv_url(self) -> str: return f"{self.base_url}/xmltv.php?username={self.username}&password={self.password}" async def test_connection(self) -> bool: try: info = await self.get_user_info() return info.get("user_info", {}).get("status") == "Active" except Exception as e: logger.warning(f"Provider connection test failed: {e}") return False