class InviteReceiver(QObject): # Wormhole got_welcome = Signal(dict) # got_code = Signal(str) got_introduction = Signal() got_message = Signal(dict) closed = Signal() # SetupRunner grid_already_joined = Signal(str) update_progress = Signal(str) got_icon = Signal(str) client_started = Signal(object) joined_folders = Signal(list) done = Signal(object) def __init__(self, known_gateways=None, use_tor=False): super(InviteReceiver, self).__init__() self.known_gateways = known_gateways self.use_tor = use_tor self.setup_runner = SetupRunner(known_gateways, use_tor) self.setup_runner.grid_already_joined.connect( self.grid_already_joined.emit ) self.setup_runner.update_progress.connect(self.update_progress.emit) self.setup_runner.got_icon.connect(self.got_icon.emit) self.setup_runner.client_started.connect(self.client_started.emit) self.setup_runner.joined_folders.connect(self.joined_folders.emit) self.setup_runner.done.connect(self.done.emit) self.wormhole = Wormhole(use_tor) self.wormhole.got_welcome.connect(self.got_welcome.emit) self.wormhole.got_introduction.connect(self.got_introduction.emit) self.wormhole.got_message.connect(self.got_message.emit) self.wormhole.closed.connect(self.closed.emit) def cancel(self): self.wormhole.close() @inlineCallbacks def _run_setup(self, settings, from_wormhole): settings = validate_settings( settings, self.known_gateways, None, from_wormhole ) yield self.setup_runner.run(settings) @inlineCallbacks def receive(self, code, settings=None): # TODO: Calculate/emit total steps if settings: yield self._run_setup(settings, from_wormhole=False) elif code.split("-")[0] == "0": settings = load_settings_from_cheatcode(code[2:]) if settings: yield self._run_setup(settings, from_wormhole=False) else: settings = yield self.wormhole.receive(code) yield self._run_setup(settings, from_wormhole=True)
def test_wormhole_receive_via_xfer_util(qtbot, monkeypatch): fake_wormhole = MagicMock() fake_wormhole.get_welcome.return_value = {} fake_wormhole.get_message.return_value = ( b'{"offer": {"message": "{\\"nickname\\": \\"Test Grid\\"}"}}') monkeypatch.setattr("gridsync.wormhole_.wormhole.create", lambda x, y, z: fake_wormhole) wormhole = Wormhole() output = yield wormhole.receive("123-test-test") assert output == {"nickname": "Test Grid"}
def test_wormhole_receive_succeed_return_msg_dict(qtbot, monkeypatch): fake_wormhole = MagicMock() fake_wormhole.get_welcome.return_value = {} fake_wormhole.get_message.return_value = ( b'{"abilities": {"server-v1": {}}}') monkeypatch.setattr("gridsync.wormhole_.wormhole.create", lambda x, y, z: fake_wormhole) wormhole = Wormhole() output = yield wormhole.receive("123-test-test") assert output == {"abilities": {"server-v1": {}}}
def test_wormhole_receive_raise_upgrade_required_no_abilities( qtbot, monkeypatch): fake_wormhole = MagicMock() fake_wormhole.get_welcome.return_value = {} fake_wormhole.get_message.return_value = b'{"blah": "blah"}' monkeypatch.setattr("gridsync.wormhole_.wormhole.create", lambda x, y, z: fake_wormhole) wormhole = Wormhole() with pytest.raises(UpgradeRequiredError): yield wormhole.receive("123-test-test")
def test_wormhole_receive_emit_got_introduction_signal(qtbot, monkeypatch): fake_wormhole = MagicMock() fake_wormhole.get_welcome.return_value = {} fake_wormhole.get_message.return_value = ( b'{"abilities": {"server-v1": {}}}') monkeypatch.setattr("gridsync.wormhole_.wormhole.create", lambda x, y, z: fake_wormhole) wormhole = Wormhole() with qtbot.wait_signal(wormhole.got_introduction): yield wormhole.receive("123-test-test")
def test_wormhole_receive_succeed_emit_got_message_signal(qtbot, monkeypatch): fake_wormhole = MagicMock() fake_wormhole.get_welcome.return_value = {} fake_wormhole.get_message.return_value = ( b'{"offer": {"message": "{\\"nickname\\": \\"Test Grid\\"}"}}') monkeypatch.setattr("gridsync.wormhole_.wormhole.create", lambda x, y, z: fake_wormhole) wormhole = Wormhole() with qtbot.wait_signal(wormhole.got_message) as blocker: yield wormhole.receive("123-test-test") assert blocker.args == [{"nickname": "Test Grid"}]
def test_wormhole_receive_raise_upgrade_required_bad_version( qtbot, monkeypatch): fake_wormhole = MagicMock() fake_wormhole.get_welcome.return_value = {} fake_wormhole.get_message.return_value = ( b'{"abilities": {"server-v9999": {}}}') monkeypatch.setattr("gridsync.wormhole_.wormhole.create", lambda x, y, z: fake_wormhole) wormhole = Wormhole() with pytest.raises(UpgradeRequiredError): yield wormhole.receive("123-test-test")
def test_wormhole_receive_via_xfer_util_raise_unknown_offer( qtbot, monkeypatch): fake_wormhole = MagicMock() fake_wormhole.get_welcome.return_value = {} fake_wormhole.get_message.return_value = ( b'{"offer": {"NOT_message": "{\\"nickname\\": \\"Test Grid\\"}"}}') monkeypatch.setattr("gridsync.wormhole_.wormhole.create", lambda x, y, z: fake_wormhole) wormhole = Wormhole() with pytest.raises(Exception): yield wormhole.receive("123-test-test")
class InviteReceiver(QDialog): done = pyqtSignal(QWidget) closed = pyqtSignal(QWidget) def __init__(self, gateways): super(InviteReceiver, self).__init__() self.gateways = gateways self.wormhole = None self.setup_runner = None self.joined_folders = [] self.use_tor = False self.setMinimumSize(500, 300) self.mail_closed_icon = QLabel() self.mail_closed_icon.setPixmap( QPixmap(resource('mail-envelope-closed.png')).scaled(128, 128)) self.mail_closed_icon.setAlignment(Qt.AlignCenter) self.mail_open_icon = QLabel() self.mail_open_icon.setPixmap( QPixmap(resource('mail-envelope-open.png')).scaled(128, 128)) self.mail_open_icon.setAlignment(Qt.AlignCenter) self.folder_icon = QLabel() icon = QFileIconProvider().icon(QFileInfo(config_dir)) self.folder_icon.setPixmap(icon.pixmap(128, 128)) self.folder_icon.setAlignment(Qt.AlignCenter) self.invite_code_widget = InviteCodeWidget(self) self.label = self.invite_code_widget.label self.tor_checkbox = self.invite_code_widget.checkbox self.tor_checkbox.stateChanged.connect(self.on_checkbox_state_changed) self.lineedit = self.invite_code_widget.lineedit self.lineedit.error.connect(self.show_error) self.lineedit.go.connect(self.go) self.tor_label = QLabel() self.tor_label.setToolTip( "This connection is being routed through the Tor network.") self.tor_label.setPixmap( QPixmap(resource('tor-onion.png')).scaled(32, 32)) self.progressbar = QProgressBar(self) self.progressbar.setValue(0) self.progressbar.setMaximum(6) # XXX self.progressbar.setTextVisible(False) self.message_label = QLabel() self.message_label.setStyleSheet("color: grey") self.message_label.setAlignment(Qt.AlignCenter) self.error_label = QLabel() self.error_label.setStyleSheet("color: red") self.error_label.setAlignment(Qt.AlignCenter) self.close_button = QPushButton("Close") self.close_button.clicked.connect(self.close) layout = QGridLayout(self) layout.addItem(QSpacerItem(0, 0, 0, QSizePolicy.Expanding), 0, 0) layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, 0), 1, 1) layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, 0), 1, 2) layout.addWidget(self.mail_closed_icon, 1, 2, 1, 3) layout.addWidget(self.mail_open_icon, 1, 2, 1, 3) layout.addWidget(self.folder_icon, 1, 2, 1, 3) layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, 0), 1, 4) layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, 0), 1, 5) layout.addWidget(self.label, 2, 3, 1, 1) layout.addWidget(self.tor_label, 3, 1, 1, 1, Qt.AlignRight | Qt.AlignVCenter) layout.addWidget(self.lineedit, 3, 2, 1, 3) layout.addWidget(self.progressbar, 3, 2, 1, 3) layout.addWidget(self.tor_checkbox, 4, 2, 1, 3, Qt.AlignCenter) layout.addWidget(self.message_label, 5, 1, 1, 5) layout.addWidget(self.error_label, 5, 2, 1, 3) layout.addWidget(self.close_button, 6, 3) layout.addItem(QSpacerItem(0, 0, 0, QSizePolicy.Expanding), 7, 1) self.reset() def reset(self): self.mail_open_icon.hide() self.folder_icon.hide() self.mail_closed_icon.show() self.label.setText("Enter invite code:") self.lineedit.show() self.lineedit.setText('') self.tor_checkbox.show() self.progressbar.hide() self.message_label.setText( "Invite codes can be used to join a grid or a folder") self.error_label.setText('') self.error_label.hide() self.close_button.hide() self.tor_label.hide() def on_checkbox_state_changed(self, state): self.use_tor = bool(state) logging.debug("use_tor=%s", self.use_tor) if state: self.progressbar.setStyleSheet( 'QProgressBar::chunk {{ background-color: {}; }}'.format( TOR_PURPLE)) else: self.progressbar.setStyleSheet('') def show_error(self, text): self.error_label.setText(text) self.message_label.hide() self.error_label.show() reactor.callLater(3, self.error_label.hide) reactor.callLater(3, self.message_label.show) def update_progress(self, message): step = self.progressbar.value() + 1 self.progressbar.setValue(step) self.message_label.setText(message) if step == 3: self.mail_closed_icon.hide() self.mail_open_icon.show() if step == 4: self.mail_open_icon.hide() self.folder_icon.show() def set_joined_folders(self, folders): self.joined_folders = folders def on_done(self, _): self.progressbar.setValue(self.progressbar.maximum()) self.close_button.show() self.done.emit(self) self.label.setPixmap( QPixmap(resource('green_checkmark.png')).scaled(32, 32)) if self.joined_folders and len(self.joined_folders) == 1: target = self.joined_folders[0] self.message_label.setText( 'Successfully joined folder "{0}"!\n"{0}" is now available ' 'for download'.format(target)) elif self.joined_folders: target = humanized_list(self.joined_folders, 'folders') self.message_label.setText( 'Successfully joined {0}!\n{0} are now available for ' 'download'.format(target)) def on_grid_already_joined(self, grid_name): QMessageBox.information( self, "Already connected", 'You are already connected to "{}"'.format(grid_name)) self.close() def got_message(self, message): self.update_progress("Reading invitation...") # 3 message = validate_settings(message, self.gateways, self) self.setup_runner = SetupRunner(self.gateways, self.use_tor) if not message.get('magic-folders'): self.setup_runner.grid_already_joined.connect( self.on_grid_already_joined) self.setup_runner.update_progress.connect(self.update_progress) self.setup_runner.joined_folders.connect(self.set_joined_folders) self.setup_runner.done.connect(self.on_done) self.setup_runner.run(message) def got_welcome(self): self.update_progress("Connected; waiting for message...") # 2 def handle_failure(self, failure): logging.error(str(failure)) if failure.type == CancelledError and self.progressbar.value() > 2: return show_failure(failure, self) self.close() def go(self, code): self.reset() self.label.setText(' ') self.lineedit.hide() self.tor_checkbox.hide() self.progressbar.show() if self.use_tor: self.tor_label.show() self.update_progress("Verifying invitation...") # 1 if code.split('-')[0] == "0": settings = get_settings_from_cheatcode(code[2:]) if settings: self.got_message(settings) return self.wormhole = Wormhole(self.use_tor) self.wormhole.got_welcome.connect(self.got_welcome) self.wormhole.got_message.connect(self.got_message) d = self.wormhole.receive(code) d.addErrback(self.handle_failure) reactor.callLater(30, d.cancel) def enterEvent(self, event): event.accept() self.lineedit.update_action_button() def closeEvent(self, event): event.accept() try: self.wormhole.close() except AttributeError: pass self.closed.emit(self) def keyPressEvent(self, event): if event.key() == Qt.Key_Escape: self.close()