feat: dashboard UI with real-time stats, light/dark mode, session metrics

This commit is contained in:
2026-06-12 08:11:24 +02:00
parent 20247c92c2
commit 7a388653ed
6 changed files with 1050 additions and 46 deletions
+73
View File
@@ -1,10 +1,83 @@
import json
import threading
import time
from collections import deque
from datetime import datetime, timezone
from http.server import HTTPServer, BaseHTTPRequestHandler
from io import StringIO
class SyncSession:
def __init__(self):
self._lock = threading.Lock()
self.start_time = time.time()
self.syncs_total = 0
self.syncs_failed = 0
self.syncs_skipped = 0
self.total_added = 0
self.total_updated = 0
self.total_deleted = 0
self.total_duration = 0.0
self.total_latency_ms = 0.0
self.non_skip_count = 0
self.bandwidth_bytes = 0
self.bandwidth_saved_bytes = 0
self.history = deque(maxlen=50)
def record(self, ok: bool, duration: float, added: int, updated: int, deleted: int, skipped: bool, ics_latency_ms: float, msg: str, ics_download_size: int = 0) -> None:
with self._lock:
self.syncs_total += 1
ts = time.strftime("%H:%M:%S", time.gmtime())
if not ok:
self.syncs_failed += 1
if skipped:
self.syncs_skipped += 1
self.total_added += added
self.total_updated += updated
self.total_deleted += deleted
if not skipped:
self.non_skip_count += 1
self.total_duration += duration
self.total_latency_ms += ics_latency_ms
if ics_download_size:
self.bandwidth_bytes += ics_download_size
self.history.append({
"time": ts,
"ok": ok,
"duration": round(duration, 2),
"added": added,
"updated": updated,
"deleted": deleted,
"skipped": skipped,
"latency_ms": round(ics_latency_ms),
"msg": msg,
})
def get_status(self) -> dict:
with self._lock:
uptime = time.time() - self.start_time
avg_dur = round(self.total_duration / self.non_skip_count, 2) if self.non_skip_count > 0 else 0
avg_lat = round(self.total_latency_ms / self.non_skip_count) if self.non_skip_count > 0 else 0
return {
"uptime_sec": round(uptime),
"syncs_total": self.syncs_total,
"syncs_failed": self.syncs_failed,
"syncs_skipped": self.syncs_skipped,
"total_added": self.total_added,
"total_updated": self.total_updated,
"total_deleted": self.total_deleted,
"avg_duration": avg_dur,
"avg_latency_ms": avg_lat,
"bandwidth_bytes": self.bandwidth_bytes,
"bandwidth_saved_bytes": self.bandwidth_saved_bytes,
"history": list(self.history),
}
def add_saved_bandwidth(self, bytes_saved: int) -> None:
with self._lock:
self.bandwidth_saved_bytes += bytes_saved
class HealthServer:
def __init__(self, port: int = 8081):
self.port = port