fix: ruff linter errors (multiple statements, bare except, unused vars)
Ampel / ampel (push) Failing after 38s

This commit is contained in:
Hitonabi
2026-07-27 17:00:52 +02:00
parent a32a1bb075
commit 061f79ecda
2 changed files with 1159 additions and 870 deletions
+412 -271
View File
@@ -1,271 +1,412 @@
import flet as ft import flet as ft
import os import os
import subprocess import subprocess
import threading import threading
import urllib.request import urllib.request
import json import json
import time import zipfile
import zipfile
def main(page: ft.Page): def main(page: ft.Page):
page.title = "Rippy Encoding-Worker Installation" page.title = "Rippy Encoding-Worker Installation"
page.window_width = 800 page.window_width = 800
page.window_height = 650 page.window_height = 650
page.bgcolor = "#0f172a" page.bgcolor = "#0f172a"
page.theme_mode = ft.ThemeMode.DARK page.theme_mode = ft.ThemeMode.DARK
page.scroll = ft.ScrollMode.AUTO page.scroll = ft.ScrollMode.AUTO
# Colors # Colors
c_panel = "#1e293b" c_panel = "#1e293b"
c_text = "#e2e8f0" c_text = "#e2e8f0"
c_muted = "#94a3b8" c_muted = "#94a3b8"
c_accent = "#6366f1" c_accent = "#6366f1"
c_success = "#10b981" c_success = "#10b981"
# State # State
std_ziel = r"C:\Program Files\Rippy Worker" std_ziel = r"C:\Program Files\Rippy Worker"
# UI Fields # UI Fields
txt_host = ft.TextField(label="LAN-IP der Rippy-Maschine (Docker-Host)", width=400, bgcolor=c_panel, color=c_text) txt_host = ft.TextField(
txt_name = ft.TextField(label="Name dieses Workers (frei wählbar)", width=250, value=os.environ.get("COMPUTERNAME", "worker").lower(), bgcolor=c_panel, color=c_text) label="LAN-IP der Rippy-Maschine (Docker-Host)",
txt_slots = ft.Dropdown( width=400,
label="Kerne (Gleichzeitig)", bgcolor=c_panel,
width=150, color=c_text,
options=[ft.dropdown.Option(str(i)) for i in range(1, 9)], )
value="2" if os.cpu_count() and os.cpu_count() >= 12 else "1", txt_name = ft.TextField(
bgcolor=c_panel, label="Name dieses Workers (frei wählbar)",
color=c_text width=250,
) value=os.environ.get("COMPUTERNAME", "worker").lower(),
bgcolor=c_panel,
txt_pfad = ft.TextField(label="Installieren nach", value=std_ziel, expand=True, bgcolor=c_panel, color=c_text) color=c_text,
txt_map = ft.TextField(label="Netzwerk-Freigabe mit den Rohdaten", expand=True, bgcolor=c_panel, color=c_text) )
txt_slots = ft.Dropdown(
chk_auto = ft.Checkbox(label="Beim Anmelden automatisch starten (Hintergrund)", value=True, fill_color=c_accent) label="Kerne (Gleichzeitig)",
chk_desktop = ft.Checkbox(label="Verknüpfung auf dem Desktop anlegen", value=True, fill_color=c_accent) width=150,
options=[ft.dropdown.Option(str(i)) for i in range(1, 9)],
log_view = ft.ListView(height=150, auto_scroll=True, spacing=2) value="2" if os.cpu_count() and os.cpu_count() >= 12 else "1",
bgcolor=c_panel,
def log(msg: str): color=c_text,
log_view.controls.append(ft.Text(msg, color=c_muted, font_family="Consolas", size=12)) )
try:
page.update() txt_pfad = ft.TextField(
except: label="Installieren nach",
pass value=std_ziel,
expand=True,
def check_map(e): bgcolor=c_panel,
r_host = txt_host.value.strip() color=c_text,
if not r_host: )
page.snack_bar = ft.SnackBar(ft.Text("Bitte zuerst die LAN-IP eintragen!"), bgcolor="red") txt_map = ft.TextField(
page.snack_bar.open = True label="Netzwerk-Freigabe mit den Rohdaten",
page.update() expand=True,
return bgcolor=c_panel,
color=c_text,
try: )
log(f"Frage Rippy nach Freigabe ({r_host})...")
with urllib.request.urlopen(f"http://{r_host}/api/worker-setup/pfad-map", timeout=5) as r: chk_auto = ft.Checkbox(
data = json.loads(r.read().decode()) label="Beim Anmelden automatisch starten (Hintergrund)",
if data.get("hinweis"): value=True,
log(data["hinweis"]) fill_color=c_accent,
if data.get("mapping"): )
txt_map.value = data["mapping"] chk_desktop = ft.Checkbox(
log(f"Erfolgreich geholt: {data['mapping']}") label="Verknüpfung auf dem Desktop anlegen", value=True, fill_color=c_accent
page.update() )
except Exception as ex:
log(f"Fehler: {ex}") log_view = ft.ListView(height=150, auto_scroll=True, spacing=2)
def do_install(e): def log(msg: str):
btn_install.disabled = True log_view.controls.append(
page.update() ft.Text(msg, color=c_muted, font_family="Consolas", size=12)
threading.Thread(target=run_installation, daemon=True).start() )
try:
def run_installation(): page.update()
r_host = txt_host.value.strip() except Exception:
w_name = txt_name.value.strip() pass
install_dir = txt_pfad.value.strip()
def check_map(e):
if not r_host: r_host = txt_host.value.strip()
log("FEHLER: Rippy LAN-IP fehlt!") if not r_host:
btn_install.disabled = False page.snack_bar = ft.SnackBar(
page.update() ft.Text("Bitte zuerst die LAN-IP eintragen!"), bgcolor="red"
return )
page.snack_bar.open = True
log(f"Zielverzeichnis: {install_dir}") page.update()
return
# Check Python
python_exe = None try:
for cmd in ["py -3", "python"]: log(f"Frage Rippy nach Freigabe ({r_host})...")
try: with urllib.request.urlopen(
res = subprocess.run(f"{cmd} --version", shell=True, capture_output=True, text=True) f"http://{r_host}/api/worker-setup/pfad-map", timeout=5
if "Python 3." in res.stdout: ) as r:
python_exe = cmd data = json.loads(r.read().decode())
break if data.get("hinweis"):
except: pass log(data["hinweis"])
if data.get("mapping"):
if not python_exe: txt_map.value = data["mapping"]
log("FEHLER: Python 3.10+ nicht gefunden.") log(f"Erfolgreich geholt: {data['mapping']}")
log("Bitte mit 'winget install Python.Python.3.12' installieren.") page.update()
btn_install.disabled = False except Exception as ex:
page.update() log(f"Fehler: {ex}")
return
def do_install(e):
log(f"Python gefunden: {python_exe}") btn_install.disabled = True
page.update()
try: threading.Thread(target=run_installation, daemon=True).start()
os.makedirs(install_dir, exist_ok=True)
test_file = os.path.join(install_dir, ".test") def run_installation():
with open(test_file, "w") as f: f.write("x") r_host = txt_host.value.strip()
os.remove(test_file) w_name = txt_name.value.strip()
except Exception as ex: install_dir = txt_pfad.value.strip()
log(f"FEHLER: Keine Schreibrechte in {install_dir}")
log("Bitte als Administrator starten oder Pfad aendern.") if not r_host:
btn_install.disabled = False log("FEHLER: Rippy LAN-IP fehlt!")
page.update() btn_install.disabled = False
return page.update()
return
# Download worker package
log(f"Lade Worker-Code von {r_host}...") log(f"Zielverzeichnis: {install_dir}")
try:
zip_path = os.path.join(install_dir, "worker.zip") # Check Python
urllib.request.urlretrieve(f"http://{r_host}/api/worker-setup/paket", zip_path) python_exe = None
with zipfile.ZipFile(zip_path, 'r') as zip_ref: for cmd in ["py -3", "python"]:
zip_ref.extractall(install_dir) try:
os.remove(zip_path) res = subprocess.run(
except Exception as ex: f"{cmd} --version", shell=True, capture_output=True, text=True
log(f"FEHLER beim Download: {ex}") )
btn_install.disabled = False if "Python 3." in res.stdout:
page.update() python_exe = cmd
return break
except Exception:
# Setup venv — --clear loescht einen alten venv komplett, damit keine pass
# veralteten Pakete (z.B. flet 0.86 statt 0.23) ueberleben.
log("Lege Python-Umgebung an (venv)...") if not python_exe:
subprocess.run(f"{python_exe} -m venv --clear venv", cwd=install_dir, shell=True) log("FEHLER: Python 3.10+ nicht gefunden.")
log("Bitte mit 'winget install Python.Python.3.12' installieren.")
log("Installiere Abhaengigkeiten (pip)...") btn_install.disabled = False
subprocess.run(r"venv\Scripts\python.exe -m pip install --quiet --upgrade pip", cwd=install_dir, shell=True) page.update()
subprocess.run(r"venv\Scripts\pip.exe install --quiet -r requirements.txt", cwd=install_dir, shell=True) return
subprocess.run(r"venv\Scripts\pip.exe install --quiet requests pillow", cwd=install_dir, shell=True)
log(f"Python gefunden: {python_exe}")
# Download Handbrake
hb_path = os.path.join(install_dir, "HandBrakeCLI.exe") try:
if not os.path.exists(hb_path): os.makedirs(install_dir, exist_ok=True)
log("Lade HandBrakeCLI herunter...") test_file = os.path.join(install_dir, ".test")
try: with open(test_file, "w") as f:
hb_ver = "1.7.3" # Fallback if github fails f.write("x")
try: os.remove(test_file)
with urllib.request.urlopen("https://api.github.com/repos/HandBrake/HandBrake/releases/latest", timeout=5) as r: except Exception:
hb_data = json.loads(r.read().decode()) log(f"FEHLER: Keine Schreibrechte in {install_dir}")
if hb_data.get("tag_name"): hb_ver = hb_data["tag_name"].lstrip("v") log("Bitte als Administrator starten oder Pfad aendern.")
except: pass btn_install.disabled = False
hb_zip = os.path.join(install_dir, "hb.zip") page.update()
urllib.request.urlretrieve(f"https://github.com/HandBrake/HandBrake/releases/download/{hb_ver}/HandBrakeCLI-{hb_ver}-win-x86_64.zip", hb_zip) return
with zipfile.ZipFile(hb_zip, 'r') as zip_ref:
zip_ref.extractall(install_dir) # Download worker package
os.remove(hb_zip) log(f"Lade Worker-Code von {r_host}...")
except Exception as ex: try:
log(f"Warnung bei HandBrake-Download: {ex}") zip_path = os.path.join(install_dir, "worker.zip")
urllib.request.urlretrieve(
log("Erstelle Start-Skripte...") f"http://{r_host}/api/worker-setup/paket", zip_path
slots = txt_slots.value )
pool_arg = "--pool=solo" if int(slots) <= 1 else f"--pool=threads --concurrency={slots}" with zipfile.ZipFile(zip_path, "r") as zip_ref:
map_zeile = f"set RIPPY_PATH_MAP={txt_map.value.strip()}\r\n" if txt_map.value.strip() else "" zip_ref.extractall(install_dir)
os.remove(zip_path)
gui_bat = f"@echo off\r\ncd /d \"%~dp0\"\r\nset REDIS_URL=redis://{r_host}:6379/0\r\nset DATABASE_URL=postgresql://rippy:rippy@{r_host}:5432/rippy\r\nset API_URL=http://{r_host}:8000\r\nset WORKER_NAME={w_name}\r\nset RIPPY_TRAY_HOST={r_host}\r\nset RIPPY_SLOTS={slots}\r\nset TZ=UTC\r\n{map_zeile}set PATH=%~dp0;%PATH%\r\nstart \"\" venv\\Scripts\\pythonw.exe gui.py" except Exception as ex:
with open(os.path.join(install_dir, "start-gui.bat"), "w") as f: f.write(gui_bat) log(f"FEHLER beim Download: {ex}")
btn_install.disabled = False
work_bat = f"@echo off\r\ncd /d \"%~dp0\"\r\nset REDIS_URL=redis://{r_host}:6379/0\r\nset DATABASE_URL=postgresql://rippy:rippy@{r_host}:5432/rippy\r\nset API_URL=http://{r_host}:8000\r\nset WORKER_NAME={w_name}\r\nset RIPPY_SLOTS={slots}\r\nset TZ=UTC\r\n{map_zeile}set PATH=%~dp0;%PATH%\r\nvenv\\Scripts\\celery.exe -A celery_app worker --loglevel=info -Q transcode {pool_arg} -n {w_name}@%%h" page.update()
with open(os.path.join(install_dir, "start-worker.bat"), "w") as f: f.write(work_bat) return
# Uninstaller # Setup venv — --clear loescht einen alten venv komplett, damit keine
uninstall_ps1 = f"""param([switch]$Force) # veralteten Pakete (z.B. flet 0.86 statt 0.23) ueberleben.
Add-Type -AssemblyName System.Windows.Forms log("Lege Python-Umgebung an (venv)...")
if (-not $Force) {{ subprocess.run(
$antwort = [System.Windows.Forms.MessageBox]::Show("Rippy-Worker '{w_name}' von diesem PC entfernen?", "Rippy Worker deinstallieren", 4, 32) f"{python_exe} -m venv --clear venv", cwd=install_dir, shell=True
if ($antwort -ne "Yes") {{ exit }} )
}}
Get-WmiObject Win32_Process | Where-Object {{ log("Installiere Abhaengigkeiten (pip)...")
$_.ExecutablePath -like "$PSScriptRoot*" -or $_.CommandLine -like "*gui.py*" -or $_.CommandLine -like "*tray.py*" subprocess.run(
}} | ForEach-Object {{ Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue }} r"venv\Scripts\python.exe -m pip install --quiet --upgrade pip",
Start-Sleep 3 cwd=install_dir,
$desktopDir = if ($PSScriptRoot -match "(?i)Program Files") {{ [Environment]::GetFolderPath("CommonDesktopDirectory") }} else {{ [Environment]::GetFolderPath("Desktop") }} shell=True,
Remove-Item -Force "$desktopDir\\Rippy Worker.lnk" -ErrorAction SilentlyContinue )
schtasks /delete /tn "RippyWorker" /f *>$null subprocess.run(
Start-Process cmd -ArgumentList "/c ping 127.0.0.1 -n 3 >nul & rmdir /s /q `"$PSScriptRoot`"" -WindowStyle Hidden r"venv\Scripts\pip.exe install --quiet -r requirements.txt",
if (-not $Force) {{ [System.Windows.Forms.MessageBox]::Show("Rippy-Worker entfernt.", "Rippy Worker") }} cwd=install_dir,
""" shell=True,
with open(os.path.join(install_dir, "uninstall.ps1"), "w", encoding="utf-8") as f: f.write(uninstall_ps1) )
subprocess.run(
# Autostart r"venv\Scripts\pip.exe install --quiet requests pillow",
if chk_auto.value: cwd=install_dir,
log("Richte Autostart (Task Scheduler) ein...") shell=True,
bat_path = os.path.join(install_dir, "start-gui.bat") )
subprocess.run(f'schtasks /create /tn "RippyWorker" /tr "\\"{bat_path}\\"" /sc ONLOGON /rl HIGHEST /f', shell=True, capture_output=True)
# Download Handbrake
# Desktop Shortcut — ueber PowerShell/COM, weil win32com im hb_path = os.path.join(install_dir, "HandBrakeCLI.exe")
# PyInstaller-Bundle nicht enthalten ist. if not os.path.exists(hb_path):
if chk_desktop.value: log("Lade HandBrakeCLI herunter...")
try: try:
public_desktop = os.path.join(os.environ.get("PUBLIC", r"C:\Users\Public"), "Desktop") hb_ver = "1.7.3" # Fallback if github fails
user_desktop = os.path.join(os.path.expanduser("~"), "Desktop") try:
desktop = public_desktop if "Program Files" in install_dir and os.path.isdir(public_desktop) else user_desktop with urllib.request.urlopen(
lnk_path = os.path.join(desktop, "Rippy Worker.lnk") "https://api.github.com/repos/HandBrake/HandBrake/releases/latest",
bat_target = os.path.join(install_dir, "start-gui.bat") timeout=5,
ico_path = os.path.join(install_dir, "rippy.ico") ) as r:
ps_cmd = ( hb_data = json.loads(r.read().decode())
f'$ws = New-Object -ComObject WScript.Shell; ' if hb_data.get("tag_name"):
f'$sc = $ws.CreateShortcut(\"{lnk_path}\"); ' hb_ver = hb_data["tag_name"].lstrip("v")
f'$sc.TargetPath = \"{bat_target}\"; ' except Exception:
f'$sc.WorkingDirectory = \"{install_dir}\"; ' pass
f'$sc.IconLocation = \"{ico_path}\"; ' hb_zip = os.path.join(install_dir, "hb.zip")
f'$sc.WindowStyle = 7; ' urllib.request.urlretrieve(
f'$sc.Save()' f"https://github.com/HandBrake/HandBrake/releases/download/{hb_ver}/HandBrakeCLI-{hb_ver}-win-x86_64.zip",
) hb_zip,
subprocess.run(["powershell", "-NoProfile", "-Command", ps_cmd], capture_output=True) )
log("Desktop-Verknüpfung erstellt.") with zipfile.ZipFile(hb_zip, "r") as zip_ref:
except Exception as e: zip_ref.extractall(install_dir)
log(f"Warnung: Shortcut konnte nicht erstellt werden: {e}") os.remove(hb_zip)
except Exception as ex:
log("FERTIG!") log(f"Warnung bei HandBrake-Download: {ex}")
btn_start.visible = True
btn_install.text = "Neu installieren" log("Erstelle Start-Skripte...")
btn_install.disabled = False slots = txt_slots.value
page.update() pool_arg = (
"--pool=solo"
def start_worker(e): if int(slots) <= 1
install_dir = txt_pfad.value.strip() else f"--pool=threads --concurrency={slots}"
bat_path = os.path.join(install_dir, "start-gui.bat") )
# os.startfile startet die .bat ueber die Shell-Verknuepfung — map_zeile = (
# CREATE_NO_WINDOW wuerde sie stumm schlucken. f"set RIPPY_PATH_MAP={txt_map.value.strip()}\r\n"
os.startfile(bat_path) if txt_map.value.strip()
page.window_close() else ""
)
btn_install = ft.ElevatedButton("Installieren", on_click=do_install, bgcolor=c_accent, color=ft.colors.WHITE, width=200, height=40)
btn_start = ft.ElevatedButton("Worker starten", on_click=start_worker, bgcolor=c_success, color=ft.colors.WHITE, width=200, height=40, visible=False) gui_bat = f'@echo off\r\ncd /d "%~dp0"\r\nset REDIS_URL=redis://{r_host}:6379/0\r\nset DATABASE_URL=postgresql://rippy:rippy@{r_host}:5432/rippy\r\nset API_URL=http://{r_host}:8000\r\nset WORKER_NAME={w_name}\r\nset RIPPY_TRAY_HOST={r_host}\r\nset RIPPY_SLOTS={slots}\r\nset TZ=UTC\r\n{map_zeile}set PATH=%~dp0;%PATH%\r\nstart "" venv\\Scripts\\pythonw.exe gui.py'
with open(os.path.join(install_dir, "start-gui.bat"), "w") as f:
def get_dir(e: ft.FilePickerResultEvent): f.write(gui_bat)
if e.path:
txt_pfad.value = e.path work_bat = f'@echo off\r\ncd /d "%~dp0"\r\nset REDIS_URL=redis://{r_host}:6379/0\r\nset DATABASE_URL=postgresql://rippy:rippy@{r_host}:5432/rippy\r\nset API_URL=http://{r_host}:8000\r\nset WORKER_NAME={w_name}\r\nset RIPPY_SLOTS={slots}\r\nset TZ=UTC\r\n{map_zeile}set PATH=%~dp0;%PATH%\r\nvenv\\Scripts\\celery.exe -A celery_app worker --loglevel=info -Q transcode {pool_arg} -n {w_name}@%%h'
page.update() with open(os.path.join(install_dir, "start-worker.bat"), "w") as f:
f.write(work_bat)
dir_picker = ft.FilePicker(on_result=get_dir)
page.overlay.append(dir_picker) # Uninstaller
uninstall_ps1 = f"""param([switch]$Force)
page.add( Add-Type -AssemblyName System.Windows.Forms
ft.Row([ if (-not $Force) {{
ft.Icon(ft.icons.DISC_FULL, size=40, color=c_accent), $antwort = [System.Windows.Forms.MessageBox]::Show("Rippy-Worker '{w_name}' von diesem PC entfernen?", "Rippy Worker deinstallieren", 4, 32)
ft.Text("Rippy Encoding-Worker", size=28, weight=ft.FontWeight.BOLD, color=c_text) if ($antwort -ne "Yes") {{ exit }}
]), }}
ft.Text("Diese Maschine übernimmt die Video-Kompression für Rippy. Gerippt wird weiter auf der Hauptmaschine.", color=c_muted), Get-WmiObject Win32_Process | Where-Object {{
ft.Divider(color="#334155"), $_.ExecutablePath -like "$PSScriptRoot*" -or $_.CommandLine -like "*gui.py*" -or $_.CommandLine -like "*tray.py*"
ft.Row([txt_host], alignment=ft.MainAxisAlignment.START), }} | ForEach-Object {{ Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue }}
ft.Row([txt_name, txt_slots], alignment=ft.MainAxisAlignment.START), Start-Sleep 3
ft.Row([txt_pfad, ft.ElevatedButton("Durchsuchen ...", on_click=lambda _: dir_picker.get_directory_path("Installationsordner wählen"), bgcolor=c_panel, color=c_text)], alignment=ft.MainAxisAlignment.START), $desktopDir = if ($PSScriptRoot -match "(?i)Program Files") {{ [Environment]::GetFolderPath("CommonDesktopDirectory") }} else {{ [Environment]::GetFolderPath("Desktop") }}
ft.Row([txt_map, ft.ElevatedButton("Freigabe holen", on_click=check_map, bgcolor=c_panel, color=c_text)], alignment=ft.MainAxisAlignment.START), Remove-Item -Force "$desktopDir\\Rippy Worker.lnk" -ErrorAction SilentlyContinue
chk_auto, schtasks /delete /tn "RippyWorker" /f *>$null
chk_desktop, Start-Process cmd -ArgumentList "/c ping 127.0.0.1 -n 3 >nul & rmdir /s /q `"$PSScriptRoot`"" -WindowStyle Hidden
ft.Container(content=log_view, bgcolor="#020617", padding=10, border_radius=5, border=ft.border.all(1, "#334155")), if (-not $Force) {{ [System.Windows.Forms.MessageBox]::Show("Rippy-Worker entfernt.", "Rippy Worker") }}
ft.Row([btn_install, btn_start]) """
) with open(
os.path.join(install_dir, "uninstall.ps1"), "w", encoding="utf-8"
if __name__ == "__main__": ) as f:
ft.app(target=main) f.write(uninstall_ps1)
# Autostart
if chk_auto.value:
log("Richte Autostart (Task Scheduler) ein...")
bat_path = os.path.join(install_dir, "start-gui.bat")
subprocess.run(
f'schtasks /create /tn "RippyWorker" /tr "\\"{bat_path}\\"" /sc ONLOGON /rl HIGHEST /f',
shell=True,
capture_output=True,
)
# Desktop Shortcut — ueber PowerShell/COM, weil win32com im
# PyInstaller-Bundle nicht enthalten ist.
if chk_desktop.value:
try:
public_desktop = os.path.join(
os.environ.get("PUBLIC", r"C:\Users\Public"), "Desktop"
)
user_desktop = os.path.join(os.path.expanduser("~"), "Desktop")
desktop = (
public_desktop
if "Program Files" in install_dir and os.path.isdir(public_desktop)
else user_desktop
)
lnk_path = os.path.join(desktop, "Rippy Worker.lnk")
bat_target = os.path.join(install_dir, "start-gui.bat")
ico_path = os.path.join(install_dir, "rippy.ico")
ps_cmd = (
f"$ws = New-Object -ComObject WScript.Shell; "
f'$sc = $ws.CreateShortcut("{lnk_path}"); '
f'$sc.TargetPath = "{bat_target}"; '
f'$sc.WorkingDirectory = "{install_dir}"; '
f'$sc.IconLocation = "{ico_path}"; '
f"$sc.WindowStyle = 7; "
f"$sc.Save()"
)
subprocess.run(
["powershell", "-NoProfile", "-Command", ps_cmd],
capture_output=True,
)
log("Desktop-Verknüpfung erstellt.")
except Exception as e:
log(f"Warnung: Shortcut konnte nicht erstellt werden: {e}")
log("FERTIG!")
btn_start.visible = True
btn_install.text = "Neu installieren"
btn_install.disabled = False
page.update()
def start_worker(e):
install_dir = txt_pfad.value.strip()
bat_path = os.path.join(install_dir, "start-gui.bat")
# os.startfile startet die .bat ueber die Shell-Verknuepfung —
# CREATE_NO_WINDOW wuerde sie stumm schlucken.
os.startfile(bat_path)
page.window_close()
btn_install = ft.ElevatedButton(
"Installieren",
on_click=do_install,
bgcolor=c_accent,
color=ft.colors.WHITE,
width=200,
height=40,
)
btn_start = ft.ElevatedButton(
"Worker starten",
on_click=start_worker,
bgcolor=c_success,
color=ft.colors.WHITE,
width=200,
height=40,
visible=False,
)
def get_dir(e: ft.FilePickerResultEvent):
if e.path:
txt_pfad.value = e.path
page.update()
dir_picker = ft.FilePicker(on_result=get_dir)
page.overlay.append(dir_picker)
page.add(
ft.Row(
[
ft.Icon(ft.icons.DISC_FULL, size=40, color=c_accent),
ft.Text(
"Rippy Encoding-Worker",
size=28,
weight=ft.FontWeight.BOLD,
color=c_text,
),
]
),
ft.Text(
"Diese Maschine übernimmt die Video-Kompression für Rippy. Gerippt wird weiter auf der Hauptmaschine.",
color=c_muted,
),
ft.Divider(color="#334155"),
ft.Row([txt_host], alignment=ft.MainAxisAlignment.START),
ft.Row([txt_name, txt_slots], alignment=ft.MainAxisAlignment.START),
ft.Row(
[
txt_pfad,
ft.ElevatedButton(
"Durchsuchen ...",
on_click=lambda _: dir_picker.get_directory_path(
"Installationsordner wählen"
),
bgcolor=c_panel,
color=c_text,
),
],
alignment=ft.MainAxisAlignment.START,
),
ft.Row(
[
txt_map,
ft.ElevatedButton(
"Freigabe holen", on_click=check_map, bgcolor=c_panel, color=c_text
),
],
alignment=ft.MainAxisAlignment.START,
),
chk_auto,
chk_desktop,
ft.Container(
content=log_view,
bgcolor="#020617",
padding=10,
border_radius=5,
border=ft.border.all(1, "#334155"),
),
ft.Row([btn_install, btn_start]),
)
if __name__ == "__main__":
ft.app(target=main)
+747 -599
View File
File diff suppressed because it is too large Load Diff