from __future__ import annotations import json import xml.etree.ElementTree as ET from urllib.request import urlopen def library_releases(library: dict | None) -> list[dict]: releases = [] for show in ((library or {}).get("collections") or {}).get("series", []): for season in show.get("seasons", []): for episode in season.get("episodes", []): if episode.get("status") not in {"missing", "upcoming"}: continue releases.append({ "provider": "Library", "title": show.get("metadata", {}).get("title") or show.get("title"), "episode_title": episode.get("title"), "season": episode.get("season"), "episode": episode.get("episode"), "date": episode.get("air_date"), "type": "tv", "status": episode.get("status"), "poster": show.get("metadata", {}).get("poster"), "library_key": show.get("key"), }) return sorted(releases, key=lambda item: (item.get("date") or "9999-99-99", item.get("title") or "")) def fetch_releases(config: dict, library: dict | None = None) -> list[dict]: releases: list[dict] = library_releases(library) for provider in config.get("release_providers", []): if not provider.get("enabled", True): continue try: with urlopen(provider["url"], timeout=8) as response: body = response.read() if provider.get("type") == "json": data = json.loads(body.decode()) for item in data[:30] if isinstance(data, list) else []: show = item.get("show", item) releases.append({ "provider": provider["name"], "title": show.get("name"), "date": item.get("airdate") or item.get("premiered"), "type": "tv", }) else: root = ET.fromstring(body) for item in root.findall(".//item")[:30]: releases.append({ "provider": provider["name"], "title": (item.findtext("title") or "").strip(), "date": (item.findtext("pubDate") or "").strip(), "type": "movie", }) except Exception as exc: releases.append({"provider": provider.get("name"), "error": str(exc)}) return releases