Aggiunge tray app e backup manuale
This commit is contained in:
113
src/bakrest/tray_app.py
Normal file
113
src/bakrest/tray_app.py
Normal file
@@ -0,0 +1,113 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import logging
|
||||
import threading
|
||||
import tkinter as tk
|
||||
from tkinter import messagebox
|
||||
from pathlib import Path
|
||||
|
||||
from PIL import Image, ImageDraw
|
||||
import pystray
|
||||
|
||||
from .backup import run_backup, shutdown_after_backup
|
||||
from .config import AppConfig, load_config
|
||||
from .logging_setup import configure_logging
|
||||
from .registry import ChangeRegistry
|
||||
|
||||
|
||||
class BakRestTrayApp:
|
||||
def __init__(self, config: AppConfig, logger: logging.Logger) -> None:
|
||||
self.config = config
|
||||
self.logger = logger
|
||||
self.registry = ChangeRegistry(config.storage.change_registry)
|
||||
self.icon = pystray.Icon(
|
||||
"BakRestTray",
|
||||
_create_icon_image(),
|
||||
"Bak&Rest",
|
||||
self._build_menu(),
|
||||
)
|
||||
|
||||
def run(self) -> None:
|
||||
self.logger.info("BakRestTray started")
|
||||
self.icon.run()
|
||||
|
||||
def _build_menu(self) -> pystray.Menu:
|
||||
return pystray.Menu(
|
||||
pystray.MenuItem(lambda item: self._status_text(), None, enabled=False),
|
||||
pystray.Menu.SEPARATOR,
|
||||
pystray.MenuItem("Backup e spegni", self._backup_and_shutdown),
|
||||
pystray.MenuItem("Aggiorna stato", self._refresh),
|
||||
pystray.MenuItem("Esci", self._quit),
|
||||
)
|
||||
|
||||
def _status_text(self) -> str:
|
||||
pending = self.registry.pending_count()
|
||||
server = self._read_server_status()
|
||||
return f"Server: {server} | File in attesa: {pending}"
|
||||
|
||||
def _read_server_status(self) -> str:
|
||||
path = self.config.storage.status_file
|
||||
if not path.exists():
|
||||
return "sconosciuto"
|
||||
try:
|
||||
data = json.loads(path.read_text(encoding="utf-8"))
|
||||
except (OSError, json.JSONDecodeError):
|
||||
return "errore stato"
|
||||
return "raggiungibile" if data.get("reachable") else "non raggiungibile"
|
||||
|
||||
def _backup_and_shutdown(self, icon: pystray.Icon, item: pystray.MenuItem) -> None:
|
||||
threading.Thread(target=self._backup_and_shutdown_worker, daemon=True).start()
|
||||
|
||||
def _backup_and_shutdown_worker(self) -> None:
|
||||
self.logger.info("User requested Backup e spegni")
|
||||
self.icon.title = "Bak&Rest - backup in corso"
|
||||
result = run_backup(self.config, self.logger)
|
||||
if result.success:
|
||||
self.icon.title = "Bak&Rest - backup completato"
|
||||
shutdown_after_backup(self.config, self.logger)
|
||||
else:
|
||||
self.icon.title = "Bak&Rest - backup fallito"
|
||||
if result.error_code == "server_unreachable":
|
||||
_show_error_message("Bak&Rest", "Server non raggiungibile. E' spento?")
|
||||
else:
|
||||
_show_error_message("Bak&Rest", result.message)
|
||||
self.icon.update_menu()
|
||||
|
||||
def _refresh(self, icon: pystray.Icon, item: pystray.MenuItem) -> None:
|
||||
self.icon.update_menu()
|
||||
|
||||
def _quit(self, icon: pystray.Icon, item: pystray.MenuItem) -> None:
|
||||
self.logger.info("BakRestTray stopped")
|
||||
self.icon.stop()
|
||||
|
||||
|
||||
def _create_icon_image() -> Image.Image:
|
||||
image = Image.new("RGBA", (64, 64), (26, 38, 52, 255))
|
||||
draw = ImageDraw.Draw(image)
|
||||
draw.rounded_rectangle((10, 14, 54, 50), radius=8, fill=(77, 163, 255, 255))
|
||||
draw.rectangle((18, 24, 46, 44), fill=(245, 248, 252, 255))
|
||||
draw.line((22, 34, 32, 42, 46, 26), fill=(26, 38, 52, 255), width=5)
|
||||
return image
|
||||
|
||||
|
||||
def _show_error_message(title: str, message: str) -> None:
|
||||
root = tk.Tk()
|
||||
root.withdraw()
|
||||
root.attributes("-topmost", True)
|
||||
try:
|
||||
messagebox.showerror(title, message, parent=root)
|
||||
finally:
|
||||
root.destroy()
|
||||
|
||||
|
||||
def main() -> int:
|
||||
config = load_config()
|
||||
logger = configure_logging(config.storage.logs_dir, "tray")
|
||||
app = BakRestTrayApp(config, logger)
|
||||
app.run()
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
Reference in New Issue
Block a user