sp-hydra-veil-gui/gui/v2/ui/pages/ticket_crypto_picker_page.py

149 lines
6.3 KiB
Python
Executable file

import os
from PyQt6.QtWidgets import QButtonGroup, QMessageBox, QPushButton
from PyQt6.QtGui import QIcon
from PyQt6.QtCore import QSize
from PyQt6 import QtCore
from core.services.prepare_tickets.ticket_tracker import delete_ticket_data
from gui.v2.ui.pages.Page import Page
from gui.v2.ui.popups.message_box import style_message_box, mark_confirm_button
from gui.v2.workers.ticketing_worker_thread import TicketingWorkerThread
HOW_MANY_PROFILES_DEFAULT = 6
class TicketCryptoPickerPage(Page):
def __init__(self, page_stack, main_window=None, parent=None):
super().__init__("TicketCrypto", page_stack, main_window, parent)
self.update_status = main_window
self.selected_plan = None
self.bypass_existing = False
self.worker = None
self.title.setText("Payment Method")
self.title.setGeometry(QtCore.QRect(510, 30, 250, 40))
self.title.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
self.button_reverse.setVisible(True)
self.button_reverse.clicked.connect(self.reverse)
button_info = [
("monero", "monero", (545, 75)),
("bitcoin", "bitcoin", (545, 290)),
("lightning", "lightnering", (545, 180)),
("litecoin", "litecoin", (545, 395)),
]
self.buttonGroup = QButtonGroup(self)
self.buttons = []
for j, (currency, icon_name, position) in enumerate(button_info):
button = QPushButton(self)
button.setGeometry(position[0], position[1], 185, 75)
button.setIconSize(QSize(190, 120))
button.setCheckable(True)
button.setIcon(QIcon(os.path.join(self.btn_path, f"{icon_name}.png")))
button.setProperty('currency', currency)
self.buttons.append(button)
self.buttonGroup.addButton(button, j)
button.clicked.connect(self.on_currency_selected)
def set_selected_plan(self, plan_key):
self.selected_plan = plan_key
self.bypass_existing = False
self.update_status.update_status(f"Selected plan: {plan_key}")
for btn in self.buttons:
btn.setChecked(False)
def on_currency_selected(self):
selected_button = self.buttonGroup.checkedButton()
if not selected_button or not self.selected_plan:
return
currency = selected_button.property('currency')
self.start_initiate_payment(currency)
def start_initiate_payment(self, currency):
self.update_status.update_status("Initiating payment...")
self.worker = TicketingWorkerThread('INITIATE_PAYMENT', params={
'how_many_profiles': HOW_MANY_PROFILES_DEFAULT,
'which_key': self.selected_plan,
'which_cryptocurrency': currency,
'bypass_existing': self.bypass_existing,
})
self.worker.invoice_ready.connect(self.on_invoice_ready)
self.worker.error.connect(self.on_error)
self.worker.start()
def on_invoice_ready(self, invoice):
if invoice is None or invoice is False:
self.update_status.update_status("Could not initiate payment.")
return
if not getattr(invoice, 'is_valid', False):
return self._handle_api_errors(invoice)
self.custom_window.navigator.navigate("payment_details")
payment_page = self.custom_window.navigator.get_cached("payment_details")
if payment_page is not None:
payment_page.set_ticket_invoice(invoice, self.selected_plan)
def _handle_api_errors(self, invoice):
error_code = getattr(invoice, 'error_code', None)
if error_code == "already_exists" and not self.bypass_existing:
self._prompt_wipe_existing()
return
elif error_code == "billing_code_exists" and not self.bypass_existing:
temp_billing_code = getattr(invoice, 'temp_billing_code', None)
self._prompt_wipe_existing(temp_billing_code)
return
else:
error_msg = getattr(invoice, 'final_error_msg', None) or error_code or "Could not initiate payment."
self.update_status.update_status(error_msg)
return
def _prompt_wipe_existing(self, temp_billing_code=None):
msg = QMessageBox(self)
if temp_billing_code:
msg.setWindowTitle("Existing billing code found")
msg.setText("You already have a ticket billing code. Use it, or wipe it and start over?")
use_button = msg.addButton("Use existing", QMessageBox.ButtonRole.AcceptRole)
wipe_button = msg.addButton("Wipe and start over", QMessageBox.ButtonRole.DestructiveRole)
cancel_button = msg.addButton("Cancel", QMessageBox.ButtonRole.RejectRole)
mark_confirm_button(use_button)
else:
msg.setWindowTitle("Existing tickets found")
msg.setText("You already have ticket data. Wipe it and start over?")
use_button = None
wipe_button = msg.addButton("Wipe and start over", QMessageBox.ButtonRole.DestructiveRole)
cancel_button = msg.addButton("Cancel", QMessageBox.ButtonRole.RejectRole)
mark_confirm_button(wipe_button)
style_message_box(msg)
msg.exec()
clicked = msg.clickedButton()
if temp_billing_code and clicked == use_button:
self.update_status.update_status("Reusing existing billing code")
self.custom_window.navigator.navigate("payment_details")
payment_page = self.custom_window.navigator.get_cached("payment_details")
if payment_page is not None:
payment_page.resume_ticket_billing(temp_billing_code)
return
if clicked == wipe_button:
self._restart_payment_after_wipe()
else:
self.update_status.update_status("Cancelled.")
def _restart_payment_after_wipe(self):
if not delete_ticket_data():
self.update_status.update_status("Could not wipe ticket data.")
return
self.bypass_existing = False
currency_btn = self.buttonGroup.checkedButton()
if currency_btn:
self.start_initiate_payment(currency_btn.property('currency'))
def on_error(self, msg):
self.update_status.update_status(f"Payment error: {msg}")
def reverse(self):
self.custom_window.navigator.navigate("plan_picker")