mirror of
https://github.com/myronblair/kino-app
synced 2026-07-31 13:02:29 -05:00
b28a49e8fa
- Requests approval now shows a Radarr/Sonarr candidate picker instead of grabbing the first search result (fixes wrong-title/wrong-year matches) - approve_request reuses an existing Radarr/Sonarr entry instead of erroring when content is already in the library - New codec-check queue (step 1) probes source codecs and skips transcoding entirely for already browser-native files; only non-native content reaches the transcode queue (step 2) - Fixes ffmpeg hard-failing on non-H.264 sources via the h264_mp4toannexb bitstream filter (root cause of the fix-audio-all failures) - Added Codec Check Worker / Transcode Worker to the services health panel with restart - Reorganized the admin page into Pipeline/Utilities dropdowns; added the missing Sonarr Import link - Bumped VERSION 1.0.0 -> 1.1.0
62 lines
2.1 KiB
Python
62 lines
2.1 KiB
Python
"""Docker service status/restart for the internal StreamHoard stack."""
|
|
import docker
|
|
|
|
SERVICES = [
|
|
{"key": "gluetun", "label": "VPN (gluetun)", "container": "streamhoard-gluetun"},
|
|
{"key": "sonarr", "label": "Sonarr", "container": "streamhoard-sonarr"},
|
|
{"key": "radarr", "label": "Radarr", "container": "streamhoard-radarr"},
|
|
{"key": "prowlarr", "label": "Prowlarr", "container": "streamhoard-prowlarr"},
|
|
{"key": "qbittorrent", "label": "qBittorrent", "container": "streamhoard-qbittorrent"},
|
|
{"key": "mongo", "label": "Database", "container": "streamhoard-mongo"},
|
|
{"key": "portainer", "label": "Portainer", "container": "streamhoard-portainer"},
|
|
]
|
|
|
|
_client = None
|
|
|
|
|
|
def _get_client():
|
|
global _client
|
|
if _client is None:
|
|
_client = docker.DockerClient(base_url="unix:///var/run/docker.sock")
|
|
return _client
|
|
|
|
|
|
def list_service_status():
|
|
client = _get_client()
|
|
out = []
|
|
for svc in SERVICES:
|
|
try:
|
|
c = client.containers.get(svc["container"])
|
|
running = c.status == "running"
|
|
except docker.errors.NotFound:
|
|
running = False
|
|
except Exception:
|
|
running = False
|
|
out.append({"key": svc["key"], "label": svc["label"], "running": running})
|
|
return out
|
|
|
|
|
|
def restart_service(key: str) -> bool:
|
|
svc = next((s for s in SERVICES if s["key"] == key), None)
|
|
if not svc:
|
|
return False
|
|
client = _get_client()
|
|
c = client.containers.get(svc["container"])
|
|
c.restart(timeout=15)
|
|
return True
|
|
|
|
|
|
# The codec-check and transcode workers are asyncio background tasks inside the backend
|
|
# process itself, not separate containers — there's no way to bounce just one of them, so
|
|
# "restart" for either really means restarting the whole streamhoard-backend container. That
|
|
# briefly takes the API down too, not just the stalled queue; the caller (server.py) surfaces
|
|
# both worker "services" as needing this same restart target.
|
|
BACKEND_CONTAINER = "streamhoard-backend"
|
|
|
|
|
|
def restart_backend() -> bool:
|
|
client = _get_client()
|
|
c = client.containers.get(BACKEND_CONTAINER)
|
|
c.restart(timeout=15)
|
|
return True
|