def run(self):
     self.thread = TaskThread(None)
     self.thread.add(
         task=self.cool_down_task,
         on_success=self.on_success,
         on_error=lambda *args, **kwargs: None,
     )
class PinConfirmationLayout(QVBoxLayout, ErrorMessageMixin, InputFieldMixin):

    def __init__(self, parent, email, error_msg=''):
        super(). __init__()
        self.parent = parent
        self.resend_strategy = parent.resend_strategy
        self.cool_down_thread = parent.cool_down_thread

        label = QLabel(_('To confirm the request, please enter the code we sent to') + f"<br><b>{email}</b>")
        label.setWordWrap(True)
        hbox = QHBoxLayout()
        code_label = QLabel(_('Code:'))
        pin_edit = PinInputFiled()
        hbox.addWidget(code_label)
        hbox.addWidget(pin_edit)
        pin_edit.textChanged.connect(self.input_edited)
        self.input_edit = pin_edit

        self.addWidget(label)
        self.addSpacing(10)
        self.addLayout(hbox)
        self.error_label = QLabel()
        self.error_label.setWordWrap(True)
        self.error_label.setVisible(False)
        if error_msg:
            self.set_error(error_msg)

        self.send_request_thread = TaskThread(None)
        if self.cool_down_thread.is_running():
            self.resend_button = QPushButton(self.cool_down_thread.get_formatted_left_time())
            self.resend_button.setEnabled(False)
        else:
            self.resend_button = QPushButton(_('Resend'))
        hbox.addStretch(1)
        hbox.addWidget(self.resend_button)
        self.resend_button.clicked.connect(self.resend_request)
        self.addSpacing(5)
        self.addLayout(hbox)
        self.addSpacing(5)
        self.addWidget(self.error_label)

    def on_error(self, errors):
        self.resend_strategy.on_error(errors[1])
        self.set_error(str(errors[1]))

    def resend_request(self):
        self.clear_error()
        self.cool_down_thread.run()
        self.send_request_thread.add(
            task=lambda: self.resend_strategy.resend(),
            on_success=lambda *args, **kwargs: None,
            on_error=self.on_error
        )

    def pin(self):
        return self.input_edit.text()

    def terminate_thread(self):
        self.send_request_thread.terminate()
class CoolDownThread:
    RESEND_COOL_DOWN_TIME = 30

    def __init__(self):
        self.elapsed_time = 0
        self.pin_layout = None
        self.thread = None

    def register_layout(self, layout: PinConfirmationLayout):
        self.pin_layout = layout

    def unregister_layout(self):
        self.pin_layout = None

    def _set_resend_button_status(self, text: str, enabled: bool):
        if self.pin_layout:
            self.pin_layout.resend_button.setText(text)
            self.pin_layout.resend_button.setEnabled(enabled)

    def get_left_time(self) -> int:
        return int(self.RESEND_COOL_DOWN_TIME - self.elapsed_time)

    def get_formatted_left_time(self) -> str:
        return f'{self.get_left_time():>2}s'

    def cool_down_task(self):
        t0 = datetime.datetime.now()
        while True:
            self.elapsed_time = (datetime.datetime.now() - t0).total_seconds()
            if self.get_left_time() < 1:
                break
            self._set_resend_button_status(self.get_formatted_left_time(), False)
            time.sleep(1)

    def on_success(self, *args, **kwargs):
        self._set_resend_button_status(_('Resend'), True)

    def run(self):
        self.thread = TaskThread(None)
        self.thread.add(
            task=self.cool_down_task,
            on_success=self.on_success,
            on_error=lambda *args, **kwargs: None,
        )

    def is_running(self) -> bool:
        return bool(self.thread and self.get_left_time() > 0)

    def terminate(self):
        self.elapsed_time = 0
        if self.thread:
            self.thread.terminate()
