update: new error log flow
This commit is contained in:
parent
22c2652c48
commit
0a3a6ecd2f
1 changed files with 80 additions and 3 deletions
|
|
@ -63,6 +63,38 @@ profile_observer = ProfileObserver()
|
||||||
ticket_observer = TicketObserver()
|
ticket_observer = TicketObserver()
|
||||||
|
|
||||||
|
|
||||||
|
def interpret_key_results(result: dict) -> str:
|
||||||
|
if not isinstance(result, dict):
|
||||||
|
return "There was an error with the format of the reply from the operation."
|
||||||
|
|
||||||
|
valid = result.get('valid', False)
|
||||||
|
comparison = result.get('comparison', 'error')
|
||||||
|
error_msg = result.get('message', None)
|
||||||
|
|
||||||
|
if error_msg:
|
||||||
|
if error_msg == "api_connection_issue":
|
||||||
|
return "There was a connection error with connecting to the API."
|
||||||
|
elif error_msg == "invalid_key":
|
||||||
|
return "Your original public key is in an invalid format to begin with."
|
||||||
|
else:
|
||||||
|
return "Unknown Error."
|
||||||
|
|
||||||
|
if comparison == "same":
|
||||||
|
first_sentence = "The key you had locally matched what the server had also."
|
||||||
|
elif comparison == "different":
|
||||||
|
first_sentence = "Your local key was different than the server's key."
|
||||||
|
else:
|
||||||
|
first_sentence = "There was an error with the comparison."
|
||||||
|
|
||||||
|
if valid:
|
||||||
|
second_sentence = "The signature now matches with the new key."
|
||||||
|
else:
|
||||||
|
second_sentence = "But the signature still does not match, even with the new key. If you prepare tickets anyway, they might not verify when used."
|
||||||
|
|
||||||
|
final_msg = first_sentence + " " + second_sentence
|
||||||
|
return final_msg
|
||||||
|
|
||||||
|
|
||||||
class TerminalWidget(QPlainTextEdit):
|
class TerminalWidget(QPlainTextEdit):
|
||||||
line_appended = pyqtSignal(str)
|
line_appended = pyqtSignal(str)
|
||||||
|
|
||||||
|
|
@ -583,6 +615,11 @@ class CustomWindow(QMainWindow):
|
||||||
self.is_tor_mode = current_connection == 'tor'
|
self.is_tor_mode = current_connection == 'tor'
|
||||||
self.set_toggle_state(self.is_tor_mode)
|
self.set_toggle_state(self.is_tor_mode)
|
||||||
|
|
||||||
|
logging.info(
|
||||||
|
f"HydraVeil application opened (client version {Constants.HV_CLIENT_VERSION_NUMBER}, "
|
||||||
|
f"connection={current_connection}, tor_mode={self.is_tor_mode})"
|
||||||
|
)
|
||||||
|
|
||||||
def perform_update_check(self):
|
def perform_update_check(self):
|
||||||
|
|
||||||
update_available = ClientController.can_be_updated()
|
update_available = ClientController.can_be_updated()
|
||||||
|
|
@ -609,6 +646,7 @@ class CustomWindow(QMainWindow):
|
||||||
self.update_status('Sync failed. Please try again later.')
|
self.update_status('Sync failed. Please try again later.')
|
||||||
|
|
||||||
def sync(self):
|
def sync(self):
|
||||||
|
logging.info("User clicked sync button")
|
||||||
if ConfigurationController.get_connection() == 'tor':
|
if ConfigurationController.get_connection() == 'tor':
|
||||||
self.worker_thread = WorkerThread('SYNC_TOR')
|
self.worker_thread = WorkerThread('SYNC_TOR')
|
||||||
else:
|
else:
|
||||||
|
|
@ -694,12 +732,14 @@ class CustomWindow(QMainWindow):
|
||||||
ConfigurationController.set_connection('system')
|
ConfigurationController.set_connection('system')
|
||||||
self.is_tor_mode = False
|
self.is_tor_mode = False
|
||||||
self.set_toggle_state(False)
|
self.set_toggle_state(False)
|
||||||
|
logging.info("User selected 'Regular' connection type from popup")
|
||||||
connection_dialog.accept()
|
connection_dialog.accept()
|
||||||
|
|
||||||
def set_tor_connection():
|
def set_tor_connection():
|
||||||
ConfigurationController.set_connection('tor')
|
ConfigurationController.set_connection('tor')
|
||||||
self.is_tor_mode = True
|
self.is_tor_mode = True
|
||||||
self.set_toggle_state(True)
|
self.set_toggle_state(True)
|
||||||
|
logging.info("User selected 'Tor' connection type from popup")
|
||||||
connection_dialog.accept()
|
connection_dialog.accept()
|
||||||
|
|
||||||
regular_btn.clicked.connect(set_regular_connection)
|
regular_btn.clicked.connect(set_regular_connection)
|
||||||
|
|
@ -815,6 +855,14 @@ class CustomWindow(QMainWindow):
|
||||||
self._save_gui_config(config)
|
self._save_gui_config(config)
|
||||||
|
|
||||||
def stop_gui_logging(self):
|
def stop_gui_logging(self):
|
||||||
|
logger = logging.getLogger()
|
||||||
|
for handler in list(logger.handlers):
|
||||||
|
logger.removeHandler(handler)
|
||||||
|
try:
|
||||||
|
handler.close()
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
if os.path.exists(self.gui_log_file):
|
if os.path.exists(self.gui_log_file):
|
||||||
os.remove(self.gui_log_file)
|
os.remove(self.gui_log_file)
|
||||||
|
|
||||||
|
|
@ -835,10 +883,15 @@ class CustomWindow(QMainWindow):
|
||||||
file_handler.setLevel(logging.INFO)
|
file_handler.setLevel(logging.INFO)
|
||||||
file_handler.setFormatter(formatter)
|
file_handler.setFormatter(formatter)
|
||||||
|
|
||||||
|
stream_handler = logging.StreamHandler(sys.stdout)
|
||||||
|
stream_handler.setLevel(logging.INFO)
|
||||||
|
stream_handler.setFormatter(formatter)
|
||||||
|
|
||||||
logger = logging.getLogger()
|
logger = logging.getLogger()
|
||||||
logger.setLevel(logging.INFO)
|
logger.setLevel(logging.INFO)
|
||||||
logger.handlers = []
|
logger.handlers = []
|
||||||
logger.addHandler(file_handler)
|
logger.addHandler(file_handler)
|
||||||
|
logger.addHandler(stream_handler)
|
||||||
|
|
||||||
if not os.path.exists(self.gui_log_file) or os.path.getsize(self.gui_log_file) == 0:
|
if not os.path.exists(self.gui_log_file) or os.path.getsize(self.gui_log_file) == 0:
|
||||||
logging.info("GUI logging system initialized")
|
logging.info("GUI logging system initialized")
|
||||||
|
|
@ -928,8 +981,9 @@ class CustomWindow(QMainWindow):
|
||||||
self.animation_step = 0
|
self.animation_step = 0
|
||||||
self.animation_timer.start(16)
|
self.animation_timer.start(16)
|
||||||
self.is_tor_mode = not self.is_tor_mode
|
self.is_tor_mode = not self.is_tor_mode
|
||||||
ConfigurationController.set_connection(
|
new_connection = 'tor' if self.is_tor_mode else 'system'
|
||||||
'tor' if self.is_tor_mode else 'system')
|
ConfigurationController.set_connection(new_connection)
|
||||||
|
logging.info(f"User toggled connection mode to '{new_connection}'")
|
||||||
|
|
||||||
def animate_toggle(self):
|
def animate_toggle(self):
|
||||||
TOTAL_STEPS = 5
|
TOTAL_STEPS = 5
|
||||||
|
|
@ -1017,6 +1071,7 @@ class CustomWindow(QMainWindow):
|
||||||
self.setWindowIcon(window_icon)
|
self.setWindowIcon(window_icon)
|
||||||
|
|
||||||
def closeEvent(self, event=None):
|
def closeEvent(self, event=None):
|
||||||
|
logging.info("HydraVeil application closing")
|
||||||
connected_profiles = self.connection_manager.get_connected_profiles()
|
connected_profiles = self.connection_manager.get_connected_profiles()
|
||||||
if connected_profiles:
|
if connected_profiles:
|
||||||
self._show_disconnect_confirmation(connected_profiles, event)
|
self._show_disconnect_confirmation(connected_profiles, event)
|
||||||
|
|
@ -7943,44 +7998,54 @@ class Settings(Page):
|
||||||
self.show_account_page()
|
self.show_account_page()
|
||||||
|
|
||||||
def show_account_page(self):
|
def show_account_page(self):
|
||||||
|
logging.info("User navigated to Settings -> Overview")
|
||||||
self.content_layout.setCurrentWidget(self.account_page)
|
self.content_layout.setCurrentWidget(self.account_page)
|
||||||
self._select_menu_button("Overview")
|
self._select_menu_button("Overview")
|
||||||
|
|
||||||
def show_subscription_page(self):
|
def show_subscription_page(self):
|
||||||
|
logging.info("User navigated to Settings -> Subscriptions")
|
||||||
self.content_layout.setCurrentWidget(self.subscription_page)
|
self.content_layout.setCurrentWidget(self.subscription_page)
|
||||||
self._select_menu_button("Subscriptions")
|
self._select_menu_button("Subscriptions")
|
||||||
|
|
||||||
def show_tickets_page(self):
|
def show_tickets_page(self):
|
||||||
|
logging.info("User navigated to Settings -> Tickets")
|
||||||
self.content_layout.setCurrentWidget(self.tickets_page)
|
self.content_layout.setCurrentWidget(self.tickets_page)
|
||||||
self._select_menu_button("Tickets")
|
self._select_menu_button("Tickets")
|
||||||
self._refresh_tickets_inventory()
|
self._refresh_tickets_inventory()
|
||||||
self._refresh_ticket_recovery_controls()
|
self._refresh_ticket_recovery_controls()
|
||||||
|
|
||||||
def show_registrations_page(self):
|
def show_registrations_page(self):
|
||||||
|
logging.info("User navigated to Settings -> Create/Edit")
|
||||||
self.content_layout.setCurrentWidget(self.registrations_page)
|
self.content_layout.setCurrentWidget(self.registrations_page)
|
||||||
self._select_menu_button("Create/Edit")
|
self._select_menu_button("Create/Edit")
|
||||||
|
|
||||||
def show_verification_page(self):
|
def show_verification_page(self):
|
||||||
|
logging.info("User navigated to Settings -> Verification")
|
||||||
self.content_layout.setCurrentWidget(self.verification_page)
|
self.content_layout.setCurrentWidget(self.verification_page)
|
||||||
self._select_menu_button("Verification")
|
self._select_menu_button("Verification")
|
||||||
|
|
||||||
def show_systemwide_page(self):
|
def show_systemwide_page(self):
|
||||||
|
logging.info("User navigated to Settings -> Legacy-Version")
|
||||||
self.content_layout.setCurrentWidget(self.systemwide_page)
|
self.content_layout.setCurrentWidget(self.systemwide_page)
|
||||||
self._select_menu_button("Systemwide")
|
self._select_menu_button("Systemwide")
|
||||||
|
|
||||||
def show_bwrap_page(self):
|
def show_bwrap_page(self):
|
||||||
|
logging.info("User navigated to Settings -> Bwrap Permission")
|
||||||
self.content_layout.setCurrentWidget(self.bwrap_page)
|
self.content_layout.setCurrentWidget(self.bwrap_page)
|
||||||
self._select_menu_button("Bwrap Permission")
|
self._select_menu_button("Bwrap Permission")
|
||||||
|
|
||||||
def show_logs_page(self):
|
def show_logs_page(self):
|
||||||
|
logging.info("User navigated to Settings -> Error Logs")
|
||||||
self.content_layout.setCurrentWidget(self.logs_page)
|
self.content_layout.setCurrentWidget(self.logs_page)
|
||||||
self._select_menu_button("Error Logs")
|
self._select_menu_button("Error Logs")
|
||||||
|
|
||||||
def show_delete_page(self):
|
def show_delete_page(self):
|
||||||
|
logging.info("User navigated to Settings -> Delete Profile")
|
||||||
self.content_layout.setCurrentWidget(self.delete_page)
|
self.content_layout.setCurrentWidget(self.delete_page)
|
||||||
self._select_menu_button("Delete Profile")
|
self._select_menu_button("Delete Profile")
|
||||||
|
|
||||||
def show_debug_page(self):
|
def show_debug_page(self):
|
||||||
|
logging.info("User navigated to Settings -> Debug Help")
|
||||||
self.content_layout.setCurrentWidget(self.debug_page)
|
self.content_layout.setCurrentWidget(self.debug_page)
|
||||||
self._select_menu_button("Debug Help")
|
self._select_menu_button("Debug Help")
|
||||||
|
|
||||||
|
|
@ -8173,6 +8238,7 @@ class Settings(Page):
|
||||||
return failure
|
return failure
|
||||||
|
|
||||||
def evaluate_ticket_public_key(self):
|
def evaluate_ticket_public_key(self):
|
||||||
|
logging.info("User clicked 'Evaluate Public Key' button")
|
||||||
failure = self._get_ticket_failure_for_action()
|
failure = self._get_ticket_failure_for_action()
|
||||||
if failure is None:
|
if failure is None:
|
||||||
return
|
return
|
||||||
|
|
@ -8190,12 +8256,15 @@ class Settings(Page):
|
||||||
self.ticket_recovery_worker.start()
|
self.ticket_recovery_worker.start()
|
||||||
|
|
||||||
def on_failed_verification_evaluated(self, result):
|
def on_failed_verification_evaluated(self, result):
|
||||||
self._write_ticket_recovery_output(self._format_ticket_recovery_result("evaluation_results", result))
|
message = interpret_key_results(result)
|
||||||
|
self._write_ticket_recovery_output(message)
|
||||||
|
logging.info(f"Public key evaluation result: {message}")
|
||||||
self.update_status.update_status("Ticket public key evaluation complete.")
|
self.update_status.update_status("Ticket public key evaluation complete.")
|
||||||
self._set_ticket_recovery_busy(False)
|
self._set_ticket_recovery_busy(False)
|
||||||
self._refresh_ticket_recovery_controls()
|
self._refresh_ticket_recovery_controls()
|
||||||
|
|
||||||
def prepare_tickets_with_saved_blind_signatures(self):
|
def prepare_tickets_with_saved_blind_signatures(self):
|
||||||
|
logging.info("User clicked 'Prepare Tickets even if validation of the server's signature failed' button")
|
||||||
failure = self._get_ticket_failure_for_action()
|
failure = self._get_ticket_failure_for_action()
|
||||||
if failure is None:
|
if failure is None:
|
||||||
return
|
return
|
||||||
|
|
@ -8232,26 +8301,32 @@ class Settings(Page):
|
||||||
self._refresh_ticket_recovery_controls()
|
self._refresh_ticket_recovery_controls()
|
||||||
|
|
||||||
def on_ticket_recovery_error(self, msg):
|
def on_ticket_recovery_error(self, msg):
|
||||||
|
logging.error(f"Ticket recovery error: {msg}")
|
||||||
self._write_ticket_recovery_output(f"EXCEPTION: {msg}")
|
self._write_ticket_recovery_output(f"EXCEPTION: {msg}")
|
||||||
self.update_status.update_status(f"Ticket recovery error: {msg}")
|
self.update_status.update_status(f"Ticket recovery error: {msg}")
|
||||||
self._set_ticket_recovery_busy(False)
|
self._set_ticket_recovery_busy(False)
|
||||||
self._refresh_ticket_recovery_controls()
|
self._refresh_ticket_recovery_controls()
|
||||||
|
|
||||||
def _on_random_toggle(self, checked):
|
def _on_random_toggle(self, checked):
|
||||||
|
logging.info(f"User toggled random ticket setting to {'on' if checked else 'off'}")
|
||||||
try:
|
try:
|
||||||
result = modify_random_tickets_setting('on' if checked else 'off', ticket_observer)
|
result = modify_random_tickets_setting('on' if checked else 'off', ticket_observer)
|
||||||
if not (isinstance(result, dict) and result.get('valid')):
|
if not (isinstance(result, dict) and result.get('valid')):
|
||||||
msg = result.get('message', 'failed') if isinstance(result, dict) else 'failed'
|
msg = result.get('message', 'failed') if isinstance(result, dict) else 'failed'
|
||||||
|
logging.error(f"Could not change random ticket setting: {msg}")
|
||||||
self.update_status.update_status(f'Could not change setting: {msg}')
|
self.update_status.update_status(f'Could not change setting: {msg}')
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
logging.error(f"Exception changing random ticket setting: {e}")
|
||||||
self.update_status.update_status(f'Could not change setting: {e}')
|
self.update_status.update_status(f'Could not change setting: {e}')
|
||||||
|
|
||||||
def _refresh_tickets_inventory(self):
|
def _refresh_tickets_inventory(self):
|
||||||
if not hasattr(self, 'tickets_inventory_label'):
|
if not hasattr(self, 'tickets_inventory_label'):
|
||||||
return
|
return
|
||||||
|
logging.info("Refreshing tickets inventory")
|
||||||
try:
|
try:
|
||||||
unused = get_unused_tickets(ticket_observer)
|
unused = get_unused_tickets(ticket_observer)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
logging.error(f"Error fetching unused tickets: {e}")
|
||||||
self.tickets_inventory_label.setText(f"Error: {e}")
|
self.tickets_inventory_label.setText(f"Error: {e}")
|
||||||
return
|
return
|
||||||
if isinstance(unused, dict) and unused.get('valid'):
|
if isinstance(unused, dict) and unused.get('valid'):
|
||||||
|
|
@ -8334,7 +8409,9 @@ class Settings(Page):
|
||||||
|
|
||||||
if self.enable_gui_logging.isChecked():
|
if self.enable_gui_logging.isChecked():
|
||||||
self.update_status._setup_gui_logging()
|
self.update_status._setup_gui_logging()
|
||||||
|
logging.info("User enabled GUI logging")
|
||||||
else:
|
else:
|
||||||
|
logging.info("User disabled GUI logging")
|
||||||
self.update_status.stop_gui_logging()
|
self.update_status.stop_gui_logging()
|
||||||
|
|
||||||
self.update_status.update_status(
|
self.update_status.update_status(
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue