diff --git a/res/icons/icons.qrc b/res/icons/icons.qrc index 1af72a7c804fbb92b62d948d1fdbea1fdbea3d5b..8fe92ad92db25a2c85261a719b8b1844ae52af9f 100644 --- a/res/icons/icons.qrc +++ b/res/icons/icons.qrc @@ -1,5 +1,7 @@ <RCC> <qresource prefix="icons"> + <file alias="leave_icon">noun_155520_cc.svg</file> + <file alias="new_membership">noun_155540_cc.svg</file> <file alias="payment_icon">noun_178785_cc.svg</file> <file alias="renew_membership">noun_155533_cc.svg</file> <file alias="certification_icon">noun_41979_cc.svg</file> diff --git a/res/ui/community_cfg.ui b/res/ui/community_cfg.ui index 0d18585d3a33202199ab2f5ae604aa3032e3099a..408cf47d40b91f5bc117fb7a2ed3ec55f1ca4752 100644 --- a/res/ui/community_cfg.ui +++ b/res/ui/community_cfg.ui @@ -25,7 +25,7 @@ <property name="currentIndex"> <number>0</number> </property> - <widget class="QWidget" name="page_init"> + <widget class="QWidget" name="page_node"> <layout class="QVBoxLayout" name="verticalLayout_4"> <item> <spacer name="verticalSpacer_2"> @@ -75,45 +75,66 @@ </layout> </item> <item> - <layout class="QHBoxLayout" name="horizontalLayout_2"> + <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="QVBoxLayout" name="verticalLayout_5"> <property name="topMargin"> <number>6</number> </property> <item> - <spacer name="horizontalSpacer"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> + <widget class="QPushButton" name="button_register"> + <property name="text"> + <string>Register your account</string> + </property> + <property name="icon"> + <iconset resource="../icons/icons.qrc"> + <normaloff>:/icons/new_membership</normaloff>:/icons/new_membership</iconset> + </property> + <property name="iconSize"> + <size> + <width>32</width> + <height>32</height> + </size> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="button_connect"> + <property name="text"> + <string>Connect using your account</string> + </property> + <property name="icon"> + <iconset resource="../icons/icons.qrc"> + <normaloff>:/icons/connect_icon</normaloff>:/icons/connect_icon</iconset> </property> - <property name="sizeHint" stdset="0"> + <property name="iconSize"> <size> - <width>40</width> - <height>20</height> + <width>32</width> + <height>32</height> </size> </property> - </spacer> + </widget> </item> <item> - <widget class="QPushButton" name="button_checknode"> + <widget class="QLabel" name="label_error"> <property name="text"> - <string>Check node connectivity</string> + <string/> </property> </widget> </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> </layout> </widget> <widget class="QWidget" name="page_add_nodes"> @@ -173,7 +194,7 @@ </widget> </item> <item> - <layout class="QHBoxLayout" name="horizontalLayout_4"> + <layout class="QHBoxLayout" name="layout_previous_next"> <item> <widget class="QPushButton" name="button_previous"> <property name="enabled"> @@ -211,7 +232,9 @@ </item> </layout> </widget> - <resources/> + <resources> + <include location="../icons/icons.qrc"/> + </resources> <connections> <connection> <sender>button_add</sender> diff --git a/src/cutecoin/core/account.py b/src/cutecoin/core/account.py index 3491a551b163d789f0117d084bb77af855202e41..ac3c6ac9776534fd5eed999d590eb3678c4914ea 100644 --- a/src/cutecoin/core/account.py +++ b/src/cutecoin/core/account.py @@ -300,7 +300,7 @@ class Account(QObject): logging.debug("Key publish : {0}".format(selfcert.signed_raw())) replies = community.bma_access.broadcast(qtbma.wot.Add, {}, {'pubkey': self.pubkey, 'self_': selfcert.signed_raw(), - 'other': []}) + 'other': ""}) for r in replies: r.finished.connect(lambda reply=r: self.__handle_selfcert_replies(replies, reply)) diff --git a/src/cutecoin/core/net/api/bma/__init__.py b/src/cutecoin/core/net/api/bma/__init__.py index 699a8cb7c32fd59d2f0f932711c55e2ac081a626..9e6132c085043cb39514de46798e72763aa138a7 100644 --- a/src/cutecoin/core/net/api/bma/__init__.py +++ b/src/cutecoin/core/net/api/bma/__init__.py @@ -6,6 +6,7 @@ from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply from PyQt5.QtCore import QUrl, QUrlQuery, QTimer, QObject, pyqtSlot import logging import asyncio +import json logger = logging.getLogger("ucoin") diff --git a/src/cutecoin/gui/password_asker.py b/src/cutecoin/gui/password_asker.py index 30815fe826d8901887e4d6a60ff921615545e262..04a7a4f92b9e262bbaafc47500f3da5ea492ded3 100644 --- a/src/cutecoin/gui/password_asker.py +++ b/src/cutecoin/gui/password_asker.py @@ -6,7 +6,7 @@ Created on 24 dec. 2014 import logging import re - +import asyncio from PyQt5.QtCore import QEvent from PyQt5.QtWidgets import QDialog, QMessageBox @@ -29,6 +29,21 @@ class PasswordAskerDialog(QDialog, Ui_PasswordAskerDialog): self.password = "" self.remember = False + def future_exec(self): + future = asyncio.Future() + if not self.remember: + def future_show(): + pwd = self.password + if not self.remember: + self.password = "" + future.set_result(pwd) + self.open() + self.finished.connect(future_show) + else: + self.setResult(QDialog.Accepted) + future.set_result(self.password) + return future + def exec_(self): if not self.remember: super().exec_() diff --git a/src/cutecoin/gui/process_cfg_community.py b/src/cutecoin/gui/process_cfg_community.py index ad439b71893d5a0104dba830cdb57471b3b3e022..36bc609ae56e60e65e1673e4604fd73d74b153e9 100644 --- a/src/cutecoin/gui/process_cfg_community.py +++ b/src/cutecoin/gui/process_cfg_community.py @@ -9,7 +9,7 @@ import asyncio from PyQt5.QtWidgets import QDialog, QMenu, QMessageBox, QApplication from PyQt5.QtGui import QCursor -from PyQt5.QtCore import pyqtSlot, pyqtSignal +from PyQt5.QtCore import pyqtSlot, pyqtSignal, QObject from ..gen_resources.community_cfg_uic import Ui_CommunityConfigurationDialog from ..models.peering import PeeringTreeModel @@ -19,8 +19,9 @@ from ..core.net import Node from . import toast -class Step(): +class Step(QObject): def __init__(self, config_dialog, previous_step=None, next_step=None): + super().__init__() self.previous_step = previous_step self.next_step = next_step self.config_dialog = config_dialog @@ -34,25 +35,93 @@ class StepPageInit(Step): super().__init__(config_dialog) self.node = None logging.debug("Init") - self.config_dialog.button_next.setEnabled(False) - self.config_dialog.button_checknode.clicked.connect(self.check_node) + self.config_dialog.button_connect.clicked.connect(self.check_connect) + self.config_dialog.button_register.clicked.connect(self.check_register) + + @property + def app(self): + return self.config_dialog.app + + @property + def account(self): + return self.config_dialog.account + + @property + def community(self): + return self.config_dialog.community + + @property + def password_asker(self): + return self.config_dialog.password_asker + + @asyncio.coroutine + def coroutine_check_connect(self): + server = self.config_dialog.lineedit_server.text() + port = self.config_dialog.spinbox_port.value() + logging.debug("Is valid ? ") + self.node = yield from Node.from_address(self.config_dialog.app.network_manager, None, server, port) + if self.node: + identity = yield from self.app.identities_registry.future_find(self.account.pubkey, self.community) + if identity.blockchain_state == BlockchainState.NOT_FOUND: + self.config_dialog.label_error.setText(self.tr("Could not find your identity on the network.")) + else: + self.next() + + @pyqtSlot() + def check_connect(self): + logging.debug("Check node") + asyncio.async(self.coroutine_check_connect()) @asyncio.coroutine - def coroutine_check_node(self): + def coroutine_check_register(self): server = self.config_dialog.lineedit_server.text() port = self.config_dialog.spinbox_port.value() logging.debug("Is valid ? ") self.node = yield from Node.from_address(self.config_dialog.app.network_manager, None, server, port) if self.node: - self.config_dialog.button_next.setEnabled(True) - self.config_dialog.button_checknode.setText("Ok !") + community = Community.create(self.app.network_manager, self.node) + identity = yield from self.app.identities_registry.future_find(self.account.pubkey, community) + if identity.blockchain_state == BlockchainState.NOT_FOUND: + password = yield from self.password_asker.future_exec() + if self.password_asker.result() == QDialog.Rejected: + return + self.config_dialog.label_error.setText(self.tr("Broadcasting identity...")) + self.account.selfcert_broadcasted.connect(self.handle_broadcast) + self.account.broadcast_error.connect(self.handle_error) + yield from self.account.send_selfcert(password, community) + self.config_dialog.community = community else: - self.config_dialog.button_next.setEnabled(False) - self.config_dialog.button_checknode.setText("Could not connect.") + self.config_dialog.label_error.setText(self.tr("Could not connect.")) @pyqtSlot() - def check_node(self): - asyncio.async(self.coroutine_check_node()) + def check_register(self): + logging.debug("Check node") + asyncio.async(self.coroutine_check_register()) + + @pyqtSlot(int, str) + def handle_broadcast(self): + if self.app.preferences['notifications']: + toast.display(self.tr("UID broadcast"), self.tr("Identity broadcasted to the network")) + # Disabled : https://github.com/harvimt/quamash/issues/41 + # else: + # QMessageBox.information(self, self.tr("UID broadcast"), self.tr("Identity broadcasted to the network")) + self.account.selfcert_broadcasted.disconnect() + self.account.broadcast_error.disconnect(self.handle_error) + QApplication.restoreOverrideCursor() + self.config_dialog.next() + + @pyqtSlot(int, str) + def handle_error(self, error_code, text): + self.config_dialog.label_error.setText(self.tr("Error") + " " + \ + self.tr("{0} : {1}".format(error_code, text))) + if self.app.preferences['notifications']: + toast.display(self.tr("Error"), self.tr("{0} : {1}".format(error_code, text))) + # Disabled : https://github.com/harvimt/quamash/issues/41 + # else: + # QMessageBox.critical(self, self.tr("Error"), self.tr("{0} : {1}".format(error_code, text))) + self.account.selfcert_broadcasted.disconnect() + self.account.broadcast_error.disconnect(self.handle_error) + QApplication.restoreOverrideCursor() def is_valid(self): return self.node is not None @@ -66,7 +135,8 @@ class StepPageInit(Step): self.config_dialog.community = Community.create(self.config_dialog.app.network_manager, self.node) def display_page(self): - self.config_dialog.button_previous.setEnabled(False) + self.config_dialog.button_next.hide() + self.config_dialog.button_previous.hide() class StepPageAddpeers(Step): @@ -83,6 +153,8 @@ class StepPageAddpeers(Step): pass def display_page(self): + self.config_dialog.button_next.show() + self.config_dialog.button_previous.show() # We add already known peers to the displayed list self.config_dialog.nodes = self.config_dialog.community.network.root_nodes tree_model = PeeringTreeModel(self.config_dialog.community) @@ -141,7 +213,7 @@ class ProcessConfigureCommunity(QDialog, Ui_CommunityConfigurationDialog): self.stacked_pages.setCurrentIndex(next_index) self.step.display_page() else: - asyncio.async(self.final()) + self.add_community_and_close() def previous(self): if self.step.previous_step is not None: @@ -198,60 +270,8 @@ class ProcessConfigureCommunity(QDialog, Ui_CommunityConfigurationDialog): action.setEnabled(False) menu.exec_(QCursor.pos()) - def selfcert_sent(self, pubkey, currency): - if self.app.preferences['notifications']: - toast.display(self.tr("UID Publishing"), - self.tr("Success publishing your UID").format(pubkey, currency)) - else: - QMessageBox.information(self, self.tr("UID Publishing"), - self.tr("Success publishing your UID").format(pubkey, currency)) - self.account.certification_broadcasted.disconnect() - self.account.broadcast_error.disconnect(self.handle_error) - QApplication.restoreOverrideCursor() - self.add_community_and_close() - - @pyqtSlot(int, str) - def handle_broadcast(self, error_code, text): - if self.app.preferences['notifications']: - toast.display(self.tr("UID broadcast"), self.tr("Identity broadcasted to the network")) - else: - QMessageBox.information(self, self.tr("UID broadcast"), self.tr("Identity broadcasted to the network")) - self.account.certification_broadcasted.disconnect() - self.account.broadcast_error.disconnect(self.handle_error) - QApplication.restoreOverrideCursor() - - @pyqtSlot(int, str) - def handle_error(self, error_code, text): - if self.app.preferences['notifications']: - toast.display(self.tr("Error"), self.tr("{0} : {1}".format(error_code, text))) - else: - QMessageBox.critical(self, self.tr("Error"), self.tr("{0} : {1}".format(error_code, text))) - self.account.selfcert_broadcasted.disconnect() - self.account.broadcast_error.disconnect(self.handle_error) - QApplication.restoreOverrideCursor() - - @pyqtSlot() def add_community_and_close(self): if self.community not in self.account.communities: self.account.add_community(self.community) self.accept() - @asyncio.coroutine - def final(self): - identity = yield from self.app.identities_registry.future_find(self.account.pubkey, self.community) - if identity.blockchain_state == BlockchainState.NOT_FOUND: - reply = QMessageBox.question(self, self.tr("Pubkey not found"), - self.tr("""The public key of your account wasn't found in the community. :\n -{0}\n -Would you like to publish the key ?""").format(self.account.pubkey)) - if reply == QMessageBox.Yes: - password = self.password_asker.exec_() - if self.password_asker.result() == QDialog.Rejected: - return - self.account.selfcert_broadcasted.connect(self.handle_broadcast) - self.account.broadcast_error.connect(self.handle_error) - asyncio.async(self.account.send_selfcert(password, self.community)) - else: - self.community_added.emit() - else: - self.community_added.emit()