# launcher_src/worker.py """ Contiene la classe Worker basata su QRunnable per eseguire le operazioni di sincronizzazione in un thread separato. """ from PyQt6.QtCore import QObject, pyqtSignal, QRunnable from .sync_manager import SyncManager import time from .logger import get_logger class WorkerSignals(QObject): """Segnali emessi dal worker.""" progress = pyqtSignal(int, str, str) finished = pyqtSignal(bool, str) class SyncWorker(QRunnable): """Worker che esegue il controllo e la sincronizzazione.""" def __init__(self, sync_manager: SyncManager): super().__init__() self.sync_manager = sync_manager self.signals = WorkerSignals() self._log = get_logger(self.__class__.__name__) def run(self): """Logica eseguita nel thread secondario con fallback offline.""" try: # --- FASE 1: CONTROLLO --- try: jobs_to_do = self.sync_manager.check_for_updates() server_ok = True except Exception as check_err: # Server non raggiungibile o metadati illeggibili: andiamo in modalità offline server_ok = False offline_reason = str(check_err) jobs_to_do = [] self._log.warning("Modalità offline: %s", offline_reason) # Memorizziamo se è necessario un aggiornamento pesante did_heavy_update = "python_embeddable" in jobs_to_do or "app" in jobs_to_do or "local_db" in jobs_to_do # --- FASE 2: ESECUZIONE (se necessaria) --- if jobs_to_do: self.sync_manager.run_sync(jobs_to_do, self.signals.progress.emit) # --- FASE 3: AVVIO E ATTESA INTELLIGENTE --- if not server_ok: self.signals.progress.emit(95, "Server non disponibile", "Modalità offline: avvio versione locale") self._log.info("Avvio in modalità offline (nessuna sincronizzazione)") self.signals.progress.emit(100, "Avvio applicazione...", "(inizializzazione in corso)") self.sync_manager.launch_application() timeout = 45 if did_heavy_update else 20 self.sync_manager.wait_for_ready(timeout=timeout) self.signals.finished.emit(True, "Avvio completato.") self._log.info("Hand-off al processo applicativo completato") except Exception as e: # Tentativo di recupero: se l'ambiente locale esiste, prova un avvio locale try: from . import config if config.LOCAL_PYTHON_EXECUTABLE.exists(): self.signals.progress.emit(95, "Tentativo di recupero", "Avvio locale senza aggiornamento") self._log.warning("Tentativo di recupero: lancio locale senza aggiornamento. Errore precedente: %s", e) self.sync_manager.launch_application() time.sleep(2) self.signals.finished.emit(True, f"Avvio locale completato (avviso: {e})") return except Exception: pass self.signals.finished.emit(False, str(e)) self._log.exception("Errore non gestito nel worker")