# --- FILE: async_workers.py --- import os import queue import logging # Usato solo per i livelli, non per loggare direttamente import datetime # Necessario per alcuni messaggi # Importa i moduli necessari per la logica interna e le dipendenze import log_handler from git_commands import GitCommands, GitCommandError from action_handler import ActionHandler from backup_handler import BackupHandler from remote_actions import RemoteActionHandler # Nota: Queste sono funzioni standalone, non metodi di una classe. # === Worker per Refresh GUI === def run_refresh_tags_async( git_commands: GitCommands, repo_path: str, results_queue: queue.Queue ): """Worker to fetch tag list asynchronously.""" func_name = "run_refresh_tags_async" log_handler.log_debug( f"[Worker] Started: Refresh Tags for '{repo_path}'", func_name=func_name ) try: # Chiama il metodo corretto in GitCommands tags_data = git_commands.list_tags(repo_path) count = len(tags_data) message = f"Tags refreshed ({count} found)." log_handler.log_info(f"[Worker] {message}", func_name=func_name) # Metti il risultato nella coda results_queue.put( {"status": "success", "result": tags_data, "message": message} ) except (GitCommandError, Exception) as e: log_handler.log_exception( f"[Worker] EXCEPTION refreshing tags: {e}", func_name=func_name ) results_queue.put( { "status": "error", "exception": e, "result": [ ("(Error)", "") ], # Formato atteso dalla GUI in caso di errore "message": f"Error refreshing tags: {type(e).__name__}", } ) finally: log_handler.log_debug("[Worker] Finished: Refresh Tags", func_name=func_name) def run_refresh_branches_async( git_commands: GitCommands, repo_path: str, results_queue: queue.Queue ): """Worker to fetch branch list asynchronously.""" func_name = "run_refresh_branches_async" log_handler.log_debug( f"[Worker] Started: Refresh Branches for '{repo_path}'", func_name=func_name ) try: # Chiama il metodo corretto in GitCommands branches, current = git_commands.list_branches(repo_path) count = len(branches) curr_disp = current if current else "None (Detached?)" message = f"Branches refreshed ({count} found). Current: {curr_disp}" log_handler.log_info(f"[Worker] {message}", func_name=func_name) # Metti il risultato (una tupla) nella coda results_queue.put( {"status": "success", "result": (branches, current), "message": message} ) except (GitCommandError, Exception) as e: log_handler.log_exception( f"[Worker] EXCEPTION refreshing branches: {e}", func_name=func_name ) results_queue.put( { "status": "error", "exception": e, "result": ( ["(Error)"], None, ), # Formato atteso dalla GUI in caso di errore "message": f"Error refreshing branches: {type(e).__name__}", } ) finally: log_handler.log_debug( "[Worker] Finished: Refresh Branches", func_name=func_name ) def run_refresh_history_async( git_commands: GitCommands, repo_path: str, branch_filter: str | None, log_scope: str, # Descrizione per i log (es. 'All History' o "'branch_name'") results_queue: queue.Queue, ): """Worker to fetch commit history asynchronously.""" func_name = "run_refresh_history_async" log_handler.log_debug( f"[Worker] Started: Refresh History ({log_scope}) for '{repo_path}'", func_name=func_name, ) try: # Chiama il metodo corretto in GitCommands log_data = git_commands.get_commit_log( repo_path, max_count=200, branch=branch_filter ) count = len(log_data) message = f"History refreshed ({count} entries for {log_scope})." log_handler.log_info(f"[Worker] {message}", func_name=func_name) # Metti il risultato (lista di stringhe) nella coda results_queue.put({"status": "success", "result": log_data, "message": message}) except (GitCommandError, Exception) as e: log_handler.log_exception( f"[Worker] EXCEPTION refreshing history: {e}", func_name=func_name ) results_queue.put( { "status": "error", "exception": e, "result": ["(Error retrieving history)"], # Formato atteso dalla GUI "message": f"Error refreshing history: {type(e).__name__}", } ) finally: log_handler.log_debug( f"[Worker] Finished: Refresh History ({log_scope})", func_name=func_name ) def run_refresh_changes_async( git_commands: GitCommands, repo_path: str, results_queue: queue.Queue ): """Worker to get status of changed files asynchronously.""" func_name = "run_refresh_changes_async" log_handler.log_debug( f"[Worker] Started: Refresh Changes for '{repo_path}'", func_name=func_name ) try: # Chiama il metodo corretto in GitCommands files_status_list = git_commands.get_status_short(repo_path) count = len(files_status_list) log_handler.log_info(f"[Worker] Found {count} changes.", func_name=func_name) message = ( f"Ready ({count} changes detected)." if count > 0 else "Ready (No changes detected)." ) # Logga prima di mettere in coda per debug log_handler.log_debug( f"[Worker] Preparing result for queue. Status: success, Count: {count}", func_name=func_name, ) results_queue.put( {"status": "success", "result": files_status_list, "message": message} ) log_handler.log_debug( "[Worker] Successfully PUT result in queue.", func_name=func_name ) except (GitCommandError, ValueError, Exception) as e: log_handler.log_exception( f"[Worker] EXCEPTION refreshing changes: {e}", func_name=func_name ) results_queue.put( { "status": "error", "exception": e, "result": ["(Error refreshing changes)"], # Formato atteso "message": f"Error refreshing changes: {type(e).__name__}", } ) finally: log_handler.log_debug("[Worker] Finished: Refresh Changes", func_name=func_name) # === Worker per Azioni Principali === def run_prepare_async( action_handler: ActionHandler, repo_path: str, results_queue: queue.Queue ): """Worker to prepare repository asynchronously.""" func_name = "run_prepare_async" log_handler.log_debug( f"[Worker] Started: Prepare Repo for '{repo_path}'", func_name=func_name ) try: # Chiama il metodo corretto in ActionHandler success = action_handler.execute_prepare_repo(repo_path) message = "Repository prepared successfully." log_handler.log_info(f"[Worker] {message}", func_name=func_name) results_queue.put({"status": "success", "result": success, "message": message}) except ValueError as e: # Gestione specifica per "already prepared" if "already prepared" in str(e).lower(): log_handler.log_warning(f"[Worker] Warning: {e}", func_name=func_name) results_queue.put( { "status": "warning", "result": True, "message": str(e), } # Segnala come warning ) else: # Rilancia altri ValueError log_handler.log_exception( f"[Worker] VALUE ERROR preparing repo: {e}", func_name=func_name ) results_queue.put( {"status": "error", "exception": e, "message": f"Error preparing: {e}"} ) except (GitCommandError, IOError, Exception) as e: log_handler.log_exception( f"[Worker] EXCEPTION preparing repo: {e}", func_name=func_name ) results_queue.put( { "status": "error", "exception": e, "message": f"Error preparing repository: {type(e).__name__}", } ) finally: log_handler.log_debug("[Worker] Finished: Prepare Repo", func_name=func_name) def run_create_bundle_async( action_handler: ActionHandler, repo_path: str, bundle_full_path: str, profile_name: str, autobackup_enabled: bool, backup_base_dir: str, autocommit_enabled: bool, commit_message: str, excluded_extensions: set, excluded_dirs: set, results_queue: queue.Queue, ): """Worker to create Git bundle asynchronously.""" func_name = "run_create_bundle_async" log_handler.log_debug( f"[Worker] Started: Create Bundle '{os.path.basename(bundle_full_path)}' from '{repo_path}'", func_name=func_name, ) try: # Chiama il metodo corretto in ActionHandler result_path = action_handler.execute_create_bundle( repo_path=repo_path, bundle_full_path=bundle_full_path, profile_name=profile_name, autobackup_enabled=autobackup_enabled, backup_base_dir=backup_base_dir, autocommit_enabled=autocommit_enabled, commit_message=commit_message, excluded_extensions=excluded_extensions, excluded_dirs=excluded_dirs, ) # Determina messaggio successo if result_path: message = f"Bundle created: {os.path.basename(result_path)}" else: # Potrebbe non essere stato creato per repo vuoto o nessun cambiamento + no commit message = "Bundle creation finished (no file generated - repo empty or no changes?)." log_handler.log_info(f"[Worker] {message}", func_name=func_name) results_queue.put( { "status": "success", "result": result_path, # Può essere None "message": message, "committed": autocommit_enabled, # Indica se è stato TENTATO un autocommit } ) except (IOError, GitCommandError, ValueError, Exception) as e: log_handler.log_exception( f"[Worker] EXCEPTION creating bundle: {e}", func_name=func_name ) results_queue.put( { "status": "error", "exception": e, "message": f"Error creating bundle: {type(e).__name__}", } ) finally: log_handler.log_debug("[Worker] Finished: Create Bundle", func_name=func_name) def run_fetch_bundle_async( action_handler: ActionHandler, target_repo_path_str: str, # Può essere dir non esistente bundle_full_path: str, profile_name: str, autobackup_enabled: bool, backup_base_dir: str, excluded_extensions: set, excluded_dirs: set, results_queue: queue.Queue, ): """Worker to fetch/clone from Git bundle asynchronously.""" func_name = "run_fetch_bundle_async" log_handler.log_debug( f"[Worker] Started: Fetch Bundle '{os.path.basename(bundle_full_path)}' into '{target_repo_path_str}'", func_name=func_name, ) try: # Chiama il metodo corretto in ActionHandler success = action_handler.execute_fetch_bundle( target_repo_path_str=target_repo_path_str, bundle_full_path=bundle_full_path, profile_name=profile_name, autobackup_enabled=autobackup_enabled, backup_base_dir=backup_base_dir, excluded_extensions=excluded_extensions, excluded_dirs=excluded_dirs, ) message = "Fetch/Clone from bundle completed successfully." log_handler.log_info(f"[Worker] {message}", func_name=func_name) results_queue.put({"status": "success", "result": success, "message": message}) except (FileNotFoundError, IOError, GitCommandError, ValueError, Exception) as e: log_handler.log_exception( f"[Worker] EXCEPTION fetching bundle: {e}", func_name=func_name ) # Controlla se è un errore di conflitto merge is_conflict = False if isinstance(e, GitCommandError) and "merge conflict" in str(e).lower(): is_conflict = True log_handler.log_error( "[Worker] Merge conflict detected during fetch.", func_name=func_name ) results_queue.put( { "status": "error", "exception": e, "message": f"Error fetching from bundle: {type(e).__name__}", "conflict": is_conflict, # Flag per gestione specifica errore "repo_path": target_repo_path_str, # Passa path per messaggio conflitto } ) finally: log_handler.log_debug("[Worker] Finished: Fetch Bundle", func_name=func_name) def run_manual_backup_async( backup_handler: BackupHandler, repo_path: str, backup_base_dir: str, profile_name: str, excluded_extensions: set, excluded_dirs: set, results_queue: queue.Queue, ): """Worker to create manual backup asynchronously.""" func_name = "run_manual_backup_async" log_handler.log_debug( f"[Worker] Started: Manual Backup for '{repo_path}' (Profile: {profile_name})", func_name=func_name, ) try: # Chiama il metodo corretto in BackupHandler result_path = backup_handler.create_zip_backup( source_repo_path=repo_path, backup_base_dir=backup_base_dir, profile_name=profile_name, excluded_extensions=excluded_extensions, excluded_dirs_base=excluded_dirs, ) # Messaggio successo ts = datetime.datetime.now().strftime("%H:%M:%S") if result_path: message = f"Manual backup created: {os.path.basename(result_path)} ({ts})." else: message = ( f"Manual backup finished (no file generated - empty/excluded?) ({ts})." ) log_handler.log_info(f"[Worker] {message}", func_name=func_name) results_queue.put( {"status": "success", "result": result_path, "message": message} ) except (IOError, ValueError, PermissionError, Exception) as e: log_handler.log_exception( f"[Worker] EXCEPTION creating manual backup: {e}", func_name=func_name ) results_queue.put( { "status": "error", "exception": e, "message": f"Error creating backup: {type(e).__name__}", } ) finally: log_handler.log_debug("[Worker] Finished: Manual Backup", func_name=func_name) def run_commit_async( action_handler: ActionHandler, repo_path: str, commit_message: str, results_queue: queue.Queue, ): """Worker to perform manual commit asynchronously.""" func_name = "run_commit_async" log_handler.log_debug( f"[Worker] Started: Commit for '{repo_path}'", func_name=func_name ) try: # Chiama il metodo corretto in ActionHandler committed = action_handler.execute_manual_commit(repo_path, commit_message) # Messaggio basato sull'esito if committed: message = "Commit successful." else: message = "Commit finished (no changes detected)." log_handler.log_info(f"[Worker] {message}", func_name=func_name) results_queue.put( { "status": "success", "result": committed, "message": message, "committed": committed, # Flag esplicito se commit avvenuto } ) except (GitCommandError, ValueError, Exception) as e: log_handler.log_exception( f"[Worker] EXCEPTION committing: {e}", func_name=func_name ) results_queue.put( { "status": "error", "exception": e, "message": f"Error committing changes: {type(e).__name__}", } ) finally: log_handler.log_debug("[Worker] Finished: Commit", func_name=func_name) def run_untrack_async( action_handler: ActionHandler, repo_path: str, results_queue: queue.Queue ): """Worker to untrack files based on .gitignore asynchronously.""" func_name = "run_untrack_async" log_handler.log_debug( f"[Worker] Started: Untrack Files Check for '{repo_path}'", func_name=func_name ) try: # Chiama il metodo corretto in ActionHandler committed = action_handler.execute_untrack_files_from_gitignore(repo_path) # Messaggio basato sull'esito if committed: message = "Untracking complete: Automatic commit created." else: message = "Untrack check complete (no tracked files matched .gitignore)." log_handler.log_info(f"[Worker] {message}", func_name=func_name) results_queue.put( { "status": "success", "result": committed, "message": message, "committed": committed, # Flag se commit avvenuto } ) except (GitCommandError, ValueError, Exception) as e: log_handler.log_exception( f"[Worker] EXCEPTION untracking files: {e}", func_name=func_name ) results_queue.put( { "status": "error", "exception": e, "message": f"Error during untracking operation: {type(e).__name__}", } ) finally: log_handler.log_debug( "[Worker] Finished: Untrack Files Check", func_name=func_name ) def run_add_file_async( git_commands: GitCommands, repo_path: str, relative_path: str, results_queue: queue.Queue, ): """Worker to add a file to staging asynchronously.""" func_name = "run_add_file_async" log_handler.log_debug( f"[Worker] Started: Add File '{relative_path}' in '{repo_path}'", func_name=func_name, ) try: # Chiama il metodo corretto in GitCommands success = git_commands.add_file(repo_path, relative_path) message = f"File '{os.path.basename(relative_path)}' added to staging area." log_handler.log_info(f"[Worker] {message}", func_name=func_name) results_queue.put({"status": "success", "result": success, "message": message}) except (GitCommandError, ValueError, Exception) as e: log_handler.log_exception( f"[Worker] EXCEPTION adding file: {e}", func_name=func_name ) results_queue.put( { "status": "error", "exception": e, "message": f"Error adding file '{os.path.basename(relative_path)}': {type(e).__name__}", } ) finally: log_handler.log_debug( f"[Worker] Finished: Add File '{relative_path}'", func_name=func_name ) def run_create_tag_async( action_handler: ActionHandler, repo_path: str, tag_name: str, tag_message: str, results_queue: queue.Queue, ): """Worker to create an annotated tag asynchronously.""" func_name = "run_create_tag_async" log_handler.log_debug( f"[Worker] Started: Create Tag '{tag_name}' in '{repo_path}'", func_name=func_name, ) try: # Chiama il metodo corretto in ActionHandler (passa None per arg 'ignored') success = action_handler.execute_create_tag( repo_path, None, tag_name, tag_message ) message = f"Tag '{tag_name}' created successfully." log_handler.log_info(f"[Worker] {message}", func_name=func_name) results_queue.put( { "status": "success", "result": success, "message": message, "committed": True, # Tag annotato implica commit } ) except (GitCommandError, ValueError, Exception) as e: log_handler.log_exception( f"[Worker] EXCEPTION creating tag: {e}", func_name=func_name ) results_queue.put( { "status": "error", "exception": e, "message": f"Error creating tag '{tag_name}': {type(e).__name__}", } ) finally: log_handler.log_debug( f"[Worker] Finished: Create Tag '{tag_name}'", func_name=func_name ) def run_checkout_tag_async( action_handler: ActionHandler, repo_path: str, tag_name: str, results_queue: queue.Queue, ): """Worker to checkout a tag asynchronously.""" func_name = "run_checkout_tag_async" log_handler.log_debug( f"[Worker] Started: Checkout Tag '{tag_name}' in '{repo_path}'", func_name=func_name, ) try: # Chiama il metodo corretto in ActionHandler success = action_handler.execute_checkout_tag(repo_path, tag_name) message = f"Checked out tag '{tag_name}' (Detached HEAD)." log_handler.log_info(f"[Worker] {message}", func_name=func_name) results_queue.put({"status": "success", "result": success, "message": message}) except (ValueError, GitCommandError, Exception) as e: # Cattura ValueError specificamente per 'uncommitted changes' log_handler.log_exception( f"[Worker] EXCEPTION checking out tag: {e}", func_name=func_name ) if isinstance(e, ValueError) and "Uncommitted changes" in str(e): msg = f"Checkout failed: Uncommitted changes exist." else: msg = f"Error checking out tag '{tag_name}': {type(e).__name__}" results_queue.put({"status": "error", "exception": e, "message": msg}) finally: log_handler.log_debug( f"[Worker] Finished: Checkout Tag '{tag_name}'", func_name=func_name ) def run_create_branch_async( action_handler: ActionHandler, repo_path: str, branch_name: str, results_queue: queue.Queue, ): """Worker to create a branch asynchronously.""" func_name = "run_create_branch_async" log_handler.log_debug( f"[Worker] Started: Create Branch '{branch_name}' in '{repo_path}'", func_name=func_name, ) try: # Chiama il metodo corretto in ActionHandler success = action_handler.execute_create_branch(repo_path, branch_name) message = f"Branch '{branch_name}' created successfully." log_handler.log_info(f"[Worker] {message}", func_name=func_name) results_queue.put({"status": "success", "result": success, "message": message}) except (GitCommandError, ValueError, Exception) as e: log_handler.log_exception( f"[Worker] EXCEPTION creating branch: {e}", func_name=func_name ) results_queue.put( { "status": "error", "exception": e, "message": f"Error creating branch '{branch_name}': {type(e).__name__}", } ) finally: log_handler.log_debug( f"[Worker] Finished: Create Branch '{branch_name}'", func_name=func_name ) def run_checkout_branch_async( action_handler: ActionHandler, repo_path: str, branch_name: str, results_queue: queue.Queue, ): """Worker to checkout a branch asynchronously.""" func_name = "run_checkout_branch_async" log_handler.log_debug( f"[Worker] Started: Checkout Branch '{branch_name}' in '{repo_path}'", func_name=func_name, ) try: # Chiama il metodo corretto in ActionHandler success = action_handler.execute_switch_branch(repo_path, branch_name) message = f"Switched to branch '{branch_name}'." log_handler.log_info(f"[Worker] {message}", func_name=func_name) results_queue.put({"status": "success", "result": success, "message": message}) except (ValueError, GitCommandError, Exception) as e: # Cattura ValueError per 'uncommitted changes' log_handler.log_exception( f"[Worker] EXCEPTION checking out branch: {e}", func_name=func_name ) if isinstance(e, ValueError) and "Uncommitted changes" in str(e): msg = f"Checkout failed: Uncommitted changes exist." else: msg = f"Error checking out branch '{branch_name}': {type(e).__name__}" results_queue.put({"status": "error", "exception": e, "message": msg}) finally: log_handler.log_debug( f"[Worker] Finished: Checkout Branch '{branch_name}'", func_name=func_name ) # === Worker per Azioni Remote (Nuove) === def run_apply_remote_config_async( remote_action_handler: RemoteActionHandler, repo_path: str, remote_name: str, remote_url: str, results_queue: queue.Queue ): # (Implementazione precedente invariata) func_name = "run_apply_remote_config_async" log_handler.log_debug(f"[Worker] Started: Apply Remote Config for '{remote_name}' in '{repo_path}'", func_name=func_name) try: success = remote_action_handler.apply_remote_config(repo_path, remote_name, remote_url) message = f"Remote '{remote_name}' configuration applied successfully." log_handler.log_info(f"[Worker] {message}", func_name=func_name) results_queue.put({"status": "success", "result": success, "message": message}) except (GitCommandError, ValueError) as e: log_handler.log_error(f"[Worker] EXCEPTION applying remote config: {e}", func_name=func_name) results_queue.put({"status": "error", "exception": e, "message": f"Error applying remote config: {e}"}) except Exception as e: log_handler.log_exception(f"[Worker] UNEXPECTED EXCEPTION applying remote config: {e}", func_name=func_name) results_queue.put({"status": "error", "exception": e, "message": f"Unexpected error applying remote config: {type(e).__name__}"}) finally: log_handler.log_debug(f"[Worker] Finished: Apply Remote Config for '{remote_name}'", func_name=func_name) def run_check_connection_async( git_commands: GitCommands, repo_path: str, remote_name: str, results_queue: queue.Queue ): """ Worker to check remote connection and potential auth issues using 'git ls-remote'. Does NOT prompt for credentials. """ func_name = "run_check_connection_async" log_handler.log_debug(f"[Worker] Started: Check Connection/Auth for '{remote_name}' in '{repo_path}'", func_name=func_name) try: # Esegui ls-remote catturando output, senza check=True result = git_commands.git_ls_remote(repo_path, remote_name) # Analizza il risultato if result.returncode == 0: # Successo: connessione e autenticazione (se necessaria) OK message = f"Connection to remote '{remote_name}' successful." log_handler.log_info(f"[Worker] {message}", func_name=func_name) results_queue.put( {"status": "success", "result": "connected", "message": message} ) elif result.returncode == 2: # RC=2: Connesso con successo, ma il remote è vuoto (no refs) o "unborn" # Lo trattiamo come connessione/auth OK, ma potremmo segnalarlo message = f"Connected to remote '{remote_name}' (Note: Repository might be empty or unborn)." log_handler.log_info(f"[Worker] {message}", func_name=func_name) # Manda 'success' così l'indicatore diventa verde results_queue.put( {"status": "success", "result": "connected_empty", "message": message} ) else: # Errore: analizza stderr per capire la causa stderr_lower = result.stderr.lower() if result.stderr else "" log_handler.log_warning(f"[Worker] ls-remote failed (RC={result.returncode}). Stderr: {stderr_lower}", func_name=func_name) # Controlla errori comuni di autenticazione/permessi auth_errors = ["authentication failed", "permission denied", "could not read username", "fatal: could not read password"] connection_errors = ["repository not found", "could not resolve host", "name or service not known", "network is unreachable"] if any(err in stderr_lower for err in auth_errors): message = f"Authentication required or failed for remote '{remote_name}'." log_handler.log_warning(f"[Worker] {message}", func_name=func_name) results_queue.put( # Stato speciale per triggerare il prompt interattivo {"status": "auth_required", "result": "authentication needed", "message": message, "exception": GitCommandError(message, stderr=result.stderr)} ) elif any(err in stderr_lower for err in connection_errors): message = f"Failed to connect to remote '{remote_name}': Repository or host not found/reachable." log_handler.log_error(f"[Worker] {message}", func_name=func_name) results_queue.put( {"status": "error", "result": "connection_failed", "message": message, "exception": GitCommandError(message, stderr=result.stderr)} ) else: # Errore generico di Git message = f"Failed to check remote '{remote_name}'. Check logs for details." log_handler.log_error(f"[Worker] Unknown error checking remote. Stderr: {result.stderr}", func_name=func_name) results_queue.put( {"status": "error", "result": "unknown_error", "message": message, "exception": GitCommandError(message, stderr=result.stderr)} ) except Exception as e: # Errore imprevisto nell'esecuzione del worker stesso log_handler.log_exception(f"[Worker] UNEXPECTED EXCEPTION checking connection: {e}", func_name=func_name) results_queue.put( { "status": "error", "exception": e, "result": "worker_exception", "message": f"Unexpected error checking connection: {type(e).__name__}", } ) finally: log_handler.log_debug(f"[Worker] Finished: Check Connection/Auth for '{remote_name}'", func_name=func_name) def run_interactive_auth_attempt_async( git_commands: GitCommands, repo_path: str, remote_name: str, results_queue: queue.Queue ): """ Worker to attempt an interactive Git operation (fetch) to trigger credential prompts. This worker intentionally does NOT capture output or hide the console. """ func_name = "run_interactive_auth_attempt_async" log_handler.log_info(f"[Worker] Started: Interactive Auth Attempt for '{remote_name}' via Fetch in '{repo_path}'", func_name=func_name) try: # Esegui git fetch in modalità interattiva (no capture, no hide) result = git_commands.git_fetch_interactive(repo_path, remote_name) # Controlla solo il codice di ritorno if result.returncode == 0: # Successo (presumibilmente l'utente ha autenticato) message = f"Interactive authentication attempt for '{remote_name}' seems successful." log_handler.log_info(f"[Worker] {message}", func_name=func_name) results_queue.put( {"status": "success", "result": "auth_attempt_success", "message": message} ) else: # Fallimento (utente ha annullato, credenziali errate, altro errore) message = f"Interactive authentication attempt for '{remote_name}' failed or was cancelled (RC={result.returncode})." log_handler.log_warning(f"[Worker] {message}", func_name=func_name) results_queue.put( {"status": "error", "result": "auth_attempt_failed", "message": message, "exception": GitCommandError(message, stderr=None)} # Non abbiamo stderr qui ) except Exception as e: # Errore imprevisto nell'esecuzione del worker log_handler.log_exception(f"[Worker] UNEXPECTED EXCEPTION during interactive auth attempt: {e}", func_name=func_name) results_queue.put( { "status": "error", "exception": e, "result": "worker_exception", "message": f"Unexpected error during interactive auth: {type(e).__name__}", } ) finally: log_handler.log_debug(f"[Worker] Finished: Interactive Auth Attempt for '{remote_name}'", func_name=func_name) # --- Placeholder per future funzioni worker remote --- # def run_fetch_remote_async(remote_action_handler, repo_path, remote_name, results_queue): pass # def run_pull_remote_async(remote_action_handler, repo_path, remote_name, branch_name, results_queue): pass # def run_push_remote_async(remote_action_handler, repo_path, remote_name, branch_name, results_queue): pass # def run_push_tags_async(remote_action_handler, repo_path, remote_name, results_queue): pass # --- END OF FILE async_workers.py ---