Map Prowlarr releases to Arr indexers for manual grab

This commit is contained in:
2026-01-24 19:21:40 +13:00
parent 3d414b4aeb
commit 030480410b
4 changed files with 36 additions and 0 deletions

View File

@@ -21,6 +21,9 @@ class RadarrClient(ApiClient):
async def get_queue(self, movie_id: int) -> Optional[Dict[str, Any]]: async def get_queue(self, movie_id: int) -> Optional[Dict[str, Any]]:
return await self.get("/api/v3/queue", params={"movieId": movie_id}) return await self.get("/api/v3/queue", params={"movieId": movie_id})
async def get_indexers(self) -> Optional[Dict[str, Any]]:
return await self.get("/api/v3/indexer")
async def search(self, movie_id: int) -> Optional[Dict[str, Any]]: async def search(self, movie_id: int) -> Optional[Dict[str, Any]]:
return await self.post("/api/v3/command", payload={"name": "MoviesSearch", "movieIds": [movie_id]}) return await self.post("/api/v3/command", payload={"name": "MoviesSearch", "movieIds": [movie_id]})

View File

@@ -18,6 +18,9 @@ class SonarrClient(ApiClient):
async def get_queue(self, series_id: int) -> Optional[Dict[str, Any]]: async def get_queue(self, series_id: int) -> Optional[Dict[str, Any]]:
return await self.get("/api/v3/queue", params={"seriesId": series_id}) return await self.get("/api/v3/queue", params={"seriesId": series_id})
async def get_indexers(self) -> Optional[Dict[str, Any]]:
return await self.get("/api/v3/indexer")
async def get_episodes(self, series_id: int) -> Optional[Dict[str, Any]]: async def get_episodes(self, series_id: int) -> Optional[Dict[str, Any]]:
return await self.get("/api/v3/episode", params={"seriesId": series_id}) return await self.get("/api/v3/episode", params={"seriesId": series_id})

View File

@@ -1608,6 +1608,7 @@ async def action_grab(
guid = payload.get("guid") guid = payload.get("guid")
indexer_id = payload.get("indexerId") indexer_id = payload.get("indexerId")
download_url = payload.get("downloadUrl") download_url = payload.get("downloadUrl")
indexer_name = payload.get("indexerName") or payload.get("indexer")
if not guid or not indexer_id: if not guid or not indexer_id:
raise HTTPException(status_code=400, detail="Missing guid or indexerId") raise HTTPException(status_code=400, detail="Missing guid or indexerId")
@@ -1617,6 +1618,20 @@ async def action_grab(
if not client.configured(): if not client.configured():
raise HTTPException(status_code=400, detail="Sonarr not configured") raise HTTPException(status_code=400, detail="Sonarr not configured")
try: try:
if indexer_name:
indexers = await client.get_indexers()
if isinstance(indexers, list):
matched = next(
(
item
for item in indexers
if isinstance(item, dict)
and str(item.get("name", "")).lower() == str(indexer_name).lower()
),
None,
)
if matched and matched.get("id") is not None:
indexer_id = int(matched["id"])
response = await client.grab_release(str(guid), int(indexer_id)) response = await client.grab_release(str(guid), int(indexer_id))
except httpx.HTTPStatusError as exc: except httpx.HTTPStatusError as exc:
raise HTTPException(status_code=502, detail=f"Sonarr grab failed: {exc}") from exc raise HTTPException(status_code=502, detail=f"Sonarr grab failed: {exc}") from exc
@@ -1629,6 +1644,20 @@ async def action_grab(
if not client.configured(): if not client.configured():
raise HTTPException(status_code=400, detail="Radarr not configured") raise HTTPException(status_code=400, detail="Radarr not configured")
try: try:
if indexer_name:
indexers = await client.get_indexers()
if isinstance(indexers, list):
matched = next(
(
item
for item in indexers
if isinstance(item, dict)
and str(item.get("name", "")).lower() == str(indexer_name).lower()
),
None,
)
if matched and matched.get("id") is not None:
indexer_id = int(matched["id"])
response = await client.grab_release(str(guid), int(indexer_id)) response = await client.grab_release(str(guid), int(indexer_id))
except httpx.HTTPStatusError as exc: except httpx.HTTPStatusError as exc:
raise HTTPException(status_code=502, detail=f"Radarr grab failed: {exc}") from exc raise HTTPException(status_code=502, detail=f"Radarr grab failed: {exc}") from exc

View File

@@ -590,6 +590,7 @@ export default function RequestTimelinePage({ params }: { params: { id: string }
body: JSON.stringify({ body: JSON.stringify({
guid: release.guid, guid: release.guid,
indexerId: release.indexerId, indexerId: release.indexerId,
indexerName: release.indexer,
downloadUrl: release.downloadUrl, downloadUrl: release.downloadUrl,
}), }),
} }