From aac84aeab34fb139ff135336987e7535adf9d977 Mon Sep 17 00:00:00 2001 From: inso <insomniak.fr@gmaiL.com> Date: Mon, 5 Dec 2016 12:51:56 +0100 Subject: [PATCH] Working on certificaton dialog --- src/sakia/data/processors/certifications.py | 15 ++++ src/sakia/data/processors/sources.py | 1 - src/sakia/data/repositories/certifications.py | 17 +++++ .../dialogs/certification/certification.ui | 53 +------------- .../gui/dialogs/certification/controller.py | 31 ++++---- src/sakia/gui/dialogs/certification/model.py | 70 ++++++------------- 6 files changed, 69 insertions(+), 118 deletions(-) diff --git a/src/sakia/data/processors/certifications.py b/src/sakia/data/processors/certifications.py index 9065ef17..07e96dba 100644 --- a/src/sakia/data/processors/certifications.py +++ b/src/sakia/data/processors/certifications.py @@ -44,6 +44,21 @@ class CertificationsProcessor: """ return self._certifications_repo.get_all(currency=currency, certified=pubkey) + def cert_issuance_delay(self, currency, pubkey, parameters, blockchain_time): + """ + Get the remaining time before being able to issue new certification. + :param str currency: the currency of the certifications + :param str pubkey: the pubkey of the certifications + :param sakia.data.entities.BlockchainParameters parameters: the parameters of the blockchain + :param int blockchain_time: the current time of the blockchain + :return: the remaining time + :rtype: int + """ + certified = self._certifications_repo.get_latest_sent(currency=currency, certifier=pubkey) + if certified and blockchain_time - certified.timestamp < parameters.sig_period: + return parameters.sig_period - (blockchain_time - certified.timestamp) + return 0 + def create_certification(self, currency, cert, blockstamp): """ Creates a certification and insert it in the db diff --git a/src/sakia/data/processors/sources.py b/src/sakia/data/processors/sources.py index 4ebef26a..0d43d4af 100644 --- a/src/sakia/data/processors/sources.py +++ b/src/sakia/data/processors/sources.py @@ -4,7 +4,6 @@ from ..entities import Source from .nodes import NodesProcessor from ..connectors import BmaConnector from duniterpy.api import bma, errors -from duniterpy.documents import Block, BMAEndpoint import asyncio diff --git a/src/sakia/data/repositories/certifications.py b/src/sakia/data/repositories/certifications.py index 87a5f7de..10624202 100644 --- a/src/sakia/data/repositories/certifications.py +++ b/src/sakia/data/repositories/certifications.py @@ -78,6 +78,23 @@ class CertificationsRepo: return [Certification(*data) for data in datas] return [] + def get_latest_sent(self, currency, pubkey): + """ + Get latest sent certification + :param str currency: + :param str pubkey: + :return: + :rtype: sakia.data.entities.Certification + """ + request = """SELECT * FROM certifications + WHERE currency=? AND certifier=? + ORDER BY timestamp DESC + LIMIT 1""" + c = self._conn.execute(request, (currency, pubkey)) + data = c.fetchone() + if data: + return Certification(*data) + def drop(self, certification): """ Drop an existing certification from the database diff --git a/src/sakia/gui/dialogs/certification/certification.ui b/src/sakia/gui/dialogs/certification/certification.ui index b45c0930..7f45c2f7 100644 --- a/src/sakia/gui/dialogs/certification/certification.ui +++ b/src/sakia/gui/dialogs/certification/certification.ui @@ -6,8 +6,8 @@ <rect> <x>0</x> <y>0</y> - <width>715</width> - <height>477</height> + <width>517</width> + <height>316</height> </rect> </property> <property name="windowTitle"> @@ -59,55 +59,6 @@ <property name="topMargin"> <number>6</number> </property> - <item> - <layout class="QHBoxLayout" name="layout_mode_contact"> - <item> - <widget class="QRadioButton" name="radio_contact"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>Con&tact</string> - </property> - <property name="checked"> - <bool>true</bool> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Maximum</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QComboBox" name="combo_contact"> - <property name="enabled"> - <bool>true</bool> - </property> - <property name="sizePolicy"> - <sizepolicy hsizetype="Maximum" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - </widget> - </item> - </layout> - </item> <item> <layout class="QHBoxLayout" name="layout_mode_pubkey"> <item> diff --git a/src/sakia/gui/dialogs/certification/controller.py b/src/sakia/gui/dialogs/certification/controller.py index 7a19764b..d5a64f47 100644 --- a/src/sakia/gui/dialogs/certification/controller.py +++ b/src/sakia/gui/dialogs/certification/controller.py @@ -42,13 +42,11 @@ class CertificationController(ComponentController): :rtype: CertificationController """ - view = CertificationView(parent.view, None, None, communities_names, contacts_names) - model = CertificationModel(None, app, account, community) + view = CertificationView(parent.view, None, None) + model = CertificationModel(None, app) certification = cls(parent, view, model, None, None) - search_user = SearchUserController.create(certification, app, - account=model.account, - community=model.community) + search_user = SearchUserController.create(certification, app) certification.set_search_user(search_user) user_information = UserInformationController.create(certification, app, @@ -156,25 +154,20 @@ class CertificationController(ComponentController): """ pubkey = None - if self.view.recipient_mode() == CertificationView.RecipientMode.CONTACT: - contact_name = self.view.selected_contact() - pubkey = self.model.contact_name_pubkey(contact_name) - elif self.view.recipient_mode() == CertificationView.RecipientMode.SEARCH: + if self.view.recipient_mode() == CertificationView.RecipientMode.SEARCH: if self.search_user.current_identity(): pubkey = self.search_user.current_identity().pubkey else: pubkey = self.view.pubkey_value() return pubkey - @once_at_a_time - @asyncify - async def refresh(self): + def refresh(self): stock = self.model.get_cert_stock() - written, pending = await self.model.nb_certifications() - days, hours, minutes, seconds = await self.model.remaining_time() + written, pending = self.model.nb_certifications() + days, hours, minutes, seconds = self.model.remaining_time() self.view.display_cert_stock(written, pending, stock, days, hours, minutes) - if await self.model.could_certify(): + if self.model.could_certify(): if written < stock or stock == 0: if days+hours+minutes > 0: if days > 0: @@ -197,10 +190,10 @@ class CertificationController(ComponentController): pubkey = self.selected_pubkey() self.user_information.search_identity(pubkey) - def change_current_community(self, index): - self.model.change_community(index) - self.search_user.set_community(self.community) - self.user_information.change_community(self.community) + def change_current_connection(self, index): + self.model.change_connection(index) + self.search_user.set_connection(self.model.connection) + self.user_information.change_connection(self.model.connection) self.refresh() def async_exec(self): diff --git a/src/sakia/gui/dialogs/certification/model.py b/src/sakia/gui/dialogs/certification/model.py index 5bb46468..dbadf913 100644 --- a/src/sakia/gui/dialogs/certification/model.py +++ b/src/sakia/gui/dialogs/certification/model.py @@ -1,8 +1,5 @@ from sakia.gui.component.model import ComponentModel -from duniterpy.api import errors -from sakia.errors import NoPeerAvailable - -import logging +from sakia.data.processors import IdentitiesProcessor, CertificationsProcessor, BlockchainProcessor class CertificationModel(ComponentModel): @@ -10,42 +7,26 @@ class CertificationModel(ComponentModel): The model of Certification component """ - def __init__(self, parent, app, identity, currency, - connections_repo, identities_processor, blockchain_processor): + def __init__(self, parent, app, connection): """ The data model of the certification dialog :param parent: :param sakia.app.Application app: - :param sakia.data.entities.Identity identity: the identity of the certifier - :param str currency: - :param sakia.data.repositories.ConnectionsRepository connections_repo: - :param sakia.data.processors.IdentitiesProcessor identities_processor: - :param sakia.data.processors.BlockchainProcessor blockchain_processor: + :param sakia.data.entities.Connection connection: the connection used to certify """ super().__init__(parent) self.app = app - self.currency = currency - self.connections_repo = connections_repo - self.identities_processor = identities_processor - self.blockchain_processor = blockchain_processor + self.connection = connection + self._certifications_processor = CertificationsProcessor.instanciate(app) + self._identities_processor = IdentitiesProcessor.instanciate(app) + self._blockchain_processor = BlockchainProcessor.instanciate(app) - def contact_name_pubkey(self, name): - """ - Get the pubkey of a contact from its name - :param str name: - :return: - :rtype: str - """ - for contact in self.account.contacts: - if contact['name'] == name: - return contact['pubkey'] - - def change_currency(self, index): + def change_connection(self, index): """ Change current currency :param int index: index of the community in the account list """ - self.currency = self.connections_repo.get_currencies()[index] + self.connection = self.connections_repo.get_currencies()[index] def get_cert_stock(self): """ @@ -55,45 +36,40 @@ class CertificationModel(ComponentModel): """ return self.blockchain_processor.parameters(self.currency).sig_stock - async def remaining_time(self): + def remaining_time(self): """ Get remaining time as a tuple to display :return: a tuple containing (days, hours, minutes, seconds) :rtype: tuple[int] """ - remaining_time = await account_identity.cert_issuance_delay(self.app.identities_registry, self.currency) + remaining_time = self._certifications_processor.cert_issuance_delay(self.connection.currency, + self.connection.pubkey) days, remainder = divmod(remaining_time, 3600 * 24) hours, remainder = divmod(remainder, 3600) minutes, seconds = divmod(remainder, 60) return days, hours, minutes, seconds - async def nb_certifications(self): + def nb_certifications(self): """ Get :return: a tuple containing (written valid certifications, pending certifications) :rtype: tuple[int] """ - account_identity = await self.account.identity(self.currency) - certifications = await account_identity.unique_valid_certified_by(self.app.identities_registry, self.currency) - nb_certifications = len([c for c in certifications if c['block_number']]) - nb_cert_pending = len([c for c in certifications if not c['block_number']]) + certifications = self._certifications_processor.certifications_sent(self.connection.currency, + self.connection.pubkey) + nb_certifications = len([c for c in certifications if c.written_on]) + nb_cert_pending = len([c for c in certifications if not c.written_on]) return nb_certifications, nb_cert_pending - async def could_certify(self): + def could_certify(self): """ Check if the user could theorically certify :return: true if the user can certifiy :rtype: bool """ - account_identity = await self.account.identity(self.community) - is_member = await account_identity.is_member(self.community) - try: - block_0 = await self.community.get_block(0) - except errors.DuniterError as e: - if e.ucode == errors.BLOCK_NOT_FOUND: - block_0 = None - except NoPeerAvailable as e: - logging.debug(str(e)) - block_0 = None - return is_member or not block_0 \ No newline at end of file + is_member = self._identities_processor.get_identity(self.connection.currency, + self.connection.pubkey, + self.connection.pubkey) + + return is_member and self._blockchain_processor.current_buid(self.connection.currency) -- GitLab