"""Encoder-Fähigkeiten dieses Workers — ehrlich erkannt, nicht behauptet. Jeder Worker meldet beim Start, was auf SEINER Maschine wirklich verfügbar ist (Commander-Anforderung 23.07.: das UI zeigt an, WAS da ist). Ein Remote-GPU-Worker meldet sich hier genauso wie der eingebaute CPU-Worker. """ import os import re import shutil import subprocess def erkenne_encoder() -> list: """Liste der verfügbaren Encoder-Backends auf dieser Maschine.""" gefunden = ["cpu-x264", "cpu-x265"] # HandBrake-Software-Encoder, immer dabei # VAAPI: AMD (VCN) und Intel (QuickSync) melden sich über /dev/dri if os.path.exists("/dev/dri/renderD128"): gefunden.append("vaapi") # NVENC: NVIDIA-Treiber im Container sichtbar if shutil.which("nvidia-smi") or os.path.exists("/usr/lib/x86_64-linux-gnu/libnvidia-encode.so.1"): gefunden.append("nvenc") return gefunden def erkenne_ip() -> str: """Beste erratbare eigene IP (UDP-Route-Trick, KEIN echter Traffic). Ehrlicher Vorbehalt: im Docker-Bridge-Netz ist das die Container-IP — für die Maschinen-Zuordnung ist deshalb WORKER_NAME (Anzeigename in compose/.env) die verlässliche Größe; die IP ist Zusatz-Indiz. """ import socket try: s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) try: s.connect(("192.0.2.1", 9)) # TEST-NET — nur Routing, kein Paket nötig return s.getsockname()[0] finally: s.close() except OSError: return "" def werkzeug_versionen() -> dict: """Kern-Werkzeuge dieses Workers — fürs UI (Einstellungen → System). MakeMKV-Version kommt aus dem Build (ENV MAKEMKV_VERSION im Dockerfile) — makemkvcon hat keinen dokumentierten --version-Schalter (usage.txt). HandBrakeCLI --version ist dokumentiert (handbrake.fr/docs, CLI Options) und gibt z.B. "HandBrake 1.6.1" aus. """ import socket info = { # Zuordnung im UI: hostname (für den Celery-Online-Abgleich) + IP "hostname": socket.gethostname(), "ip": erkenne_ip(), } if shutil.which("makemkvcon"): info["makemkv"] = os.getenv("MAKEMKV_VERSION") or "installiert" if shutil.which("HandBrakeCLI"): try: aus = subprocess.run( ["HandBrakeCLI", "--version"], capture_output=True, text=True, timeout=15, ) treffer = re.search(r"HandBrake\s+([\w.]+)", (aus.stdout or "") + (aus.stderr or "")) info["handbrake"] = treffer.group(1) if treffer else "installiert" except (OSError, subprocess.TimeoutExpired): info["handbrake"] = "installiert" # Woher kommt der MakeMKV-Key? UI-Setting schlägt Env — ehrlich anzeigen. try: import db ui_key = (db.get_settings().get("makemkvAppKey") or "").strip() except Exception: ui_key = "" if ui_key: info["makemkv_key"] = "ui" elif os.getenv("MAKEMKV_APP_KEY"): info["makemkv_key"] = "env" else: info["makemkv_key"] = "keiner" return info