diff --git a/gui/__main__.py b/gui/__main__.py index 8520046..6a0b418 100755 --- a/gui/__main__.py +++ b/gui/__main__.py @@ -15,6 +15,9 @@ import qrcode from io import BytesIO from typing import Union from core.Errors import UnknownConnectionTypeError, CommandNotFoundError, MissingSubscriptionError, InvalidSubscriptionError, ProfileActivationError, UnsupportedApplicationVersionError, FileIntegrityError, ProfileModificationError, ProfileStateConflictError, EndpointVerificationError, PolicyAssignmentError, PolicyInstatementError, PolicyRevocationError +from core.errors.logger import logger as core_logger + +core_logger.propagate = False from core.controllers.ApplicationVersionController import ApplicationVersionController from core.controllers.ApplicationController import ApplicationController from core.controllers.ClientController import ClientController @@ -615,7 +618,7 @@ class CustomWindow(QMainWindow): self.is_tor_mode = current_connection == 'tor' self.set_toggle_state(self.is_tor_mode) - logging.info( + core_logger.info( f"HydraVeil application opened (client version {Constants.HV_CLIENT_VERSION_NUMBER}, " f"connection={current_connection}, tor_mode={self.is_tor_mode})" ) @@ -646,7 +649,7 @@ class CustomWindow(QMainWindow): self.update_status('Sync failed. Please try again later.') def sync(self): - logging.info("User clicked sync button") + core_logger.info("User clicked sync button") if ConfigurationController.get_connection() == 'tor': self.worker_thread = WorkerThread('SYNC_TOR') else: @@ -732,14 +735,14 @@ class CustomWindow(QMainWindow): ConfigurationController.set_connection('system') self.is_tor_mode = False self.set_toggle_state(False) - logging.info("User selected 'Regular' connection type from popup") + core_logger.info("User selected 'Regular' connection type from popup") connection_dialog.accept() def set_tor_connection(): ConfigurationController.set_connection('tor') self.is_tor_mode = True self.set_toggle_state(True) - logging.info("User selected 'Tor' connection type from popup") + core_logger.info("User selected 'Tor' connection type from popup") connection_dialog.accept() regular_btn.clicked.connect(set_regular_connection) @@ -855,6 +858,13 @@ class CustomWindow(QMainWindow): self._save_gui_config(config) def stop_gui_logging(self): + for handler in getattr(self, '_gui_log_handlers', []): + try: + core_logger.removeHandler(handler) + except Exception: + pass + self._gui_log_handlers = [] + logger = logging.getLogger() for handler in list(logger.handlers): logger.removeHandler(handler) @@ -893,6 +903,15 @@ class CustomWindow(QMainWindow): logger.addHandler(file_handler) logger.addHandler(stream_handler) + for handler in getattr(self, '_gui_log_handlers', []): + try: + core_logger.removeHandler(handler) + except Exception: + pass + core_logger.addHandler(file_handler) + core_logger.addHandler(stream_handler) + self._gui_log_handlers = [file_handler, stream_handler] + if not os.path.exists(self.gui_log_file) or os.path.getsize(self.gui_log_file) == 0: logging.info("GUI logging system initialized") @@ -983,7 +1002,7 @@ class CustomWindow(QMainWindow): self.is_tor_mode = not self.is_tor_mode new_connection = 'tor' if self.is_tor_mode else 'system' ConfigurationController.set_connection(new_connection) - logging.info(f"User toggled connection mode to '{new_connection}'") + core_logger.info(f"User toggled connection mode to '{new_connection}'") def animate_toggle(self): TOTAL_STEPS = 5 @@ -1071,7 +1090,7 @@ class CustomWindow(QMainWindow): self.setWindowIcon(window_icon) def closeEvent(self, event=None): - logging.info("HydraVeil application closing") + core_logger.info("HydraVeil application closing") connected_profiles = self.connection_manager.get_connected_profiles() if connected_profiles: self._show_disconnect_confirmation(connected_profiles, event) @@ -7998,54 +8017,54 @@ class Settings(Page): self.show_account_page() def show_account_page(self): - logging.info("User navigated to Settings -> Overview") + core_logger.info("User navigated to Settings -> Overview") self.content_layout.setCurrentWidget(self.account_page) self._select_menu_button("Overview") def show_subscription_page(self): - logging.info("User navigated to Settings -> Subscriptions") + core_logger.info("User navigated to Settings -> Subscriptions") self.content_layout.setCurrentWidget(self.subscription_page) self._select_menu_button("Subscriptions") def show_tickets_page(self): - logging.info("User navigated to Settings -> Tickets") + core_logger.info("User navigated to Settings -> Tickets") self.content_layout.setCurrentWidget(self.tickets_page) self._select_menu_button("Tickets") self._refresh_tickets_inventory() self._refresh_ticket_recovery_controls() def show_registrations_page(self): - logging.info("User navigated to Settings -> Create/Edit") + core_logger.info("User navigated to Settings -> Create/Edit") self.content_layout.setCurrentWidget(self.registrations_page) self._select_menu_button("Create/Edit") def show_verification_page(self): - logging.info("User navigated to Settings -> Verification") + core_logger.info("User navigated to Settings -> Verification") self.content_layout.setCurrentWidget(self.verification_page) self._select_menu_button("Verification") def show_systemwide_page(self): - logging.info("User navigated to Settings -> Legacy-Version") + core_logger.info("User navigated to Settings -> Legacy-Version") self.content_layout.setCurrentWidget(self.systemwide_page) self._select_menu_button("Systemwide") def show_bwrap_page(self): - logging.info("User navigated to Settings -> Bwrap Permission") + core_logger.info("User navigated to Settings -> Bwrap Permission") self.content_layout.setCurrentWidget(self.bwrap_page) self._select_menu_button("Bwrap Permission") def show_logs_page(self): - logging.info("User navigated to Settings -> Error Logs") + core_logger.info("User navigated to Settings -> Error Logs") self.content_layout.setCurrentWidget(self.logs_page) self._select_menu_button("Error Logs") def show_delete_page(self): - logging.info("User navigated to Settings -> Delete Profile") + core_logger.info("User navigated to Settings -> Delete Profile") self.content_layout.setCurrentWidget(self.delete_page) self._select_menu_button("Delete Profile") def show_debug_page(self): - logging.info("User navigated to Settings -> Debug Help") + core_logger.info("User navigated to Settings -> Debug Help") self.content_layout.setCurrentWidget(self.debug_page) self._select_menu_button("Debug Help") @@ -8238,7 +8257,7 @@ class Settings(Page): return failure def evaluate_ticket_public_key(self): - logging.info("User clicked 'Evaluate Public Key' button") + core_logger.info("User clicked 'Evaluate Public Key' button") failure = self._get_ticket_failure_for_action() if failure is None: return @@ -8258,13 +8277,13 @@ class Settings(Page): def on_failed_verification_evaluated(self, result): message = interpret_key_results(result) self._write_ticket_recovery_output(message) - logging.info(f"Public key evaluation result: {message}") + core_logger.info(f"Public key evaluation result: {message}") self.update_status.update_status("Ticket public key evaluation complete.") self._set_ticket_recovery_busy(False) self._refresh_ticket_recovery_controls() def prepare_tickets_with_saved_blind_signatures(self): - logging.info("User clicked 'Prepare Tickets even if validation of the server's signature failed' button") + core_logger.info("User clicked 'Prepare Tickets even if validation of the server's signature failed' button") failure = self._get_ticket_failure_for_action() if failure is None: return @@ -8301,32 +8320,32 @@ class Settings(Page): self._refresh_ticket_recovery_controls() def on_ticket_recovery_error(self, msg): - logging.error(f"Ticket recovery error: {msg}") + core_logger.error(f"Ticket recovery error: {msg}") self._write_ticket_recovery_output(f"EXCEPTION: {msg}") self.update_status.update_status(f"Ticket recovery error: {msg}") self._set_ticket_recovery_busy(False) self._refresh_ticket_recovery_controls() def _on_random_toggle(self, checked): - logging.info(f"User toggled random ticket setting to {'on' if checked else 'off'}") + core_logger.info(f"User toggled random ticket setting to {'on' if checked else 'off'}") try: result = modify_random_tickets_setting('on' if checked else 'off', ticket_observer) if not (isinstance(result, dict) and result.get('valid')): msg = result.get('message', 'failed') if isinstance(result, dict) else 'failed' - logging.error(f"Could not change random ticket setting: {msg}") + core_logger.error(f"Could not change random ticket setting: {msg}") self.update_status.update_status(f'Could not change setting: {msg}') except Exception as e: - logging.error(f"Exception changing random ticket setting: {e}") + core_logger.error(f"Exception changing random ticket setting: {e}") self.update_status.update_status(f'Could not change setting: {e}') def _refresh_tickets_inventory(self): if not hasattr(self, 'tickets_inventory_label'): return - logging.info("Refreshing tickets inventory") + core_logger.info("Refreshing tickets inventory") try: unused = get_unused_tickets(ticket_observer) except Exception as e: - logging.error(f"Error fetching unused tickets: {e}") + core_logger.error(f"Error fetching unused tickets: {e}") self.tickets_inventory_label.setText(f"Error: {e}") return if isinstance(unused, dict) and unused.get('valid'): @@ -8409,9 +8428,9 @@ class Settings(Page): if self.enable_gui_logging.isChecked(): self.update_status._setup_gui_logging() - logging.info("User enabled GUI logging") + core_logger.info("User enabled GUI logging") else: - logging.info("User disabled GUI logging") + core_logger.info("User disabled GUI logging") self.update_status.stop_gui_logging() self.update_status.update_status(