- type: custom-api title: Arr Calendar hide-header: true update-interval: 10m options: radarr-url: https://radarr.${BASE_HOST} radarr-key: ${RADARR_KEY} sonarr-url: https://sonarr.${BASE_HOST} sonarr-key: ${SONARR_KEY} lidarr-url: https://lidarr.${BASE_HOST} lidarr-key: ${LIDARR_KEY} exclude-physical: true past-days: 90 future-days: 90 template: | {{- /* === *arr Calendar Widget — self-contained === */}} {{- /* CSS is inlined below (works because Dynacat CSP allows style-src */}} {{- /* 'self' 'unsafe-inline'). JS lives in /assets/arr-calendar.js and */}} {{- /* must be wired once in dynacat.yml > document.head: */}} {{- /* */}} {{ $radarrUrl := .Options.StringOr "radarr-url" "" }} {{ $sonarrUrl := .Options.StringOr "sonarr-url" "" }} {{ $lidarrUrl := .Options.StringOr "lidarr-url" "" }} {{ $radarrKey := .Options.StringOr "radarr-key" "" }} {{ $sonarrKey := .Options.StringOr "sonarr-key" "" }} {{ $lidarrKey := .Options.StringOr "lidarr-key" "" }} {{ $excludePhysical := .Options.BoolOr "exclude-physical" false }} {{ $pastDays := .Options.IntOr "past-days" 90 }} {{ $futureDays := .Options.IntOr "future-days" 90 }} {{ $pastH := mul $pastDays 24 }} {{ $futureH := mul $futureDays 24 }} {{ $start := offsetNow (printf "-%dh" $pastH) | formatTime "2006-01-02T15:04:05" }} {{ $end := offsetNow (printf "+%dh" $futureH) | formatTime "2006-01-02T15:04:05" }} {{ $nowIso := now | formatTime "2006-01-02T15:04:05" }} {{- /* A service is "configured" if BOTH the URL and the API key are set. Unconfigured services are silently skipped — no request, no error. We declare $xxxData at the OUTER scope with an empty URL, which Glance's getResponse() handles by returning a zero-valued response with Response.StatusCode = 0 (see fetchCustomAPIResponse in widget-custom-api.go: empty URL short-circuits to a no-op). The outer-scope declaration is required because Go text/template variables declared with `:=` inside an if-block are scoped to that block — referencing them outside the block yields "undefined variable". The if-block then reassigns the outer variable with `=` when the service is enabled. */}} {{ $radarrEnabled := and (ne $radarrUrl "") (ne $radarrKey "") }} {{ $sonarrEnabled := and (ne $sonarrUrl "") (ne $sonarrKey "") }} {{ $lidarrEnabled := and (ne $lidarrUrl "") (ne $lidarrKey "") }} {{- $radarrData := newRequest "" | getResponse }} {{- $sonarrData := newRequest "" | getResponse }} {{- $lidarrData := newRequest "" | getResponse }} {{- if $radarrEnabled }} {{ $radarrReq := printf "%s/api/v3/calendar?start=%s&end=%s" $radarrUrl $start $end }} {{- $radarrData = newRequest $radarrReq | withHeader "Accept" "application/json" | withHeader "X-Api-Key" $radarrKey | getResponse }} {{- end }} {{- if $sonarrEnabled }} {{ $sonarrReq := printf "%s/api/v3/calendar?includeSeries=true&start=%s&end=%s" $sonarrUrl $start $end }} {{- $sonarrData = newRequest $sonarrReq | withHeader "Accept" "application/json" | withHeader "X-Api-Key" $sonarrKey | getResponse }} {{- end }} {{- if $lidarrEnabled }} {{ $lidarrReq := printf "%s/api/v1/calendar?start=%s&end=%s" $lidarrUrl $start $end }} {{- $lidarrData = newRequest $lidarrReq | withHeader "Accept" "application/json" | withHeader "X-Api-Key" $lidarrKey | getResponse }} {{- end }} {{ $anyConfigured := or $radarrEnabled $sonarrEnabled $lidarrEnabled }}
{{- /* Soft empty-state message when the user hasn't configured any service. We intentionally do NOT render the giant widget-error banner — partial availability (e.g. Sonarr-only) is success, not an error. */}} {{ if not $anyConfigured }}
Configure at least one of SONARR_KEY, RADARR_KEY, or LIDARR_KEY in the container environment to show releases.
{{ end }}