Update-Check im System-Tab, Worker-Adressfeld mit Heimnetz-Warnung, Save-Knopf raus aus dem Worker-Tab
Ampel / ampel (push) Successful in 28s

1. Update-Erkennung (Commander-Frage 'wie kriegen wir Updates mit?'):
   GET /system/updates vergleicht installierte Versionen (Worker-Info) mit
   makemkv.com (Versionsnummer der Download-Seite) und der HandBrake-
   GitHub-Release-API (releases/latest), 12 h gecacht. Einstellungen ->
   System: 'Auf Updates prüfen' + fertiger Update-Befehl bei MakeMKV.
   Selbst-Update gibt es bewusst NICHT (waere Docker-Socket-Zugriff);
   dafuer ist MAKEMKV_VERSION jetzt per .env uebersteuerbar — Update ohne
   Code-Aenderung. HandBrake-Abweichung wird als Info dargestellt
   (Debian-Paket hinkt der offiziellen Version bewusst hinterher).
2. Worker-Anbindung: editierbares Adressfeld statt stillschweigend
   window.location.hostname — Befund: ueber die externe Domain kopierte
   Befehle liefen in den Reverse-Proxy (401) und Worker koennen Redis/
   Postgres eh nur im Heimnetz erreichen. Amber-Warnung bei oeffentlich
   aussehender Adresse, Anleitung ergaenzt.
3. 'Einstellungen speichern' ist im Worker-Tab ausgeblendet — dort gibt
   es nichts zu speichern, der Knopf verwirrte nur.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Hitonabi
2026-07-24 15:39:20 +02:00
parent 76b4286ad3
commit 3987c31b1e
7 changed files with 198 additions and 5 deletions
+64
View File
@@ -935,6 +935,70 @@ async def browse_mkdir(request: MkdirRequest):
return {"path": ziel}
@app.get("/system/updates")
async def system_updates():
"""Update-Check für die Kern-Werkzeuge (Einstellungen → System).
Quellen: HandBrake über die GitHub-Release-API (releases/latest →
tag_name), MakeMKV über die offizielle Download-Seite (Versionsnummer
im Seitentext). Ergebnisse werden 12 h gecacht — der Check ist Komfort,
kein Dauerfeuer auf fremde Server. Ein Selbst-Update gibt es bewusst
NICHT: die Versionen stecken im Worker-Image, das Update ist ein
Image-Rebuild (Befehl wird im UI angezeigt).
"""
import re as _re
import requests as _requests
from cache import get as cache_get, set as _cache_set
def hole_neueste():
ergebnis = {"makemkv": None, "handbrake": None}
cached = cache_get("updates:neueste")
if cached:
return cached
try:
antwort = _requests.get(
"https://api.github.com/repos/HandBrake/HandBrake/releases/latest",
timeout=15, headers={"Accept": "application/vnd.github+json"},
)
if antwort.status_code == 200:
ergebnis["handbrake"] = (antwort.json().get("tag_name") or "").lstrip("v")
except Exception:
pass
try:
antwort = _requests.get("https://www.makemkv.com/download/", timeout=15)
treffer = _re.search(r"MakeMKV\s+(\d+\.\d+\.\d+)", antwort.text or "")
if treffer:
ergebnis["makemkv"] = treffer.group(1)
except Exception:
pass
if ergebnis["makemkv"] or ergebnis["handbrake"]:
_cache_set("updates:neueste", ergebnis, expire=12 * 3600)
return ergebnis
def sammle():
neueste = hole_neueste()
installiert = {"makemkv": None, "handbrake": None}
for worker in db.list_workers():
info = worker.get("info") or {}
installiert["makemkv"] = installiert["makemkv"] or info.get("makemkv")
installiert["handbrake"] = installiert["handbrake"] or info.get("handbrake")
return {
werkzeug: {
"installiert": installiert[werkzeug],
"verfuegbar": neueste[werkzeug],
"update": bool(
installiert[werkzeug] and neueste[werkzeug]
and installiert[werkzeug] != neueste[werkzeug]
),
}
for werkzeug in ("makemkv", "handbrake")
}
return await asyncio.to_thread(sammle)
@app.get("/worker-setup/windows")
async def worker_setup_windows():
"""Windows-Installer-Skript für den nativen Transcode-Worker.