diff --git a/src/sakia/data/processors/sources.py b/src/sakia/data/processors/sources.py index 70e4700566fcea8f92bb532ef4252dcfc28d5fdb..006352b5552b8d3207dea2c3f59b09cd526d922b 100644 --- a/src/sakia/data/processors/sources.py +++ b/src/sakia/data/processors/sources.py @@ -62,12 +62,13 @@ class SourcesProcessor: sources = self._repo.get_all(currency=currency, pubkey=pubkey) return sum([s.amount * (10**s.base) for s in sources]) - def available(self, currency): + def available(self, currency, pubkey): """" :param str currency: the currency of the sources + :param str pubkey: the owner of the sources :rtype: list[sakia.data.entities.Source] """ - return self._repo.get_all(currency=currency) + return self._repo.get_all(currency=currency, pubkey=pubkey) def consume(self, sources): """ diff --git a/src/sakia/gui/dialogs/connection_cfg/connection_cfg.ui b/src/sakia/gui/dialogs/connection_cfg/connection_cfg.ui index 4db97ce83f7dc3ce6b2212617d0126b252728c34..1ac14cc533d89ae6361fbeb091710bbfe1304da5 100644 --- a/src/sakia/gui/dialogs/connection_cfg/connection_cfg.ui +++ b/src/sakia/gui/dialogs/connection_cfg/connection_cfg.ui @@ -32,7 +32,7 @@ <item> <widget class="QPushButton" name="button_register"> <property name="text"> - <string>Register a new account</string> + <string>Register a new identity</string> </property> <property name="icon"> <iconset resource="../../../../../res/icons/icons.qrc"> @@ -49,7 +49,7 @@ <item> <widget class="QPushButton" name="button_connect"> <property name="text"> - <string>Connect with an existing account</string> + <string>Connect with an existing identity</string> </property> <property name="icon"> <iconset resource="../../../../../res/icons/icons.qrc"> @@ -102,22 +102,9 @@ <item> <widget class="QGroupBox" name="groupBox"> <property name="title"> - <string>Account parameters</string> + <string>Connection parameters</string> </property> <layout class="QVBoxLayout" name="verticalLayout_2"> - <item> - <spacer name="verticalSpacer_3"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>40</height> - </size> - </property> - </spacer> - </item> <item> <layout class="QHBoxLayout" name="horizontalLayout"> <item> @@ -132,49 +119,6 @@ </item> </layout> </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_8"> - <property name="topMargin"> - <number>6</number> - </property> - <item> - <spacer name="horizontalSpacer_2"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QPushButton" name="button_delete"> - <property name="styleSheet"> - <string notr="true">color: rgb(255, 0, 0);</string> - </property> - <property name="text"> - <string>Delete account</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <spacer name="verticalSpacer_4"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>40</height> - </size> - </property> - </spacer> - </item> <item> <layout class="QVBoxLayout" name="verticalLayout_6"> <item> @@ -356,6 +300,19 @@ </item> </layout> </item> + <item> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> <item> <layout class="QHBoxLayout" name="horizontalLayout_4"> <property name="topMargin"> @@ -404,19 +361,6 @@ </widget> </widget> </item> - <item> - <spacer name="verticalSpacer"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>40</height> - </size> - </property> - </spacer> - </item> <item> <widget class="QLabel" name="label_currency"> <property name="text"> diff --git a/src/sakia/gui/dialogs/connection_cfg/controller.py b/src/sakia/gui/dialogs/connection_cfg/controller.py index 0019c3697d8f21b36dcbfedb1a9a301ebf904a19..b9165a025c0883a7ed9cae2de10e57d8b5dc85c7 100644 --- a/src/sakia/gui/dialogs/connection_cfg/controller.py +++ b/src/sakia/gui/dialogs/connection_cfg/controller.py @@ -74,23 +74,10 @@ class ConnectionConfigController(QObject): :return: """ connection_cfg = cls.create(parent, app) - connection_cfg.view.set_creation_layout() + connection_cfg.view.set_creation_layout(app.currency) asyncio.ensure_future(connection_cfg.process()) return connection_cfg - @classmethod - def modify_connection(cls, parent, app, connection): - """ - Open a dialog to modify an existing account - :param parent: - :param app: - :param account: - :return: - """ - connection_cfg = cls.create(parent, app, connection=connection) - #connection_cfg.view.set_modification_layout(account.name) - connection_cfg._current_step = 1 - def init_nodes_page(self): self.view.set_steps_buttons_visible(True) model = self.model.init_nodes_model() @@ -150,6 +137,7 @@ class ConnectionConfigController(QObject): self._logger.debug("Wallet mode") self.view.button_next.clicked.connect(self.check_wallet) self.view.edit_uid.hide() + self.view.label_action.hide() self.view.stacked_pages.setCurrentWidget(self.view.page_connection) connection_identity = await self.step_key diff --git a/src/sakia/gui/dialogs/connection_cfg/view.py b/src/sakia/gui/dialogs/connection_cfg/view.py index 45824214fcecfea1c04376f6a12f7ccac2e4fe09..82ada7449678d22b2f4feaba47541dc1a672dd41 100644 --- a/src/sakia/gui/dialogs/connection_cfg/view.py +++ b/src/sakia/gui/dialogs/connection_cfg/view.py @@ -104,23 +104,11 @@ class ConnectionConfigView(QDialog, Ui_ConnectionConfigurationDialog): def set_nodes_model(self, model): self.tree_peers.setModel(model) - def set_creation_layout(self): + def set_creation_layout(self, currency): """ Hide unecessary buttons and display correct title """ - self.setWindowTitle(self.tr("New account")) - self.button_delete.hide() - - def set_modification_layout(self, account_name): - """ - Hide unecessary widgets for account modification - and display correct title - :return: - """ - self.label_action.setText("Edit account uid") - self.edit_account_name.setPlaceholderText(account_name) - self.button_next.setEnabled(True) - self.setWindowTitle(self.tr("Configure {0}".format(account_name))) + self.setWindowTitle(self.tr("New connection to {0} network").format(currency)) def action_show_pubkey(self): salt = self.edit_salt.text() diff --git a/src/sakia/gui/dialogs/transfer/controller.py b/src/sakia/gui/dialogs/transfer/controller.py index 27ef1ae247f71c680d4b918616cae820a2d6214c..8aef7ee5f62a678d8f1b181c26ddb5e100926ef2 100644 --- a/src/sakia/gui/dialogs/transfer/controller.py +++ b/src/sakia/gui/dialogs/transfer/controller.py @@ -137,6 +137,8 @@ class TransferController(QObject): if self.view.recipient_mode() == TransferView.RecipientMode.SEARCH: if self.search_user.current_identity(): pubkey = self.search_user.current_identity().pubkey + elif self.view.recipient_mode() == TransferView.RecipientMode.LOCAL_KEY: + pubkey = self.model.connection_pubkey(self.view.local_key_selected()) else: pubkey = self.view.pubkey_value() return pubkey diff --git a/src/sakia/gui/dialogs/transfer/model.py b/src/sakia/gui/dialogs/transfer/model.py index ebb523d508fabcab80626ed17e4d0f466667ad09..4a32c58f12fa800f2e897471fc19953fb33aa708 100644 --- a/src/sakia/gui/dialogs/transfer/model.py +++ b/src/sakia/gui/dialogs/transfer/model.py @@ -97,3 +97,6 @@ class TransferModel(QObject): def notifications(self): return self.app.parameters.notifications + + def connection_pubkey(self, index): + return self.available_connections()[index].pubkey diff --git a/src/sakia/gui/dialogs/transfer/transfer.ui b/src/sakia/gui/dialogs/transfer/transfer.ui index 5b9a2593595ea6daca3a870e3a868b4efc3c158a..4e43b10f8372229b0bb59c521022cde60d0ddb8f 100644 --- a/src/sakia/gui/dialogs/transfer/transfer.ui +++ b/src/sakia/gui/dialogs/transfer/transfer.ui @@ -7,7 +7,7 @@ <x>0</x> <y>0</y> <width>566</width> - <height>415</height> + <height>450</height> </rect> </property> <property name="windowTitle"> @@ -134,6 +134,23 @@ </item> </layout> </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <property name="topMargin"> + <number>6</number> + </property> + <item> + <widget class="QRadioButton" name="radio_local_key"> + <property name="text"> + <string>Local ke&y</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="combo_local_keys"/> + </item> + </layout> + </item> </layout> </item> </layout> diff --git a/src/sakia/gui/dialogs/transfer/view.py b/src/sakia/gui/dialogs/transfer/view.py index f69fe9037d6c43e0e393d4c05df303b6fe720a20..ebb087c6a40c473d2f5360eb9b7b20e91dd8e014 100644 --- a/src/sakia/gui/dialogs/transfer/view.py +++ b/src/sakia/gui/dialogs/transfer/view.py @@ -19,6 +19,7 @@ class TransferView(QDialog, Ui_TransferMoneyDialog): class RecipientMode(Enum): PUBKEY = 1 SEARCH = 2 + LOCAL_KEY = 3 _button_box_values = { ButtonBoxState.NO_AMOUNT: (False, @@ -38,6 +39,8 @@ class TransferView(QDialog, Ui_TransferMoneyDialog): self.radio_pubkey.toggled.connect(lambda c, radio=TransferView.RecipientMode.PUBKEY: self.recipient_mode_changed(radio)) self.radio_search.toggled.connect(lambda c, radio=TransferView.RecipientMode.SEARCH: self.recipient_mode_changed(radio)) + self.radio_local_key.toggled.connect(lambda c, radio=TransferView.RecipientMode.LOCAL_KEY: self.recipient_mode_changed(radio)) + regexp = QRegExp('^([ a-zA-Z0-9-_:/;*?\[\]\(\)\\\?!^+=@&~#{}|<>%.]{0,255})$') validator = QRegExpValidator(regexp) @@ -51,12 +54,18 @@ class TransferView(QDialog, Ui_TransferMoneyDialog): def recipient_mode(self): if self.radio_search.isChecked(): return TransferView.RecipientMode.SEARCH + elif self.radio_local_key.isChecked(): + return TransferView.RecipientMode.LOCAL_KEY else: return TransferView.RecipientMode.PUBKEY def set_keys(self, connections): for conn in connections: self.combo_connections.addItem(conn.title()) + self.combo_local_keys.addItem(conn.title()) + + def local_key_selected(self): + return self.combo_local_keys.currentIndex() def set_search_user(self, search_user_view): """ @@ -78,6 +87,7 @@ class TransferView(QDialog, Ui_TransferMoneyDialog): """ self.edit_pubkey.setEnabled(radio == TransferView.RecipientMode.PUBKEY) self.search_user.setEnabled(radio == TransferView.RecipientMode.SEARCH) + self.combo_local_keys.setEnabled(radio == TransferView.RecipientMode.LOCAL_KEY) def change_quantitative_amount(self, amount): """ diff --git a/src/sakia/services/blockchain.py b/src/sakia/services/blockchain.py index 5666a55a511253ac71097590eac0039459894b59..49617fb22806969a7992d18892b80b0a3692fd57 100644 --- a/src/sakia/services/blockchain.py +++ b/src/sakia/services/blockchain.py @@ -46,25 +46,26 @@ class BlockchainService(QObject): :param duniterpy.documents.BlockUID network_blockstamp: """ try: - with_identities = await self._blockchain_processor.new_blocks_with_identities(self.currency) - with_money = await self._blockchain_processor.new_blocks_with_money(self.currency) - blocks = await self._blockchain_processor.blocks(with_identities + with_money + [network_blockstamp.number], - self.currency) - await self._sources_service.refresh_sources() - if len(blocks) > 0: - identities = await self._identities_service.handle_new_blocks(blocks) - changed_tx, new_tx, new_dividends = await self._transactions_service.handle_new_blocks(blocks) - self.handle_new_blocks(blocks) - self.app.db.commit() - for tx in changed_tx: - self.app.transaction_state_changed.emit(tx) - for tx in new_tx: - self.app.new_transfer.emit(tx) - for ud in new_dividends: - self.app.new_dividend.emit(ud) - for idty in identities: - self.app.identity_changed.emit(idty) - self.app.sources_refreshed.emit() + if self._blockchain_processor.initialized(self.currency): + with_identities = await self._blockchain_processor.new_blocks_with_identities(self.currency) + with_money = await self._blockchain_processor.new_blocks_with_money(self.currency) + blocks = await self._blockchain_processor.blocks(with_identities + with_money + [network_blockstamp.number], + self.currency) + await self._sources_service.refresh_sources() + if len(blocks) > 0: + identities = await self._identities_service.handle_new_blocks(blocks) + changed_tx, new_tx, new_dividends = await self._transactions_service.handle_new_blocks(blocks) + self.handle_new_blocks(blocks) + self.app.db.commit() + for tx in changed_tx: + self.app.transaction_state_changed.emit(tx) + for tx in new_tx: + self.app.new_transfer.emit(tx) + for ud in new_dividends: + self.app.new_dividend.emit(ud) + for idty in identities: + self.app.identity_changed.emit(idty) + self.app.sources_refreshed.emit() except (NoPeerAvailable, DuniterError) as e: self._logger.debug(str(e)) diff --git a/src/sakia/services/documents.py b/src/sakia/services/documents.py index 2fc43b34c9f41d7d594aa36235ade75b02b9adf9..3be55c31b2e4fae14bc9252c51627b1bd2415b1d 100644 --- a/src/sakia/services/documents.py +++ b/src/sakia/services/documents.py @@ -212,12 +212,13 @@ class DocumentsService: document.sign(self_cert, [key]) return document.signed_raw(self_cert) - def tx_sources(self, amount, amount_base, currency): + def tx_sources(self, amount, amount_base, currency, pubkey): """ Get inputs to generate a transaction with a given amount of money :param int amount: The amount target value :param int amount_base: The amount base target value :param str currency: The community target of the transaction + :param str pubkey: The pubkey owning the sources :return: The list of inputs to use in the transaction document """ @@ -234,7 +235,7 @@ class DocumentsService: return i amount, amount_base = reduce_base(amount, amount_base) - available_sources = self._sources_processor.available(currency) + available_sources = self._sources_processor.available(currency, pubkey) if available_sources: current_base = max([src.base for src in available_sources]) value = 0 @@ -335,7 +336,7 @@ class DocumentsService: :return: the transaction document :rtype: duniterpy.documents.Transaction """ - result = self.tx_sources(int(amount), amount_base, currency) + result = self.tx_sources(int(amount), amount_base, currency, issuer) sources = result[0] computed_outputs = result[1] overheads = result[2]