"""Jellyfin + Arr suite media endpoints.""" import json import subprocess from fastapi import APIRouter import httpx router = APIRouter(tags=["media"]) JELLYFIN_API_KEY = "REDACTED_API_KEY" # pragma: allowlist secret SONARR_URL = "http://192.168.0.200:8989" SONARR_KEY = "REDACTED_SONARR_API_KEY" # pragma: allowlist secret RADARR_URL = "http://192.168.0.200:7878" RADARR_KEY = "REDACTED_RADARR_API_KEY" # pragma: allowlist secret SABNZBD_URL = "http://192.168.0.200:8080" SABNZBD_KEY = "6ae289de5a4f45f7a0124b43ba9c3dea" # pragma: allowlist secret def _jellyfin(path: str) -> dict: """Call Jellyfin API via SSH+kubectl to bypass Olares auth sidecar.""" sep = "&" if "?" in path else "?" url = f"http://localhost:8096{path}{sep}api_key={JELLYFIN_API_KEY}" try: result = subprocess.run( ["ssh", "-o", "ConnectTimeout=3", "olares", f"kubectl exec -n jellyfin-vishinator deploy/jellyfin -c jellyfin -- curl -s '{url}'"], capture_output=True, text=True, timeout=15, ) return json.loads(result.stdout) if result.returncode == 0 else {} except Exception: return {} @router.get("/jellyfin/status") def jellyfin_status(): """Jellyfin server status: version, libraries, sessions.""" info = _jellyfin("/System/Info") libraries = _jellyfin("/Library/VirtualFolders") sessions = _jellyfin("/Sessions") active = [] idle_count = 0 if isinstance(sessions, list): for s in sessions: if s.get("NowPlayingItem"): active.append({ "user": s.get("UserName", ""), "client": s.get("Client", ""), "device": s.get("DeviceName", ""), "now_playing": s["NowPlayingItem"].get("Name", ""), "type": s["NowPlayingItem"].get("Type", ""), }) else: idle_count += 1 return { "version": info.get("Version", "unknown"), "server_name": info.get("ServerName", "unknown"), "libraries": [{"name": lib.get("Name"), "type": lib.get("CollectionType", "")} for lib in libraries] if isinstance(libraries, list) else [], "active_sessions": active, "idle_sessions": idle_count, } @router.get("/sonarr/queue") async def sonarr_queue(): """Sonarr download queue.""" try: async with httpx.AsyncClient(timeout=10) as client: resp = await client.get( f"{SONARR_URL}/api/v3/queue", headers={"X-Api-Key": SONARR_KEY}, ) return resp.json() except Exception as e: return {"error": str(e)} @router.get("/radarr/queue") async def radarr_queue(): """Radarr download queue.""" try: async with httpx.AsyncClient(timeout=10) as client: resp = await client.get( f"{RADARR_URL}/api/v3/queue", headers={"X-Api-Key": RADARR_KEY}, ) return resp.json() except Exception as e: return {"error": str(e)} @router.get("/sabnzbd/queue") async def sabnzbd_queue(): """SABnzbd download queue.""" try: async with httpx.AsyncClient(timeout=10) as client: resp = await client.get( f"{SABNZBD_URL}/api", params={"apikey": SABNZBD_KEY, "output": "json", "mode": "queue"}, ) return resp.json() except Exception as e: return {"error": str(e)}