update: cli_failed_verification flow
This commit is contained in:
parent
cf817a62d0
commit
2e735c7303
2 changed files with 292 additions and 9 deletions
299
gui/__main__.py
299
gui/__main__.py
|
|
@ -38,6 +38,10 @@ from core.observers.TicketObserver import TicketObserver
|
||||||
from core.controllers.tickets.TicketSyncController import sync_ticket_prices
|
from core.controllers.tickets.TicketSyncController import sync_ticket_prices
|
||||||
from core.controllers.tickets.TicketPayController import initiate_payment, check_if_paid
|
from core.controllers.tickets.TicketPayController import initiate_payment, check_if_paid
|
||||||
from core.controllers.tickets.TicketPrepController import prepare_tickets
|
from core.controllers.tickets.TicketPrepController import prepare_tickets
|
||||||
|
from core.controllers.tickets.FailedVerificationController import (
|
||||||
|
evaluate_if_its_the_key,
|
||||||
|
prepare_tickets_with_saved_blind_sigs,
|
||||||
|
)
|
||||||
from core.controllers.tickets.UseTicketController import (
|
from core.controllers.tickets.UseTicketController import (
|
||||||
use_ticket,
|
use_ticket,
|
||||||
modify_random_tickets_setting,
|
modify_random_tickets_setting,
|
||||||
|
|
@ -733,6 +737,59 @@ class CustomWindow(QMainWindow):
|
||||||
with open(self.gui_config_file, 'w') as f:
|
with open(self.gui_config_file, 'w') as f:
|
||||||
json.dump(config, f, indent=4)
|
json.dump(config, f, indent=4)
|
||||||
|
|
||||||
|
def _default_gui_config(self):
|
||||||
|
return {"logging": {"gui_logging_enabled": False, "log_level": "INFO"}}
|
||||||
|
|
||||||
|
def save_ticket_verification_failure(self, result):
|
||||||
|
try:
|
||||||
|
failed_validations = result.get('failed_validations', []) if isinstance(result, dict) else []
|
||||||
|
if not failed_validations:
|
||||||
|
return False
|
||||||
|
|
||||||
|
config = self._load_gui_config()
|
||||||
|
if config is None:
|
||||||
|
config = self._default_gui_config()
|
||||||
|
if "tickets" not in config:
|
||||||
|
config["tickets"] = {}
|
||||||
|
|
||||||
|
config["tickets"]["failed_verification"] = {
|
||||||
|
"message": result.get('message', 'verification_failed'),
|
||||||
|
"how_many_failed": result.get('how_many_failed', len(failed_validations)),
|
||||||
|
"failed_validations": list(failed_validations),
|
||||||
|
"updated_at": datetime.now(timezone.utc).isoformat(),
|
||||||
|
}
|
||||||
|
self._save_gui_config(config)
|
||||||
|
return True
|
||||||
|
except Exception as e:
|
||||||
|
logging.error(f"Error saving ticket verification failure: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
def get_ticket_verification_failure(self):
|
||||||
|
try:
|
||||||
|
config = self._load_gui_config()
|
||||||
|
if not config:
|
||||||
|
return None
|
||||||
|
failure = config.get("tickets", {}).get("failed_verification")
|
||||||
|
if not isinstance(failure, dict):
|
||||||
|
return None
|
||||||
|
failed_validations = failure.get("failed_validations")
|
||||||
|
if not failed_validations:
|
||||||
|
return None
|
||||||
|
return failure
|
||||||
|
except Exception as e:
|
||||||
|
logging.error(f"Error loading ticket verification failure: {e}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
def clear_ticket_verification_failure(self):
|
||||||
|
try:
|
||||||
|
config = self._load_gui_config()
|
||||||
|
if not config or "tickets" not in config:
|
||||||
|
return
|
||||||
|
config["tickets"].pop("failed_verification", None)
|
||||||
|
self._save_gui_config(config)
|
||||||
|
except Exception as e:
|
||||||
|
logging.error(f"Error clearing ticket verification failure: {e}")
|
||||||
|
|
||||||
def check_logging(self):
|
def check_logging(self):
|
||||||
config = self._load_gui_config()
|
config = self._load_gui_config()
|
||||||
if config is None:
|
if config is None:
|
||||||
|
|
@ -1084,18 +1141,25 @@ class CustomWindow(QMainWindow):
|
||||||
def clear_data(self):
|
def clear_data(self):
|
||||||
self._data = {"Profile_1": {}}
|
self._data = {"Profile_1": {}}
|
||||||
|
|
||||||
|
def _set_status_font_size(self, font_size):
|
||||||
|
self.status_label.setStyleSheet(
|
||||||
|
f"color: rgb(0, 255, 255); font-size: {font_size}px;")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def update_status(self, text, clear=False):
|
def update_status(self, text, clear=False):
|
||||||
if text is None:
|
if text is None:
|
||||||
|
self._set_status_font_size(16)
|
||||||
self.status_label.setText('Status:')
|
self.status_label.setText('Status:')
|
||||||
self.disable_marquee()
|
self.disable_marquee()
|
||||||
return
|
return
|
||||||
|
|
||||||
if clear:
|
if clear:
|
||||||
|
self._set_status_font_size(16)
|
||||||
self.status_label.setText('')
|
self.status_label.setText('')
|
||||||
return
|
return
|
||||||
|
|
||||||
full_text = f'Status: {text}'
|
self.status_label.setText('Status: ' + text)
|
||||||
self.status_label.setText(full_text)
|
|
||||||
self.disable_marquee()
|
self.disable_marquee()
|
||||||
|
|
||||||
def check_first_launch(self):
|
def check_first_launch(self):
|
||||||
|
|
@ -7890,6 +7954,7 @@ class Settings(Page):
|
||||||
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()
|
||||||
|
|
||||||
def show_registrations_page(self):
|
def show_registrations_page(self):
|
||||||
self.content_layout.setCurrentWidget(self.registrations_page)
|
self.content_layout.setCurrentWidget(self.registrations_page)
|
||||||
|
|
@ -7928,14 +7993,33 @@ class Settings(Page):
|
||||||
|
|
||||||
def create_tickets_page(self):
|
def create_tickets_page(self):
|
||||||
page = QWidget()
|
page = QWidget()
|
||||||
layout = QVBoxLayout(page)
|
page_layout = QVBoxLayout(page)
|
||||||
layout.setSpacing(15)
|
page_layout.setSpacing(15)
|
||||||
layout.setContentsMargins(20, 20, 20, 20)
|
page_layout.setContentsMargins(20, 20, 20, 20)
|
||||||
|
|
||||||
title = QLabel("TICKETS")
|
title = QLabel("TICKETS")
|
||||||
title.setStyleSheet(
|
title.setStyleSheet(
|
||||||
f"color: #808080; font-size: 12px; font-weight: bold; {self.font_style}")
|
f"color: #808080; font-size: 12px; font-weight: bold; {self.font_style}")
|
||||||
layout.addWidget(title)
|
page_layout.addWidget(title)
|
||||||
|
|
||||||
|
scroll_area = QScrollArea()
|
||||||
|
scroll_area.setWidgetResizable(True)
|
||||||
|
scroll_area.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
|
||||||
|
scroll_area.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAsNeeded)
|
||||||
|
scroll_area.setStyleSheet("""
|
||||||
|
QScrollArea {
|
||||||
|
background-color: transparent;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
QScrollArea > QWidget > QWidget {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
|
||||||
|
scroll_content = QWidget()
|
||||||
|
layout = QVBoxLayout(scroll_content)
|
||||||
|
layout.setSpacing(15)
|
||||||
|
layout.setContentsMargins(0, 0, 8, 0)
|
||||||
|
|
||||||
random_group = QGroupBox("Random Ticket Use")
|
random_group = QGroupBox("Random Ticket Use")
|
||||||
random_group.setStyleSheet(
|
random_group.setStyleSheet(
|
||||||
|
|
@ -7978,9 +8062,181 @@ class Settings(Page):
|
||||||
inventory_layout.addWidget(self.refresh_tickets_button)
|
inventory_layout.addWidget(self.refresh_tickets_button)
|
||||||
layout.addWidget(inventory_group)
|
layout.addWidget(inventory_group)
|
||||||
|
|
||||||
|
saved_failure = self.update_status.get_ticket_verification_failure()
|
||||||
|
has_failure = saved_failure is not None
|
||||||
|
|
||||||
|
recovery_group = QGroupBox("Verification Failure Recovery")
|
||||||
|
recovery_group.setStyleSheet(
|
||||||
|
f"QGroupBox {{ color: white; padding: 15px; {self.font_style} }}")
|
||||||
|
recovery_layout = QVBoxLayout(recovery_group)
|
||||||
|
|
||||||
|
self.ticket_recovery_status_label = QLabel(self._format_ticket_failure_status(saved_failure))
|
||||||
|
self.ticket_recovery_status_label.setStyleSheet(
|
||||||
|
f"color: white; font-size: 12px; {self.font_style}")
|
||||||
|
self.ticket_recovery_status_label.setWordWrap(True)
|
||||||
|
recovery_layout.addWidget(self.ticket_recovery_status_label)
|
||||||
|
|
||||||
|
self.evaluate_public_key_button = QPushButton("Evaluate Public Key")
|
||||||
|
self.evaluate_public_key_button.setFixedSize(180, 36)
|
||||||
|
self.evaluate_public_key_button.setEnabled(has_failure)
|
||||||
|
self.evaluate_public_key_button.setStyleSheet(f"""
|
||||||
|
QPushButton {{
|
||||||
|
background: #00aaff; color: white; border: none;
|
||||||
|
border-radius: 5px; font-weight: bold; {self.font_style}
|
||||||
|
}}
|
||||||
|
QPushButton:hover:!disabled {{ background: #0088cc; }}
|
||||||
|
QPushButton:disabled {{ background: #666666; color: #bbbbbb; }}
|
||||||
|
""")
|
||||||
|
self.evaluate_public_key_button.clicked.connect(self.evaluate_ticket_public_key)
|
||||||
|
recovery_layout.addWidget(self.evaluate_public_key_button)
|
||||||
|
|
||||||
|
self.ticket_recovery_output = TerminalWidget()
|
||||||
|
self.ticket_recovery_output.setFixedHeight(130)
|
||||||
|
if not has_failure:
|
||||||
|
self.ticket_recovery_output.setPlainText("No saved verification failure.")
|
||||||
|
recovery_layout.addWidget(self.ticket_recovery_output)
|
||||||
|
|
||||||
|
layout.addWidget(recovery_group)
|
||||||
|
|
||||||
|
debug_group = QGroupBox("Debug Recovery")
|
||||||
|
debug_group.setStyleSheet(
|
||||||
|
f"QGroupBox {{ color: white; padding: 15px; {self.font_style} }}")
|
||||||
|
debug_layout = QVBoxLayout(debug_group)
|
||||||
|
|
||||||
|
self.prepare_saved_blind_sigs_button = QPushButton(
|
||||||
|
"Prepare Tickets even if validation of the server's signature failed")
|
||||||
|
self.prepare_saved_blind_sigs_button.setFixedSize(500, 40)
|
||||||
|
self.prepare_saved_blind_sigs_button.setEnabled(has_failure)
|
||||||
|
self.prepare_saved_blind_sigs_button.setStyleSheet(f"""
|
||||||
|
QPushButton {{
|
||||||
|
background: #c0392b; color: white; border: none;
|
||||||
|
border-radius: 5px; font-size: 10px; font-weight: bold; {self.font_style}
|
||||||
|
}}
|
||||||
|
QPushButton:hover:!disabled {{ background: #a93226; }}
|
||||||
|
QPushButton:disabled {{ background: #666666; color: #bbbbbb; }}
|
||||||
|
""")
|
||||||
|
self.prepare_saved_blind_sigs_button.clicked.connect(self.prepare_tickets_with_saved_blind_signatures)
|
||||||
|
debug_layout.addWidget(self.prepare_saved_blind_sigs_button)
|
||||||
|
|
||||||
|
layout.addWidget(debug_group)
|
||||||
layout.addStretch()
|
layout.addStretch()
|
||||||
|
scroll_area.setWidget(scroll_content)
|
||||||
|
page_layout.addWidget(scroll_area)
|
||||||
return page
|
return page
|
||||||
|
|
||||||
|
def _format_ticket_failure_status(self, failure):
|
||||||
|
if not failure:
|
||||||
|
return "No saved verification failure. If ticket preparation fails validation, recovery data will appear here."
|
||||||
|
failed_validations = failure.get("failed_validations", [])
|
||||||
|
how_many_failed = failure.get("how_many_failed", len(failed_validations))
|
||||||
|
updated_at = failure.get("updated_at", "unknown time")
|
||||||
|
failed_text = ", ".join(str(item) for item in failed_validations)
|
||||||
|
return (
|
||||||
|
f"Saved verification failure: {how_many_failed} failed. "
|
||||||
|
f"Failed validation indices: {failed_text}. Saved: {updated_at}"
|
||||||
|
)
|
||||||
|
|
||||||
|
def _refresh_ticket_recovery_controls(self):
|
||||||
|
failure = self.update_status.get_ticket_verification_failure()
|
||||||
|
has_failure = failure is not None
|
||||||
|
if hasattr(self, 'ticket_recovery_status_label'):
|
||||||
|
self.ticket_recovery_status_label.setText(self._format_ticket_failure_status(failure))
|
||||||
|
if hasattr(self, 'evaluate_public_key_button'):
|
||||||
|
self.evaluate_public_key_button.setEnabled(has_failure)
|
||||||
|
if hasattr(self, 'prepare_saved_blind_sigs_button'):
|
||||||
|
self.prepare_saved_blind_sigs_button.setEnabled(has_failure)
|
||||||
|
|
||||||
|
def _set_ticket_recovery_busy(self, busy):
|
||||||
|
if hasattr(self, 'evaluate_public_key_button'):
|
||||||
|
self.evaluate_public_key_button.setEnabled(not busy and self.update_status.get_ticket_verification_failure() is not None)
|
||||||
|
if hasattr(self, 'prepare_saved_blind_sigs_button'):
|
||||||
|
self.prepare_saved_blind_sigs_button.setEnabled(not busy and self.update_status.get_ticket_verification_failure() is not None)
|
||||||
|
|
||||||
|
def _write_ticket_recovery_output(self, text):
|
||||||
|
if hasattr(self, 'ticket_recovery_output'):
|
||||||
|
self.ticket_recovery_output.setPlainText(text)
|
||||||
|
|
||||||
|
def _format_ticket_recovery_result(self, label, result):
|
||||||
|
try:
|
||||||
|
payload = json.dumps(result, indent=2, default=str)
|
||||||
|
except TypeError:
|
||||||
|
payload = str(result)
|
||||||
|
return f"{label}:\n{payload}"
|
||||||
|
|
||||||
|
def _get_ticket_failure_for_action(self):
|
||||||
|
failure = self.update_status.get_ticket_verification_failure()
|
||||||
|
if failure is None:
|
||||||
|
self._write_ticket_recovery_output("No saved verification failure.")
|
||||||
|
self.update_status.update_status("No ticket verification failure is saved.")
|
||||||
|
self._refresh_ticket_recovery_controls()
|
||||||
|
return None
|
||||||
|
return failure
|
||||||
|
|
||||||
|
def evaluate_ticket_public_key(self):
|
||||||
|
failure = self._get_ticket_failure_for_action()
|
||||||
|
if failure is None:
|
||||||
|
return
|
||||||
|
failed_validations = list(failure.get("failed_validations", []))
|
||||||
|
self._write_ticket_recovery_output("Evaluating public key...")
|
||||||
|
self.update_status.update_status("Evaluating ticket public key...")
|
||||||
|
self._set_ticket_recovery_busy(True)
|
||||||
|
|
||||||
|
self.ticket_recovery_worker = TicketingWorkerThread(
|
||||||
|
'EVALUATE_FAILED_VERIFICATION',
|
||||||
|
params={'failed_validations': failed_validations},
|
||||||
|
)
|
||||||
|
self.ticket_recovery_worker.failed_verification_evaluated.connect(self.on_failed_verification_evaluated)
|
||||||
|
self.ticket_recovery_worker.error.connect(self.on_ticket_recovery_error)
|
||||||
|
self.ticket_recovery_worker.start()
|
||||||
|
|
||||||
|
def on_failed_verification_evaluated(self, result):
|
||||||
|
self._write_ticket_recovery_output(self._format_ticket_recovery_result("evaluation_results", result))
|
||||||
|
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):
|
||||||
|
failure = self._get_ticket_failure_for_action()
|
||||||
|
if failure is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
reply = QMessageBox.warning(
|
||||||
|
self,
|
||||||
|
"Prepare Tickets Anyway",
|
||||||
|
"This will prepare tickets even though server signature validation failed. Continue only if you have evaluated the situation.",
|
||||||
|
QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No,
|
||||||
|
QMessageBox.StandardButton.No,
|
||||||
|
)
|
||||||
|
if reply != QMessageBox.StandardButton.Yes:
|
||||||
|
return
|
||||||
|
|
||||||
|
self._write_ticket_recovery_output("Preparing tickets with saved blind signatures...")
|
||||||
|
self.update_status.update_status("Preparing tickets with saved blind signatures...")
|
||||||
|
self._set_ticket_recovery_busy(True)
|
||||||
|
|
||||||
|
self.ticket_recovery_worker = TicketingWorkerThread('PREPARE_SAVED_BLIND_SIGS')
|
||||||
|
self.ticket_recovery_worker.saved_blind_prep_done.connect(self.on_saved_blind_prep_done)
|
||||||
|
self.ticket_recovery_worker.error.connect(self.on_ticket_recovery_error)
|
||||||
|
self.ticket_recovery_worker.start()
|
||||||
|
|
||||||
|
def on_saved_blind_prep_done(self, result):
|
||||||
|
self._write_ticket_recovery_output(self._format_ticket_recovery_result("Results of preparation", result))
|
||||||
|
if isinstance(result, dict) and result.get('valid') is True:
|
||||||
|
self.update_status.clear_ticket_verification_failure()
|
||||||
|
self.update_status.update_status("Tickets prepared from saved blind signatures.")
|
||||||
|
self._refresh_tickets_inventory()
|
||||||
|
else:
|
||||||
|
msg = result.get('message', 'failed') if isinstance(result, dict) else 'failed'
|
||||||
|
self.update_status.update_status(f"Saved blind signature prep failed: {msg}")
|
||||||
|
self._set_ticket_recovery_busy(False)
|
||||||
|
self._refresh_ticket_recovery_controls()
|
||||||
|
|
||||||
|
def on_ticket_recovery_error(self, 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):
|
def _on_random_toggle(self, checked):
|
||||||
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)
|
||||||
|
|
@ -10488,6 +10744,8 @@ class TicketingWorkerThread(QThread):
|
||||||
paid_check_failed = pyqtSignal(str)
|
paid_check_failed = pyqtSignal(str)
|
||||||
prep_done = pyqtSignal(object)
|
prep_done = pyqtSignal(object)
|
||||||
use_done = pyqtSignal(object)
|
use_done = pyqtSignal(object)
|
||||||
|
failed_verification_evaluated = pyqtSignal(object)
|
||||||
|
saved_blind_prep_done = pyqtSignal(object)
|
||||||
error = pyqtSignal(str)
|
error = pyqtSignal(str)
|
||||||
|
|
||||||
def __init__(self, action, params=None):
|
def __init__(self, action, params=None):
|
||||||
|
|
@ -10524,6 +10782,16 @@ class TicketingWorkerThread(QThread):
|
||||||
elif self.action == 'PREPARE_TICKETS':
|
elif self.action == 'PREPARE_TICKETS':
|
||||||
result = prepare_tickets(self.params['how_many_profiles'], ticket_observer, connection_observer)
|
result = prepare_tickets(self.params['how_many_profiles'], ticket_observer, connection_observer)
|
||||||
self.prep_done.emit(result)
|
self.prep_done.emit(result)
|
||||||
|
elif self.action == 'EVALUATE_FAILED_VERIFICATION':
|
||||||
|
result = evaluate_if_its_the_key(
|
||||||
|
self.params['failed_validations'],
|
||||||
|
ticket_observer,
|
||||||
|
connection_observer,
|
||||||
|
)
|
||||||
|
self.failed_verification_evaluated.emit(result)
|
||||||
|
elif self.action == 'PREPARE_SAVED_BLIND_SIGS':
|
||||||
|
result = prepare_tickets_with_saved_blind_sigs(ticket_observer, connection_observer)
|
||||||
|
self.saved_blind_prep_done.emit(result)
|
||||||
elif self.action == 'USE_TICKET':
|
elif self.action == 'USE_TICKET':
|
||||||
result = use_ticket(
|
result = use_ticket(
|
||||||
self.params['which_ticket'],
|
self.params['which_ticket'],
|
||||||
|
|
@ -10758,6 +11026,7 @@ class TicketPrepPage(Page):
|
||||||
self.update_status = main_window
|
self.update_status = main_window
|
||||||
self.worker = None
|
self.worker = None
|
||||||
self._terminal_bound = False
|
self._terminal_bound = False
|
||||||
|
self._tickets_ready = False
|
||||||
|
|
||||||
self.title.setText("Preparing Tickets")
|
self.title.setText("Preparing Tickets")
|
||||||
self.title.setGeometry(QtCore.QRect(280, 20, 240, 40))
|
self.title.setGeometry(QtCore.QRect(280, 20, 240, 40))
|
||||||
|
|
@ -10780,7 +11049,7 @@ class TicketPrepPage(Page):
|
||||||
}
|
}
|
||||||
QPushButton:disabled { background-color: #555555; }
|
QPushButton:disabled { background-color: #555555; }
|
||||||
""")
|
""")
|
||||||
self.continue_button.setEnabled(False)
|
self.continue_button.setEnabled(True)
|
||||||
self.continue_button.clicked.connect(self.on_continue)
|
self.continue_button.clicked.connect(self.on_continue)
|
||||||
|
|
||||||
def _bind_terminal_once(self):
|
def _bind_terminal_once(self):
|
||||||
|
|
@ -10796,7 +11065,8 @@ class TicketPrepPage(Page):
|
||||||
def start_prep(self):
|
def start_prep(self):
|
||||||
self._bind_terminal_once()
|
self._bind_terminal_once()
|
||||||
self.terminal.append("=== Starting ticket preparation ===")
|
self.terminal.append("=== Starting ticket preparation ===")
|
||||||
self.continue_button.setEnabled(False)
|
self._tickets_ready = False
|
||||||
|
self.continue_button.setEnabled(True)
|
||||||
self.status_label.setText("Preparing tickets...")
|
self.status_label.setText("Preparing tickets...")
|
||||||
self.update_status.update_status("Preparing tickets...")
|
self.update_status.update_status("Preparing tickets...")
|
||||||
|
|
||||||
|
|
@ -10813,6 +11083,8 @@ class TicketPrepPage(Page):
|
||||||
self.status_label.setText("Preparation failed.")
|
self.status_label.setText("Preparation failed.")
|
||||||
return
|
return
|
||||||
if result.get('valid') is True:
|
if result.get('valid') is True:
|
||||||
|
self._tickets_ready = True
|
||||||
|
self.update_status.clear_ticket_verification_failure()
|
||||||
self.terminal.append("=== Ticket preparation complete ===")
|
self.terminal.append("=== Ticket preparation complete ===")
|
||||||
self.status_label.setText("Tickets ready. Click Continue to apply one to your profile.")
|
self.status_label.setText("Tickets ready. Click Continue to apply one to your profile.")
|
||||||
self.update_status.update_status("Tickets ready.")
|
self.update_status.update_status("Tickets ready.")
|
||||||
|
|
@ -10825,18 +11097,29 @@ class TicketPrepPage(Page):
|
||||||
failed_validations = result.get('failed_validations', [])
|
failed_validations = result.get('failed_validations', [])
|
||||||
self.terminal.append(f" failed count: {how_many_failed}")
|
self.terminal.append(f" failed count: {how_many_failed}")
|
||||||
self.terminal.append(f" failed indices: {failed_validations}")
|
self.terminal.append(f" failed indices: {failed_validations}")
|
||||||
|
if self.update_status.save_ticket_verification_failure(result):
|
||||||
|
self.terminal.append("Recovery data saved. Open Settings > Tickets to evaluate or resume.")
|
||||||
|
self.status_label.setText("Verification failed. Open Settings > Tickets for recovery.")
|
||||||
|
self.update_status.update_status("Ticket verification failed")
|
||||||
|
self.continue_button.setEnabled(True)
|
||||||
|
return
|
||||||
self.status_label.setText(f"Preparation failed: {msg}")
|
self.status_label.setText(f"Preparation failed: {msg}")
|
||||||
self.update_status.update_status(f"An error occurred")
|
self.update_status.update_status(f"An error occurred")
|
||||||
|
self.continue_button.setEnabled(True)
|
||||||
|
|
||||||
def on_error(self, msg):
|
def on_error(self, msg):
|
||||||
self.terminal.append(f"EXCEPTION: {msg}")
|
self.terminal.append(f"EXCEPTION: {msg}")
|
||||||
self.status_label.setText(f"An unkown error occured")
|
self.status_label.setText(f"An unkown error occured")
|
||||||
|
self.continue_button.setEnabled(True)
|
||||||
|
|
||||||
def on_continue(self):
|
def on_continue(self):
|
||||||
menu_page = self.page_stack.findChild(MenuPage)
|
menu_page = self.page_stack.findChild(MenuPage)
|
||||||
profile_id = getattr(self.update_status, 'current_profile_id', None)
|
profile_id = getattr(self.update_status, 'current_profile_id', None)
|
||||||
if menu_page:
|
if menu_page:
|
||||||
self.page_stack.setCurrentWidget(menu_page)
|
self.page_stack.setCurrentWidget(menu_page)
|
||||||
|
if not self._tickets_ready:
|
||||||
|
self.update_status.update_status("Ticket preparation was not completed.")
|
||||||
|
return
|
||||||
if profile_id is None or menu_page is None:
|
if profile_id is None or menu_page is None:
|
||||||
self.update_status.update_status("Tickets ready. Random ticket use is ON.")
|
self.update_status.update_status("Tickets ready. Random ticket use is ON.")
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
[project]
|
[project]
|
||||||
name = "sp-hydra-veil-gui"
|
name = "sp-hydra-veil-gui"
|
||||||
version = "2.2.7"
|
version = "2.2.8"
|
||||||
authors = [
|
authors = [
|
||||||
{ name = "Simplified Privacy" },
|
{ name = "Simplified Privacy" },
|
||||||
]
|
]
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue