The Pirate Phase 1.b: Lidarr + Whisparr + Overseerr tools
Adds 9 read-only tools across three new services: - Lidarr: queue, artist_search, library_stats (music library awareness) - Whisparr: queue, series_search, library_stats (adult content, v3 API) - Overseerr: search, requests, request_counts (cross-library availability, request tracking via X-Api-Key header reusing arr_get helper) Fix _common.py urlencode to use %20 instead of + for query values — Overseerr rejects + as reserved. Safe for all arr services. Pirate catalog: 11 → 20 tools.
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
"""Lidarr tools — music library queries (read-only)."""
|
||||
|
||||
from ._common import arr_get
|
||||
|
||||
|
||||
def _compact_artist(a):
|
||||
st = a.get("statistics", {}) or {}
|
||||
return {
|
||||
"id": a.get("id"),
|
||||
"name": a.get("artistName"),
|
||||
"status": a.get("status"),
|
||||
"monitored": a.get("monitored"),
|
||||
"genres": a.get("genres", []),
|
||||
"album_count": st.get("albumCount"),
|
||||
"tracks_on_disk": st.get("trackFileCount"),
|
||||
"tracks_total": st.get("totalTrackCount"),
|
||||
"size_on_disk_gb": round((st.get("sizeOnDisk", 0) or 0) / 1e9, 1),
|
||||
}
|
||||
|
||||
|
||||
def lidarr_queue(limit=20):
|
||||
"""Music albums/tracks currently downloading or pending import."""
|
||||
data = arr_get("lidarr", "/api/v1/queue", {
|
||||
"pageSize": limit,
|
||||
"includeArtist": "true",
|
||||
"includeAlbum": "true",
|
||||
})
|
||||
items = []
|
||||
for r in data.get("records", []):
|
||||
items.append({
|
||||
"title": r.get("title"),
|
||||
"artist": r.get("artist", {}).get("artistName") if r.get("artist") else None,
|
||||
"album": r.get("album", {}).get("title") if r.get("album") else None,
|
||||
"status": r.get("status"),
|
||||
"timeleft": r.get("timeleft"),
|
||||
"size_mb": round((r.get("size", 0) or 0) / 1e6, 1),
|
||||
"size_left_mb": round((r.get("sizeleft", 0) or 0) / 1e6, 1),
|
||||
"download_client": r.get("downloadClient"),
|
||||
})
|
||||
return {"total_records": data.get("totalRecords", 0), "items": items}
|
||||
|
||||
|
||||
def lidarr_artist_search(query):
|
||||
"""Look up an artist in the user's Lidarr library by partial name match.
|
||||
Does NOT search Prowlarr/indexers — only what's already tracked."""
|
||||
all_artists = arr_get("lidarr", "/api/v1/artist")
|
||||
q = query.lower().strip()
|
||||
hits = [a for a in all_artists if q in (a.get("artistName") or "").lower()]
|
||||
return {"query": query, "count": len(hits), "artists": [_compact_artist(a) for a in hits[:20]]}
|
||||
|
||||
|
||||
def lidarr_library_stats():
|
||||
"""Summary stats of the Lidarr music library."""
|
||||
all_artists = arr_get("lidarr", "/api/v1/artist")
|
||||
total_albums = total_tracks = total_on_disk = total_size = 0
|
||||
for a in all_artists:
|
||||
st = a.get("statistics", {}) or {}
|
||||
total_albums += st.get("albumCount", 0) or 0
|
||||
total_tracks += st.get("totalTrackCount", 0) or 0
|
||||
total_on_disk += st.get("trackFileCount", 0) or 0
|
||||
total_size += st.get("sizeOnDisk", 0) or 0
|
||||
return {
|
||||
"artist_count": len(all_artists),
|
||||
"album_count": total_albums,
|
||||
"tracks_total": total_tracks,
|
||||
"tracks_on_disk": total_on_disk,
|
||||
"total_size_gb": round(total_size / 1e9, 1),
|
||||
}
|
||||
|
||||
|
||||
TOOLS = [
|
||||
{
|
||||
"name": "lidarr_queue",
|
||||
"description": "List music albums/tracks Lidarr is currently downloading or importing. Use when the user asks 'what music is downloading', 'is the new album in yet'.",
|
||||
"input_schema": {
|
||||
"type": "object",
|
||||
"properties": {"limit": {"type": "integer", "description": "Max rows to return (default 20)", "default": 20}},
|
||||
},
|
||||
"read_only": True,
|
||||
"fn": lidarr_queue,
|
||||
},
|
||||
{
|
||||
"name": "lidarr_artist_search",
|
||||
"description": "Check whether an artist is in the user's Lidarr library by partial name match. Does NOT search for new artists to add.",
|
||||
"input_schema": {
|
||||
"type": "object",
|
||||
"properties": {"query": {"type": "string", "description": "Partial or full artist name"}},
|
||||
"required": ["query"],
|
||||
},
|
||||
"read_only": True,
|
||||
"fn": lidarr_artist_search,
|
||||
},
|
||||
{
|
||||
"name": "lidarr_library_stats",
|
||||
"description": "High-level stats about the Lidarr music library: artist count, album count, tracks on disk, total size.",
|
||||
"input_schema": {"type": "object", "properties": {}},
|
||||
"read_only": True,
|
||||
"fn": lidarr_library_stats,
|
||||
},
|
||||
]
|
||||
Reference in New Issue
Block a user