#!/usr/bin/env python3 """Python helpers for Kaizoku's Node provider bridge.""" import json import subprocess from pathlib import Path PROJECT_ROOT = Path(__file__).resolve().parent BRIDGE = PROJECT_ROOT / "providers" / "bridge.js" PROVIDERS = ("anikoto", "anineko", "pahe") def parse_provider_id(value, default_provider="anikoto"): text = str(value or "").strip() if ":" in text: provider, provider_id = text.split(":", 1) provider = provider.strip().lower() if provider in PROVIDERS: return provider, provider_id.strip() provider = str(default_provider or "anikoto").strip().lower() return provider if provider in PROVIDERS else "anikoto", text def bridge(command, provider, *args): normalized = str(provider or "anikoto").strip().lower() if normalized not in PROVIDERS: normalized = "anikoto" proc = subprocess.run( ["node", str(BRIDGE), command, normalized, *[str(arg) for arg in args]], cwd=PROJECT_ROOT, text=True, capture_output=True, check=False, ) if proc.returncode != 0: raise RuntimeError((proc.stderr or proc.stdout or f"Provider command {command} failed").strip()) try: return json.loads(proc.stdout or "{}") except json.JSONDecodeError as exc: raise RuntimeError(f"Provider bridge returned invalid JSON: {exc}") from exc def search(query, provider="anikoto", page=1): return bridge("search", provider, query, page) def info(show_id, provider="anikoto"): actual_provider, provider_id = parse_provider_id(show_id, provider) return bridge("info", actual_provider, provider_id) def episodes(show_id, provider="anikoto"): actual_provider, provider_id = parse_provider_id(show_id, provider) return bridge("episodes", actual_provider, provider_id).get("episodes") or []