Пример #4
0
 def load_wallet(self, wallet, window):
     for keystore in wallet.get_keystores():
         if not isinstance(keystore, self.keystore_class):
             continue
         if not self.libraries_available:
             message = keystore.plugin.get_library_not_available_message()
             window.show_error(message)
             return
         tooltip = self.device + '\n' + (keystore.label or 'unnamed')
         cb = partial(self.show_settings_dialog, window, keystore)
         button = StatusBarButton(read_QIcon(self.icon_unpaired), tooltip,
                                  cb)
         button.icon_paired = self.icon_paired
         button.icon_unpaired = self.icon_unpaired
         window.statusBar().addPermanentWidget(button)
         handler = self.create_handler(window)
         handler.button = button
         keystore.handler = handler
         keystore.thread = TaskThread(window,
                                      on_error=partial(
                                          self.on_task_thread_error, window,
                                          keystore))
         self.add_show_address_on_hw_device_button_for_receive_addr(
             wallet, keystore, window)
         # Trigger a pairing
         keystore.thread.add(partial(self.get_client, keystore))
Пример #5
0
 def load_wallet(self: Union['QtPluginBase', HW_PluginBase], wallet: 'Abstract_Wallet', window: ElectrumWindow):
     relevant_keystores = [keystore for keystore in wallet.get_keystores()
                           if isinstance(keystore, self.keystore_class)]
     if not relevant_keystores:
         return
     for keystore in relevant_keystores:
         if not self.libraries_available:
             message = keystore.plugin.get_library_not_available_message()
             window.show_error(message)
             return
         tooltip = self.device + '\n' + (keystore.label or 'unnamed')
         cb = partial(self._on_status_bar_button_click, window=window, keystore=keystore)
         button = StatusBarButton(read_QIcon(self.icon_unpaired), tooltip, cb)
         button.icon_paired = self.icon_paired
         button.icon_unpaired = self.icon_unpaired
         window.statusBar().addPermanentWidget(button)
         handler = self.create_handler(window)
         handler.button = button
         keystore.handler = handler
         keystore.thread = TaskThread(window, on_error=partial(self.on_task_thread_error, window, keystore))
         self.add_show_address_on_hw_device_button_for_receive_addr(wallet, keystore, window)
     # Trigger pairings
     devmgr = self.device_manager()
     trigger_pairings = partial(devmgr.trigger_pairings, relevant_keystores, allow_user_interaction=True)
     some_keystore = relevant_keystores[0]
     some_keystore.thread.add(trigger_pairings)
    def __init__(self, parent, email, error_msg=''):
        super(). __init__()
        self.parent = parent
        self.resend_strategy = parent.resend_strategy
        self.cool_down_thread = parent.cool_down_thread

        label = QLabel(_('To confirm the request, please enter the code we sent to') + f"<br><b>{email}</b>")
        label.setWordWrap(True)
        hbox = QHBoxLayout()
        code_label = QLabel(_('Code:'))
        pin_edit = PinInputFiled()
        hbox.addWidget(code_label)
        hbox.addWidget(pin_edit)
        pin_edit.textChanged.connect(self.input_edited)
        self.input_edit = pin_edit

        self.addWidget(label)
        self.addSpacing(10)
        self.addLayout(hbox)
        self.error_label = QLabel()
        self.error_label.setWordWrap(True)
        self.error_label.setVisible(False)
        if error_msg:
            self.set_error(error_msg)

        self.send_request_thread = TaskThread(None)
        if self.cool_down_thread.is_running():
            self.resend_button = QPushButton(self.cool_down_thread.get_formatted_left_time())
            self.resend_button.setEnabled(False)
        else:
            self.resend_button = QPushButton(_('Resend'))
        hbox.addStretch(1)
        hbox.addWidget(self.resend_button)
        self.resend_button.clicked.connect(self.resend_request)
        self.addSpacing(5)
        self.addLayout(hbox)
        self.addSpacing(5)
        self.addWidget(self.error_label)