feat: Thumbnails, bunte Logs und Button-Status im Worker UI
This commit is contained in:
Binary file not shown.
+73
-16
@@ -6,6 +6,7 @@ import time
|
|||||||
import urllib.request
|
import urllib.request
|
||||||
import json
|
import json
|
||||||
import webbrowser
|
import webbrowser
|
||||||
|
import re
|
||||||
import flet as ft
|
import flet as ft
|
||||||
|
|
||||||
# Tray-Icon: pystray + PIL fuer das Icon-Bild
|
# Tray-Icon: pystray + PIL fuer das Icon-Bild
|
||||||
@@ -313,12 +314,35 @@ def main(page: ft.Page):
|
|||||||
height=120,
|
height=120,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Live Log Regex and Layout
|
||||||
|
# [2026-07-26 20:34:00,093: INFO/MainProcess] message...
|
||||||
|
LOG_REGEX = re.compile(r"^\[.*? (\d{2}:\d{2}:\d{2}),.*?: (INFO|WARNING|ERROR|SUCCESS).*?\] (.*)")
|
||||||
|
|
||||||
log_view = ft.ListView(expand=1, spacing=2, auto_scroll=True)
|
log_view = ft.ListView(expand=1, spacing=2, auto_scroll=True)
|
||||||
queue_view = ft.ListView(height=120, spacing=4, auto_scroll=False)
|
queue_view = ft.ListView(height=120, spacing=4, auto_scroll=False)
|
||||||
|
|
||||||
def add_log(zeile):
|
def add_log(zeile):
|
||||||
# Zeilen anfügen und limitieren
|
z = zeile.strip()
|
||||||
log_view.controls.append(ft.Text(zeile.strip(), color=c_muted, size=12, font_family="Consolas"))
|
if not z: return
|
||||||
|
|
||||||
|
match = LOG_REGEX.match(z)
|
||||||
|
if match:
|
||||||
|
zeit, level, msg = match.groups()
|
||||||
|
color = c_text
|
||||||
|
if level == "INFO": color = "#38bdf8" # sky-400
|
||||||
|
elif level == "WARNING": color = "#fbbf24" # amber-400
|
||||||
|
elif level == "ERROR": color = "#f87171" # red-400
|
||||||
|
elif level == "SUCCESS": color = "#34d399" # emerald-400
|
||||||
|
|
||||||
|
row = ft.Row([
|
||||||
|
ft.Text(zeit, color=c_muted, size=12, font_family="Consolas"),
|
||||||
|
ft.Text(f"[{level}]", color=color, size=12, font_family="Consolas", weight=ft.FontWeight.BOLD),
|
||||||
|
ft.Text(msg, color=c_text, size=12, font_family="Consolas", expand=True)
|
||||||
|
], spacing=10, vertical_alignment=ft.CrossAxisAlignment.START)
|
||||||
|
log_view.controls.append(row)
|
||||||
|
else:
|
||||||
|
log_view.controls.append(ft.Text(z, color=c_muted, size=12, font_family="Consolas"))
|
||||||
|
|
||||||
if len(log_view.controls) > 200:
|
if len(log_view.controls) > 200:
|
||||||
log_view.controls.pop(0)
|
log_view.controls.pop(0)
|
||||||
try:
|
try:
|
||||||
@@ -327,23 +351,20 @@ def main(page: ft.Page):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
def toggle_worker(e):
|
def toggle_worker(e):
|
||||||
if worker_laeuft():
|
if not worker_laeuft():
|
||||||
worker_stoppen()
|
|
||||||
btn_toggle.text = "Worker Starten"
|
|
||||||
btn_toggle.icon = ft.icons.PLAY_ARROW
|
|
||||||
btn_toggle.bgcolor = c_success
|
|
||||||
else:
|
|
||||||
worker_starten(add_log)
|
worker_starten(add_log)
|
||||||
btn_toggle.text = "Worker Stoppen"
|
btn_toggle.text = "Worker läuft"
|
||||||
btn_toggle.icon = ft.icons.STOP
|
btn_toggle.icon = ft.icons.CHECK
|
||||||
btn_toggle.bgcolor = c_danger
|
btn_toggle.bgcolor = "#1e293b"
|
||||||
|
btn_toggle.disabled = True
|
||||||
page.update()
|
page.update()
|
||||||
|
|
||||||
btn_toggle = ft.ElevatedButton(
|
btn_toggle = ft.ElevatedButton(
|
||||||
text="Worker Stoppen" if worker_laeuft() else "Worker Starten",
|
text="Worker läuft" if worker_laeuft() else "Worker Starten",
|
||||||
icon=ft.icons.STOP if worker_laeuft() else ft.icons.PLAY_ARROW,
|
icon=ft.icons.CHECK if worker_laeuft() else ft.icons.PLAY_ARROW,
|
||||||
bgcolor=c_danger if worker_laeuft() else c_success,
|
bgcolor="#1e293b" if worker_laeuft() else c_success,
|
||||||
color="white",
|
color="white",
|
||||||
|
disabled=worker_laeuft(),
|
||||||
on_click=toggle_worker
|
on_click=toggle_worker
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -400,12 +421,15 @@ def main(page: ft.Page):
|
|||||||
alignment=ft.MainAxisAlignment.SPACE_BETWEEN
|
alignment=ft.MainAxisAlignment.SPACE_BETWEEN
|
||||||
)
|
)
|
||||||
|
|
||||||
|
active_poster = ft.Image(src="", visible=False, width=64, height=96, border_radius=8, fit=ft.ImageFit.COVER)
|
||||||
|
|
||||||
dashboard_card = ft.Container(
|
dashboard_card = ft.Container(
|
||||||
content=ft.Column([
|
content=ft.Column([
|
||||||
status_text,
|
status_text,
|
||||||
machine_info,
|
machine_info,
|
||||||
ft.Container(height=5),
|
ft.Container(height=5),
|
||||||
ft.Row([
|
ft.Row([
|
||||||
|
active_poster,
|
||||||
progress_stack,
|
progress_stack,
|
||||||
ft.Column([job_title, eta_text], alignment=ft.MainAxisAlignment.CENTER, spacing=10)
|
ft.Column([job_title, eta_text], alignment=ft.MainAxisAlignment.CENTER, spacing=10)
|
||||||
], alignment=ft.MainAxisAlignment.START, spacing=30),
|
], alignment=ft.MainAxisAlignment.START, spacing=30),
|
||||||
@@ -471,7 +495,16 @@ def main(page: ft.Page):
|
|||||||
queue_view.controls.append(ft.Text("Keine Aufgaben in Rippy", color=c_muted, font_family="Consolas", size=13))
|
queue_view.controls.append(ft.Text("Keine Aufgaben in Rippy", color=c_muted, font_family="Consolas", size=13))
|
||||||
else:
|
else:
|
||||||
for j in jobs[:8]:
|
for j in jobs[:8]:
|
||||||
queue_view.controls.append(ft.Text(" " + job_text(j), color=c_muted, font_family="Consolas", size=13))
|
poster = None
|
||||||
|
if j.get("meta") and j["meta"].get("poster_path"):
|
||||||
|
p = j["meta"]["poster_path"]
|
||||||
|
poster = p if p.startswith("http") else f"https://image.tmdb.org/t/p/w342{p}"
|
||||||
|
|
||||||
|
row_items = []
|
||||||
|
if poster:
|
||||||
|
row_items.append(ft.Image(src=poster, width=40, height=60, border_radius=5, fit=ft.ImageFit.COVER))
|
||||||
|
row_items.append(ft.Text(job_text(j), color=c_muted, font_family="Consolas", size=13, expand=True))
|
||||||
|
queue_view.controls.append(ft.Row(row_items, alignment=ft.MainAxisAlignment.START, spacing=15))
|
||||||
|
|
||||||
# Update status
|
# Update status
|
||||||
if not worker_laeuft():
|
if not worker_laeuft():
|
||||||
@@ -481,11 +514,17 @@ def main(page: ft.Page):
|
|||||||
progress_percentage.value = "0%"
|
progress_percentage.value = "0%"
|
||||||
job_title.value = "Nichts in Arbeit"
|
job_title.value = "Nichts in Arbeit"
|
||||||
eta_text.value = "Bereit"
|
eta_text.value = "Bereit"
|
||||||
|
active_poster.visible = False
|
||||||
|
btn_toggle.disabled = False
|
||||||
|
btn_toggle.text = "Worker Starten"
|
||||||
|
btn_toggle.icon = ft.icons.PLAY_ARROW
|
||||||
|
btn_toggle.bgcolor = c_success
|
||||||
elif not online:
|
elif not online:
|
||||||
status_text.value = "Nicht mit Rippy verbunden (offline)"
|
status_text.value = "Nicht mit Rippy verbunden (offline)"
|
||||||
status_text.color = c_warning
|
status_text.color = c_warning
|
||||||
progress_ring.value = 0
|
progress_ring.value = 0
|
||||||
progress_percentage.value = "0%"
|
progress_percentage.value = "0%"
|
||||||
|
active_poster.visible = False
|
||||||
elif job:
|
elif job:
|
||||||
status_text.value = "Aktiv: Komprimiert"
|
status_text.value = "Aktiv: Komprimiert"
|
||||||
status_text.color = c_success
|
status_text.color = c_success
|
||||||
@@ -496,13 +535,31 @@ def main(page: ft.Page):
|
|||||||
job_title.value = titel
|
job_title.value = titel
|
||||||
eta = job.get("eta_text") or "Restzeit wird berechnet..."
|
eta = job.get("eta_text") or "Restzeit wird berechnet..."
|
||||||
eta_text.value = f"Verbleibend: {eta}"
|
eta_text.value = f"Verbleibend: {eta}"
|
||||||
|
|
||||||
|
# Update Active Poster
|
||||||
|
poster = None
|
||||||
|
if job.get("meta") and job["meta"].get("poster_path"):
|
||||||
|
p = job["meta"]["poster_path"]
|
||||||
|
poster = p if p.startswith("http") else f"https://image.tmdb.org/t/p/w342{p}"
|
||||||
|
|
||||||
|
if poster:
|
||||||
|
active_poster.src = poster
|
||||||
|
active_poster.visible = True
|
||||||
|
else:
|
||||||
|
active_poster.visible = False
|
||||||
else:
|
else:
|
||||||
status_text.value = "Verbunden & Bereit"
|
status_text.value = "Verbunden & Bereit"
|
||||||
status_text.color = c_accent
|
status_text.color = c_accent
|
||||||
progress_ring.value = 0
|
progress_ring.value = 0
|
||||||
progress_percentage.value = "0%"
|
progress_percentage.value = "0%"
|
||||||
job_title.value = "Warte auf Aufträge..."
|
job_title.value = "Warte auf Encoder-Aufträge..."
|
||||||
eta_text.value = "Nichts in Arbeit"
|
eta_text.value = "Nichts in Arbeit"
|
||||||
|
active_poster.visible = False
|
||||||
|
|
||||||
|
btn_toggle.disabled = True
|
||||||
|
btn_toggle.text = "Worker läuft"
|
||||||
|
btn_toggle.icon = ft.icons.CHECK
|
||||||
|
btn_toggle.bgcolor = "#1e293b"
|
||||||
|
|
||||||
page.update()
|
page.update()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
Reference in New Issue
Block a user