fichiers oubliés

This commit is contained in:
sebastien committed 2026-09-26 23:01:47 +02:00
1 parent d048732613
commit 857efcef18
8 files changed
+722

No files matched your search

+113
View File
@@ -0,0 +1,113 @@
"""Non-blocking controls for the system Syncthing instance."""
import queue
import subprocess
import threading
from tkinter import ttk, messagebox
SERVICE = "syncthing@sebastien.service"
def service_status():
result = subprocess.run(
["systemctl", "show", SERVICE, "--property=ActiveState", "--value"],
capture_output=True, text=True, timeout=10,
)
if result.returncode:
raise RuntimeError(result.stderr.strip() or "Statut indisponible")
return result.stdout.strip() or "unknown"
def control_service(action):
if action == "ensure" and service_status() == "active":
return "active"
command = "start" if action == "ensure" else action
result = subprocess.run(
["systemctl", "--no-ask-password", command, SERVICE],
capture_output=True, text=True, timeout=60,
)
if result.returncode:
raise RuntimeError(result.stderr.strip() or f"Échec de systemctl {command}")
status = service_status()
if command == "start" and status != "active":
raise RuntimeError(f"Syncthing n’est pas actif : {status}")
return status
class SyncthingPanel(ttk.Frame):
def __init__(self, parent):
super().__init__(parent)
self.events = queue.Queue()
self.busy = False
self.pending_export = None
self.status = ttk.Label(self, text=f"{SERVICE} : vérification…")
self.status.pack(anchor="w")
controls = ttk.Frame(self)
controls.pack(anchor="w", pady=4)
self.start_button = ttk.Button(controls, text="Démarrer Syncthing",
command=lambda: self.request("start"))
self.start_button.pack(side="left")
self.stop_button = ttk.Button(controls, text="Arrêter Syncthing",
command=lambda: self.request("stop"))
self.stop_button.pack(side="left", padx=6)
self.timer = self.after(100, self.poll)
self.refresh_timer = None
self.bind("<Destroy>", self.cleanup, add=True)
self.request("status")
def ensure_started(self, callback):
self.pending_export = callback
if not self.busy:
self.request("ensure")
def request(self, action):
if self.busy:
return
self.busy = True
self.start_button.configure(state="disabled")
self.stop_button.configure(state="disabled")
if action != "status":
self.status.configure(text=f"{SERVICE} : opération en cours…")
def work():
try:
status = service_status() if action == "status" else control_service(action)
self.events.put((action, status, None))
except (OSError, RuntimeError, subprocess.TimeoutExpired) as exc:
self.events.put((action, None, str(exc)))
threading.Thread(target=work, daemon=True).start()
def poll(self):
try:
action, status, error = self.events.get_nowait()
except queue.Empty:
pass
else:
self.busy = False
self.start_button.configure(state="normal")
self.stop_button.configure(state="normal")
self.status.configure(text=f"{SERVICE} : {error or status}")
if error and action != "status":
self.pending_export = None
messagebox.showerror("Syncthing", error)
elif action == "ensure":
callback, self.pending_export = self.pending_export, None
if callback:
callback()
elif self.pending_export:
self.request("ensure")
if self.winfo_exists():
self.timer = self.after(100, self.poll)
if self.refresh_timer is None:
self.refresh_timer = self.after(5000, self.refresh)
def refresh(self):
self.refresh_timer = None
self.request("status")
def cleanup(self, event):
if event.widget == self:
self.pending_export = None
for timer in (self.timer, self.refresh_timer):
if timer:
self.after_cancel(timer)