multiuser/subscriptions/notifications
This commit is contained in:
@@ -25,7 +25,7 @@ def _get(url, headers, params=None, timeout=5):
|
||||
def _abs_url(base: str, p: str | None) -> str | None:
|
||||
if not p:
|
||||
return None
|
||||
return f"{base.rstrip('/')}{p}" if p.startswith("/") else p
|
||||
return f"{base.rstrip('/')}" + p if p.startswith("/") else p
|
||||
|
||||
def sonarr_calendar(days: int | None = None, base_url: str | None = None, api_key: str | None = None):
|
||||
base = (base_url or ENV_SONARR_URL).strip()
|
||||
@@ -131,3 +131,62 @@ def radarr_calendar(days: int | None = None, base_url: str | None = None, api_ke
|
||||
return False
|
||||
|
||||
return [m for m in out if is_upcoming(m)]
|
||||
|
||||
def sonarr_get_series(series_id: int, base_url: str | None = None, api_key: str | None = None) -> dict | None:
|
||||
"""Fetch a single series by id from Sonarr, return dict with title, overview, poster and genres."""
|
||||
base = (base_url or ENV_SONARR_URL).strip()
|
||||
key = (api_key or ENV_SONARR_KEY).strip()
|
||||
if not base or not key:
|
||||
return None
|
||||
url = f"{base.rstrip('/')}/api/v3/series/{series_id}"
|
||||
headers = {"X-Api-Key": key}
|
||||
data = _get(url, headers)
|
||||
# Poster
|
||||
poster = None
|
||||
for img in (data.get("images") or []):
|
||||
if (img.get("coverType") or "").lower() == "poster":
|
||||
poster = img.get("remoteUrl") or _abs_url(base, img.get("url"))
|
||||
if poster:
|
||||
break
|
||||
return {
|
||||
"series_id": data.get("id"),
|
||||
"series_title": data.get("title"),
|
||||
"series_overview": data.get("overview") or "",
|
||||
"series_genres": data.get("genres") or [],
|
||||
"series_poster": poster,
|
||||
}
|
||||
|
||||
def radarr_lookup_movie_by_title(title: str, base_url: str | None = None, api_key: str | None = None) -> dict | None:
|
||||
"""Lookup a movie by title via Radarr /api/v3/movie/lookup. Returns title, poster, overview, genres, year, tmdbId, and id if present."""
|
||||
base = (base_url or ENV_RADARR_URL).strip()
|
||||
key = (api_key or ENV_RADARR_KEY).strip()
|
||||
if not base or not key or not title:
|
||||
return None
|
||||
url = f"{base.rstrip('/')}/api/v3/movie/lookup"
|
||||
headers = {"X-Api-Key": key}
|
||||
data = _get(url, headers, params={"term": title})
|
||||
if not data:
|
||||
return None
|
||||
# naive pick: exact match by title (case-insensitive), else first
|
||||
best = None
|
||||
for it in data:
|
||||
if (it.get("title") or "").lower() == title.lower():
|
||||
best = it
|
||||
break
|
||||
if not best:
|
||||
best = data[0]
|
||||
poster = None
|
||||
for img in (best.get("images") or []):
|
||||
if (img.get("coverType") or "").lower() == "poster":
|
||||
poster = img.get("remoteUrl") or _abs_url(base, img.get("url"))
|
||||
if poster:
|
||||
break
|
||||
return {
|
||||
"movie_id": best.get("id") or 0,
|
||||
"title": best.get("title") or title,
|
||||
"poster": poster,
|
||||
"overview": best.get("overview") or "",
|
||||
"genres": best.get("genres") or [],
|
||||
"year": best.get("year"),
|
||||
"tmdbId": best.get("tmdbId"),
|
||||
}
|
||||
|
Reference in New Issue
Block a user