"""Whisparr tools — adult library queries (read-only). Whisparr V2 uses a Sonarr-style series/episode model with `/api/v3/` paths. """ from ._common import arr_get def _compact_series(s): st = s.get("statistics", {}) or {} return { "id": s.get("id"), "title": s.get("title"), "year": s.get("year"), "status": s.get("status"), "monitored": s.get("monitored"), "episode_count": st.get("episodeCount"), "episode_file_count": st.get("episodeFileCount"), "size_on_disk_gb": round((st.get("sizeOnDisk", 0) or 0) / 1e9, 1), } def whisparr_queue(limit=20): """Adult content currently downloading or pending import.""" data = arr_get("whisparr", "/api/v3/queue", {"pageSize": limit, "includeSeries": "true"}) items = [] for r in data.get("records", []): items.append({ "title": r.get("title"), "series": r.get("series", {}).get("title") if r.get("series") else None, "status": r.get("status"), "timeleft": r.get("timeleft"), "size_gb": round((r.get("size", 0) or 0) / 1e9, 2), "size_left_gb": round((r.get("sizeleft", 0) or 0) / 1e9, 2), "download_client": r.get("downloadClient"), }) return {"total_records": data.get("totalRecords", 0), "items": items} def whisparr_series_search(query): """Look up a title in the user's Whisparr library by partial match. Does NOT search indexers — only what's already tracked.""" all_series = arr_get("whisparr", "/api/v3/series") q = query.lower().strip() hits = [s for s in all_series if q in (s.get("title") or "").lower()] return {"query": query, "count": len(hits), "series": [_compact_series(s) for s in hits[:20]]} def whisparr_library_stats(): """Summary stats of the Whisparr adult library.""" all_series = arr_get("whisparr", "/api/v3/series") total_eps = total_on_disk = total_size = 0 for s in all_series: st = s.get("statistics", {}) or {} total_eps += st.get("episodeCount", 0) or 0 total_on_disk += st.get("episodeFileCount", 0) or 0 total_size += st.get("sizeOnDisk", 0) or 0 return { "series_count": len(all_series), "episode_total": total_eps, "episodes_on_disk": total_on_disk, "total_size_gb": round(total_size / 1e9, 1), } TOOLS = [ { "name": "whisparr_queue", "description": "List adult content Whisparr is currently downloading or importing.", "input_schema": { "type": "object", "properties": {"limit": {"type": "integer", "default": 20}}, }, "read_only": True, "fn": whisparr_queue, }, { "name": "whisparr_series_search", "description": "Search the user's Whisparr library by partial title match. Does NOT search indexers.", "input_schema": { "type": "object", "properties": {"query": {"type": "string"}}, "required": ["query"], }, "read_only": True, "fn": whisparr_series_search, }, { "name": "whisparr_library_stats", "description": "High-level stats about the Whisparr adult library: title count, episodes on disk, total size.", "input_schema": {"type": "object", "properties": {}}, "read_only": True, "fn": whisparr_library_stats, }, ]