4K: download clients (packaged, idempotent) + Homepage tiles
Add SABnzbd+Transmission to radarr-4k/sonarr-4k with distinct categories (sabnzbd movies-4k/tv-4k, transmission radarr-uhd/sonarr-uhd; Transmission forbids digits) so they dont cross-import the 1080p instances. Packaged into deploy-arrs-4k.yml via an idempotent ensure-arrs-4k-dl.py (changed=0). Homepage Radarr 4K/Sonarr 4K tiles (HOMEPAGE_VAR keys, siteMonitor). 4K path proven: Obsession routed to radarr-4k, grabbed WEBDL-2160p, 1080p rejected 'not wanted in profile'. Keys via vault, no secrets. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -21,6 +21,11 @@ idempotent, changed=0).
|
|||||||
1080p radarr was mislabeled `is4k=true` and was flipped to `is4k=false` (non-4k default).
|
1080p radarr was mislabeled `is4k=true` and was flipped to `is4k=false` (non-4k default).
|
||||||
- **Plex**: SEPARATE libraries `Movies - 4K` (/data/media/movies-4k) + `TV - 4K` (/data/media/tv-4k),
|
- **Plex**: SEPARATE libraries `Movies - 4K` (/data/media/movies-4k) + `TV - 4K` (/data/media/tv-4k),
|
||||||
not merged into the 1080p libraries.
|
not merged into the 1080p libraries.
|
||||||
|
- **Download clients** (added post-Step-1, packaged in the playbook via `ensure-arrs-4k-dl.py`):
|
||||||
|
SABnzbd + Transmission on both instances, DISTINCT categories to avoid cross-import with 1080p —
|
||||||
|
sabnzbd `movies-4k`/`tv-4k`, transmission `radarr-uhd`/`sonarr-uhd` (Transmission category forbids digits).
|
||||||
|
Completed paths under /data (hardlinks intact).
|
||||||
|
- **Homepage**: separate `Radarr 4K`/`Sonarr 4K` tiles in Media Automation (keys via HOMEPAGE_VAR, siteMonitor).
|
||||||
- **Traefik**: file-provider routers (see traefik-router snippet), NOT docker labels.
|
- **Traefik**: file-provider routers (see traefik-router snippet), NOT docker labels.
|
||||||
- **Tdarr**: does NOT watch movies-4k/tv-4k (its libraries are the specific 1080p /media/movies,
|
- **Tdarr**: does NOT watch movies-4k/tv-4k (its libraries are the specific 1080p /media/movies,
|
||||||
/media/tv) — quality-first keeps the grabbed file.
|
/media/tv) — quality-first keeps the grabbed file.
|
||||||
|
|||||||
@@ -84,3 +84,76 @@
|
|||||||
- name: Result
|
- name: Result
|
||||||
ansible.builtin.debug:
|
ansible.builtin.debug:
|
||||||
msg: "arrs-4k {{ 'running (changed)' if r.changed else 'already up (no-op)' }}"
|
msg: "arrs-4k {{ 'running (changed)' if r.changed else 'already up (no-op)' }}"
|
||||||
|
|
||||||
|
- name: Wait for 4K arr APIs (ports)
|
||||||
|
ansible.builtin.wait_for:
|
||||||
|
host: 192.168.99.183
|
||||||
|
port: "{{ item }}"
|
||||||
|
timeout: 90
|
||||||
|
loop: [7879, 8990]
|
||||||
|
|
||||||
|
- name: Install 4K download-client config script
|
||||||
|
ansible.builtin.copy:
|
||||||
|
dest: "{{ app_dir }}/ensure-arrs-4k-dl.py"
|
||||||
|
owner: tommy
|
||||||
|
group: tommy
|
||||||
|
mode: "0755"
|
||||||
|
content: |
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# Idempotent: ensure the 4K arr download clients + sabnzbd categories exist.
|
||||||
|
# Reads RADARR4K_KEY / SONARR4K_KEY / SAB_KEY from env. Prints CHANGED or NOCHANGE.
|
||||||
|
import os, json, urllib.request
|
||||||
|
H = "http://192.168.99.183"
|
||||||
|
SAB = os.environ["SAB_KEY"]
|
||||||
|
changed = False
|
||||||
|
|
||||||
|
def sab_cats():
|
||||||
|
return json.load(urllib.request.urlopen(f"{H}:8081/api?mode=get_cats&output=json&apikey={SAB}"))["categories"]
|
||||||
|
def sab_add(cat):
|
||||||
|
urllib.request.urlopen(f"{H}:8081/api?mode=set_config§ion=categories&keyword={cat}&dir={cat}&apikey={SAB}").read()
|
||||||
|
def dc_get(port, key):
|
||||||
|
return json.load(urllib.request.urlopen(urllib.request.Request(f"{H}:{port}/api/v3/downloadclient", headers={"X-Api-Key": key})))
|
||||||
|
def dc_post(port, key, body):
|
||||||
|
urllib.request.urlopen(urllib.request.Request(f"{H}:{port}/api/v3/downloadclient",
|
||||||
|
data=json.dumps(body).encode(), method="POST", headers={"X-Api-Key": key, "Content-Type": "application/json"}))
|
||||||
|
|
||||||
|
def sab_body(catf, catv, recent, older):
|
||||||
|
return {"enable": True, "protocol": "usenet", "priority": 1, "name": "SABnzbd",
|
||||||
|
"implementation": "Sabnzbd", "configContract": "SabnzbdSettings",
|
||||||
|
"fields": [{"name": "host", "value": "gluetun"}, {"name": "port", "value": 8080},
|
||||||
|
{"name": "apiKey", "value": SAB}, {"name": catf, "value": catv},
|
||||||
|
{"name": recent, "value": -100}, {"name": older, "value": -100}]}
|
||||||
|
def tr_body(catf, catv):
|
||||||
|
return {"enable": True, "protocol": "torrent", "priority": 1, "name": "Transmission",
|
||||||
|
"implementation": "Transmission", "configContract": "TransmissionSettings",
|
||||||
|
"fields": [{"name": "host", "value": "gluetun"}, {"name": "port", "value": 9091},
|
||||||
|
{"name": "urlBase", "value": "/transmission/"}, {"name": catf, "value": catv}]}
|
||||||
|
|
||||||
|
cats = sab_cats()
|
||||||
|
for c in ("movies-4k", "tv-4k"):
|
||||||
|
if c not in cats:
|
||||||
|
sab_add(c); changed = True
|
||||||
|
|
||||||
|
plan = [
|
||||||
|
(7879, os.environ["RADARR4K_KEY"], [sab_body("movieCategory", "movies-4k", "recentMoviePriority", "olderMoviePriority"),
|
||||||
|
tr_body("movieCategory", "radarr-uhd")]),
|
||||||
|
(8990, os.environ["SONARR4K_KEY"], [sab_body("tvCategory", "tv-4k", "recentTvPriority", "olderTvPriority"),
|
||||||
|
tr_body("tvCategory", "sonarr-uhd")]),
|
||||||
|
]
|
||||||
|
for port, key, bodies in plan:
|
||||||
|
have = {c["name"] for c in dc_get(port, key)}
|
||||||
|
for b in bodies:
|
||||||
|
if b["name"] not in have:
|
||||||
|
dc_post(port, key, b); changed = True
|
||||||
|
|
||||||
|
print("CHANGED" if changed else "NOCHANGE")
|
||||||
|
|
||||||
|
- name: Ensure 4K download clients + sabnzbd categories (idempotent, cats movies-4k/tv-4k)
|
||||||
|
ansible.builtin.command: "python3 {{ app_dir }}/ensure-arrs-4k-dl.py"
|
||||||
|
environment:
|
||||||
|
RADARR4K_KEY: "{{ vault_radarr4k_apikey }}"
|
||||||
|
SONARR4K_KEY: "{{ vault_sonarr4k_apikey }}"
|
||||||
|
SAB_KEY: "{{ vault_sabnzbd_apikey }}"
|
||||||
|
register: dl_result
|
||||||
|
changed_when: "'CHANGED' in dl_result.stdout"
|
||||||
|
no_log: true
|
||||||
|
|||||||
@@ -55,6 +55,25 @@
|
|||||||
type: radarr
|
type: radarr
|
||||||
url: http://radarr:7878
|
url: http://radarr:7878
|
||||||
key: {{HOMEPAGE_VAR_RADARR_KEY}}
|
key: {{HOMEPAGE_VAR_RADARR_KEY}}
|
||||||
|
- Radarr 4K:
|
||||||
|
icon: radarr.png
|
||||||
|
href: https://radarr-4k.goattw.net
|
||||||
|
description: 4K Movies (quality-first)
|
||||||
|
siteMonitor: https://radarr-4k.goattw.net
|
||||||
|
widget:
|
||||||
|
type: radarr
|
||||||
|
url: http://radarr-4k:7878
|
||||||
|
key: {{HOMEPAGE_VAR_RADARR4K_KEY}}
|
||||||
|
|
||||||
|
- Sonarr 4K:
|
||||||
|
icon: sonarr.png
|
||||||
|
href: https://sonarr-4k.goattw.net
|
||||||
|
description: 4K TV (quality-first)
|
||||||
|
siteMonitor: https://sonarr-4k.goattw.net
|
||||||
|
widget:
|
||||||
|
type: sonarr
|
||||||
|
url: http://sonarr-4k:8989
|
||||||
|
key: {{HOMEPAGE_VAR_SONARR4K_KEY}}
|
||||||
|
|
||||||
- Prowlarr:
|
- Prowlarr:
|
||||||
icon: prowlarr.png
|
icon: prowlarr.png
|
||||||
|
|||||||
Reference in New Issue
Block a user