Name the show on Sonarr and Plex episode cards

This commit is contained in:
Archibold committed 2026-11-07 19:01:36 +11:00
1 parent 71d5c68550
commit 102683363f
2 files changed
+29 -7

No files matched your search

+5
View File
@@ -257,6 +257,11 @@ in three kinds:
- Artwork (Radarr posters, Plex thumbs) is relayed through
`/api/widgets/{id}/image?u=...` - the browser cannot reach the internal host,
and the relay only ever fetches from that widget's own origin.
- Calendar cards always name the show, not just the episode: Sonarr's calendar
items carry only `seriesId` plus an episode `title`, so the request asks for
`includeSeries=true` and reads the name off the nested `series` object (Radarr
ignores that parameter). Plex episodes take the show from `grandparentTitle`
(`parentTitle` is the season), skipped when it repeats the episode title.
- `severity` is notice-only: `urgent`/`heads-up`/`info` tints the card edge, the
chip, and the icon on Home. Setting it on a live widget is a validation error
(live rows have no severity to sort by).
+24 -7
View File
@@ -201,7 +201,13 @@ class WidgetData:
return {}
today = datetime.now()
end = today + timedelta(days=widget.days)
return {"start": today.strftime("%Y-%m-%d"), "end": end.strftime("%Y-%m-%d")}
# Sonarr's calendar items carry only seriesId unless asked for the series
# object; Radarr ignores this unknown parameter.
return {
"start": today.strftime("%Y-%m-%d"),
"end": end.strftime("%Y-%m-%d"),
"includeSeries": "true",
}
def _headers(self, widget: Widget) -> Dict[str, str]:
headers = dict(widget.headers)
@@ -252,15 +258,21 @@ class WidgetData:
if not date:
continue
season, episode = item.get("seasonNumber"), item.get("episodeNumber")
# `title` is the episode title; the show name only arrives with
# ?includeSeries=true as a nested `series` object (SeriesResource
# calls it `title`). Older/other shapes use `seriesTitle` directly.
series = item.get("series") or {}
show = str(item.get("seriesTitle") or series.get("title") or "")
episode_title = str(item.get("episodeTitle") or item.get("title") or "")
bits = []
if season is not None and episode is not None:
bits.append(f"S{season} E{episode}")
if item.get("episodeTitle"):
bits.append(str(item["episodeTitle"]))
if episode_title and show:
bits.append(episode_title)
rows.append(
{
"date": date,
"label": str(item.get("seriesTitle") or item.get("title") or "?"),
"label": show or episode_title or "?",
"sub": " · ".join(bits),
"type": "episode",
"source": widget.name,
@@ -307,9 +319,14 @@ class WidgetData:
bits.append(str(item["type"]))
if item.get("year"):
bits.append(str(item["year"]))
if item.get("parentTitle"):
index = f"{item.get('parentIndex', '')}x{item.get('index', '')}"
bits.append(f"{item['parentTitle']} {index}")
# Plex nests the show under grandparentTitle for episodes (parentTitle
# is the season); recordings only carry parentTitle.
show = item.get("grandparentTitle") or item.get("parentTitle")
if show and show != item.get("title"):
if item.get("index") is not None:
bits.append(f"{show} {item.get('parentIndex', '')}x{item['index']}")
else:
bits.append(str(show))
rows.append(
{
"date": date,