From 9edc3b199b25cd1a33630bc413fa76a7af7bda95 Mon Sep 17 00:00:00 2001 From: Inso <insomniak.fr@gmail.com> Date: Sun, 9 Feb 2014 21:54:04 +0100 Subject: [PATCH] Enhancements of communities management --- res/ui/communityTabWidget.ui | 4 +- src/cutecoin/core/config.py | 29 +++++++++++++- src/cutecoin/core/exceptions.py | 25 ++++++++++++ src/cutecoin/gui/addAccountDialog.py | 10 ++--- src/cutecoin/gui/addCommunityDialog.py | 15 ++++++-- src/cutecoin/gui/communityTabWidget.py | 5 +++ src/cutecoin/gui/mainWindow.py | 12 +++--- src/cutecoin/models/account/__init__.py | 5 ++- .../models/account/communities/__init__.py | 16 ++++---- src/cutecoin/models/community/__init__.py | 11 ++++-- .../models/community/issuancesListModel.py | 33 ++++++++++++++++ .../models/community/membersListModel.py | 38 +++++++++++++++++++ src/cutecoin/models/community/treeModel.py | 8 ++-- 13 files changed, 175 insertions(+), 36 deletions(-) create mode 100644 src/cutecoin/core/exceptions.py create mode 100644 src/cutecoin/models/community/issuancesListModel.py create mode 100644 src/cutecoin/models/community/membersListModel.py diff --git a/res/ui/communityTabWidget.ui b/res/ui/communityTabWidget.ui index acee98be..41c59598 100644 --- a/res/ui/communityTabWidget.ui +++ b/res/ui/communityTabWidget.ui @@ -24,7 +24,7 @@ </widget> </item> <item> - <widget class="QListView" name="communityMembers_2"/> + <widget class="QListView" name="communityMembersList"/> </item> </layout> </item> @@ -38,7 +38,7 @@ </widget> </item> <item> - <widget class="QListView" name="listView"/> + <widget class="QListView" name="issuancesList"/> </item> </layout> </item> diff --git a/src/cutecoin/core/config.py b/src/cutecoin/core/config.py index ca1ce159..74b13d1f 100644 --- a/src/cutecoin/core/config.py +++ b/src/cutecoin/core/config.py @@ -4,9 +4,34 @@ Created on 7 févr. 2014 @author: inso ''' - +import logging +from optparse import OptionParser data = { 'home' : '~/.cutecoin'} def parseArguments(argv): - #TODO: Parsing d'arguments + parser = OptionParser() + + parser.add_option("-v", "--verbose", + action="store_true", dest="verbose", default=False, + help="Print INFO messages to stdout") + + parser.add_option("-d", "--debug", + action="store_true", dest="debug", default=False, + help="Print DEBUG messages to stdout") + + + parser.add_option("--home", dest="home", default="~/.cutecoin", + help="Set another home for cutecoin.") + + (options, args) = parser.parse_args(argv) + + if options.debug == True: + logging.basicConfig(format='%(levelname)s:%(module)s:%(message)s', level=logging.DEBUG) + elif options.verbose == True: + logging.basicConfig(format='%(levelname)s:%(message)s', level=logging.INFO) + else: + logging.getLogger().propagate = False + + data['home'] = options.home + pass \ No newline at end of file diff --git a/src/cutecoin/core/exceptions.py b/src/cutecoin/core/exceptions.py new file mode 100644 index 00000000..40e712bc --- /dev/null +++ b/src/cutecoin/core/exceptions.py @@ -0,0 +1,25 @@ +''' +Created on 9 févr. 2014 + +@author: inso +''' + +class Error(Exception): + def __init__(self, message): + ''' + Constructor + ''' + self.message = "Error : " + message + + +class NotMemberOfCommunityError(Error): + ''' + Exception raised for error in the input + ''' + + + def __init__(self, account, community): + ''' + Constructor + ''' + super(NotMemberOfCommunityError, self).__init__(account + " is not a member of " + community) diff --git a/src/cutecoin/gui/addAccountDialog.py b/src/cutecoin/gui/addAccountDialog.py index 00c2caec..e4fdc2c2 100644 --- a/src/cutecoin/gui/addAccountDialog.py +++ b/src/cutecoin/gui/addAccountDialog.py @@ -26,7 +26,6 @@ class AddAccountDialog(QDialog, Ui_AddAccountDialog): # Set up the user interface from Designer. super(AddAccountDialog, self).__init__() self.setupUi(self) - self.dialog = AddCommunityDialog(self) self.mainWindow = mainWindow self.buttonBox.accepted.connect(self.mainWindow.actionAddAccount) @@ -40,15 +39,16 @@ class AddAccountDialog(QDialog, Ui_AddAccountDialog): self.gpgKeysList.addItem(key['uids'][0]) self.account = Account(availableKeys[0]['keyid'], "", Communities()) - self.gpgKeysList.setEnabled() + self.gpgKeysList.setEnabled(True) self.gpgKeysList.currentIndexChanged[int].connect(self.keyChanged) + self.communityDialog = AddCommunityDialog(self) def openAddCommunityDialog(self): - self.dialog.setAccount(self.account) - self.dialog.exec_() + self.communityDialog.setAccount(self.account) + self.communityDialog.exec_() def actionAddCommunity(self): - self.gpgKeysList.setDisabled() + self.gpgKeysList.setEnabled(False) self.gpgKeysList.disconnect() self.communitiesList.setModel(CommunitiesListModel(self.account)) diff --git a/src/cutecoin/gui/addCommunityDialog.py b/src/cutecoin/gui/addCommunityDialog.py index ad77ba71..9c37f280 100644 --- a/src/cutecoin/gui/addCommunityDialog.py +++ b/src/cutecoin/gui/addCommunityDialog.py @@ -4,9 +4,10 @@ Created on 2 févr. 2014 @author: inso ''' from cutecoin.gen_resources.addCommunityDialog_uic import Ui_AddCommunityDialog -from PyQt5.QtWidgets import QDialog +from PyQt5.QtWidgets import QDialog, QErrorMessage from cutecoin.models.community.treeModel import CommunityTreeModel from cutecoin.models.node import MainNode +from cutecoin.core.exceptions import NotMemberOfCommunityError class AddCommunityDialog(QDialog, Ui_AddCommunityDialog): ''' @@ -32,8 +33,14 @@ class AddCommunityDialog(QDialog, Ui_AddCommunityDialog): ''' server = self.serverEdit.text() port = self.portBox.value() - community = self.account.communities.addCommunity(MainNode(server, port), self.account.keyFingerprint()) - self.account.wallets.addWallet(community.currency) - self.communityView.setModel( CommunityTreeModel(community) ) + #TODO: Manage case where account is not member of the community + #An error must be displayed and the community must not be added + try: + community = self.account.communities.addCommunity(MainNode(server, port), self.account.keyFingerprint()) + self.account.wallets.addWallet(community.currency) + self.communityView.setModel( CommunityTreeModel(community) ) + except NotMemberOfCommunityError as e: + QErrorMessage(self).showMessage(e.message) + diff --git a/src/cutecoin/gui/communityTabWidget.py b/src/cutecoin/gui/communityTabWidget.py index ffd81cd3..a87dfc38 100644 --- a/src/cutecoin/gui/communityTabWidget.py +++ b/src/cutecoin/gui/communityTabWidget.py @@ -4,6 +4,8 @@ Created on 2 févr. 2014 @author: inso ''' from PyQt5.QtWidgets import QWidget +from cutecoin.models.community.membersListModel import MembersListModel +from cutecoin.models.community.issuancesListModel import IssuancesListModel from cutecoin.gen_resources.communityTabWidget_uic import Ui_CommunityTabWidget class CommunityTabWidget(QWidget, Ui_CommunityTabWidget): @@ -17,5 +19,8 @@ class CommunityTabWidget(QWidget, Ui_CommunityTabWidget): super(CommunityTabWidget, self).__init__() self.setupUi(self) self.community = community + self.communityMembersList.setModel(MembersListModel(community)) + self.issuancesList.setModel(IssuancesListModel(community)) + diff --git a/src/cutecoin/gui/mainWindow.py b/src/cutecoin/gui/mainWindow.py index 1c3bb62a..f6722673 100644 --- a/src/cutecoin/gui/mainWindow.py +++ b/src/cutecoin/gui/mainWindow.py @@ -26,13 +26,13 @@ class MainWindow(QMainWindow, Ui_MainWindow): self.core = core def openAddAccountDialog(self): - self.dialog = AddAccountDialog(self) - self.dialog.setData() - self.dialog.exec_() + self.addAccountDialog = AddAccountDialog(self) + self.addAccountDialog.setData() + self.addAccountDialog.exec_() def actionAddAccount(self): - self.dialog.account.name = self.dialog.accountName.text() - self.core.addAccount(self.dialog.account) + self.addAccountDialog.account.name = self.addAccountDialog.accountName.text() + self.core.addAccount(self.addAccountDialog.account) self.refreshMainWindow() ''' @@ -49,7 +49,7 @@ class MainWindow(QMainWindow, Ui_MainWindow): self.walletsList.setModel(WalletsListModel(self.core.currentAccount)) self.walletContent.setModel(WalletListModel(self.core.currentAccount.wallets.walletsList[0])) for community in self.core.currentAccount.communities.communitiesList: - self.communitiesTab.addPage(CommunityTabWidget(community), community.name()) + self.communitiesTab.addTab(CommunityTabWidget(community), community.name()) #TODO: self.transactionsReceived.setModel() #TODO: self.transactionsSent.setModel() diff --git a/src/cutecoin/models/account/__init__.py b/src/cutecoin/models/account/__init__.py index 5234def8..64245b78 100644 --- a/src/cutecoin/models/account/__init__.py +++ b/src/cutecoin/models/account/__init__.py @@ -6,6 +6,7 @@ Created on 1 févr. 2014 import ucoinpy as ucoin import gnupg +import logging from cutecoin.models.account.wallets import Wallets class Account(object): @@ -34,9 +35,9 @@ class Account(object): def keyFingerprint(self): gpg = gnupg.GPG() availableKeys = gpg.list_keys() - print(self.gpgKey) + logging.debug(self.gpgKey) for k in availableKeys: - print(k) + logging.debug(k) if k['keyid'] == self.gpgKey: return k['fingerprint'] return "" diff --git a/src/cutecoin/models/account/communities/__init__.py b/src/cutecoin/models/account/communities/__init__.py index 56097ebe..47a5ed06 100644 --- a/src/cutecoin/models/account/communities/__init__.py +++ b/src/cutecoin/models/account/communities/__init__.py @@ -5,6 +5,8 @@ Created on 5 févr. 2014 ''' import ucoinpy as ucoin from cutecoin.models.community import Community +from cutecoin.core.exceptions import NotMemberOfCommunityError +import logging class Communities(object): ''' @@ -16,23 +18,23 @@ class Communities(object): ''' self.communitiesList = [] - def getCommunity(self, currency): + def getCommunity(self, amendmentId): for com in self.communitiesList: - #TODO: Compare communities by amendment hash instead of currency - if com.currency == currency: + if com.currentAmendmentId() == amendmentId: return com - def addCommunity(self, mainNode, accountFingerprint): + def addCommunity(self, mainNode, keyFingerprint): community = Community(mainNode) self.members = community.ucoinRequest(lambda:ucoin.hdc.amendments.view.Members(community.currentAmendmentId()).get) - print(accountFingerprint) + logging.debug("Account fingerprint : " + keyFingerprint) for member in self.members: - print(member) - if member['value'] == accountFingerprint: + logging.debug(member) + if member['value'] == keyFingerprint: self.communitiesList.append(community) return community + raise NotMemberOfCommunityError(keyFingerprint, community.currency + "-" + community.currentAmendmentId()) return None #TODO: Jsonify this model diff --git a/src/cutecoin/models/community/__init__.py b/src/cutecoin/models/community/__init__.py index 69db60d1..0a4d0784 100644 --- a/src/cutecoin/models/community/__init__.py +++ b/src/cutecoin/models/community/__init__.py @@ -7,6 +7,7 @@ Created on 1 févr. 2014 import ucoinpy as ucoin import hashlib import json +import logging class Community(object): ''' @@ -27,7 +28,10 @@ class Community(object): ''' Listing members of a community ''' - members = self.ucoinRequest(lambda : self.ucoinInstance.hdc.amendments.view.Members().get) + membersList = self.ucoinRequest(lambda : self.ucoinInstance.hdc.amendments.view.Members(self.currentAmendmentId()).get) + members = [] + for m in membersList: + members.append(m['value']) return members def ucoinRequest(self, request): @@ -35,7 +39,7 @@ class Community(object): if node.available == True: self.ucoinInstance.settings['server'] = node.server self.ucoinInstance.settings['port'] = node.port - print("Trying to connect to : " + node.getText()) + logging.debug("Trying to connect to : " + node.getText()) return (request())() raise RuntimeError("Cannot connect to any node") @@ -45,8 +49,7 @@ class Community(object): currentAmendment = self.ucoinRequest(lambda:ucoin.hdc.amendments.Current().get) currentAmendmentHash = hashlib.sha1(currentAmendment['raw'].encode('utf-8')).hexdigest().upper() amendmentId = str(currentAmendment["number"]) + "-" + currentAmendmentHash - #TODO: Distinct debug logging and info logging for a -d parameter - print("Amendment : " + amendmentId) + logging.debug("Amendment : " + amendmentId) return amendmentId def name(self): diff --git a/src/cutecoin/models/community/issuancesListModel.py b/src/cutecoin/models/community/issuancesListModel.py new file mode 100644 index 00000000..b3a52607 --- /dev/null +++ b/src/cutecoin/models/community/issuancesListModel.py @@ -0,0 +1,33 @@ +''' +Created on 5 févr. 2014 + +@author: inso +''' + +from PyQt5.QtCore import QAbstractListModel, Qt + +class IssuancesListModel(QAbstractListModel): + ''' + A Qt abstract item model to display communities in a tree + ''' + def __init__(self, community, parent=None): + ''' + Constructor + ''' + super(IssuancesListModel, self).__init__(parent) + #TODO: Manage issuances + self.issuances = [] + + + def rowCount(self ,parent): + return len(self.issuanes) + + def data(self,index,role): + + if role == Qt.DisplayRole: + row=index.row() + value = self.issuances[row] + return value + + def flags(self,index): + return Qt.ItemIsSelectable | Qt.ItemIsEnabled diff --git a/src/cutecoin/models/community/membersListModel.py b/src/cutecoin/models/community/membersListModel.py new file mode 100644 index 00000000..06aeba9c --- /dev/null +++ b/src/cutecoin/models/community/membersListModel.py @@ -0,0 +1,38 @@ +''' +Created on 5 févr. 2014 + +@author: inso +''' + +import ucoinpy as ucoin +from PyQt5.QtCore import QAbstractListModel, Qt + +class MembersListModel(QAbstractListModel): + ''' + A Qt abstract item model to display communities in a tree + ''' + def __init__(self, community, parent=None): + ''' + Constructor + ''' + super(MembersListModel, self).__init__(parent) + fingerprints = community.members() + self.members = [] + '''for f in fingerprints: + keys = community.ucoinRequest(lambda : ucoin.pks.Lookup().get) + if len(keys) > 0: + self.members.append(keys[0]['key']['name']) + ''' + + def rowCount(self ,parent): + return len(self.members) + + def data(self,index,role): + + if role == Qt.DisplayRole: + row=index.row() + value = self.members[row] + return value + + def flags(self,index): + return Qt.ItemIsSelectable | Qt.ItemIsEnabled diff --git a/src/cutecoin/models/community/treeModel.py b/src/cutecoin/models/community/treeModel.py index 1515fc40..2180564f 100644 --- a/src/cutecoin/models/community/treeModel.py +++ b/src/cutecoin/models/community/treeModel.py @@ -7,6 +7,7 @@ Created on 5 févr. 2014 from PyQt5.QtCore import QAbstractItemModel, QModelIndex, Qt from cutecoin.models.node.itemModel import MainNodeItem, NodeItem from cutecoin.models.community.itemModel import CommunityItemModel +import logging class CommunityTreeModel(QAbstractItemModel): ''' @@ -87,14 +88,13 @@ class CommunityTreeModel(QAbstractItemModel): def refreshTreeNodes(self): - - print("root : " + self.rootItem.data(0)) + logging.debug("root : " + self.rootItem.data(0)) for mainNode in self.community.knownNodes: mainNodeItem = MainNodeItem(mainNode, self.rootItem) - print("mainNode : " + mainNode.getText() + " / " + mainNodeItem.data(0)) + logging.debug("mainNode : " + mainNode.getText() + " / " + mainNodeItem.data(0)) self.rootItem.appendChild(mainNodeItem) for node in mainNode.downstreamPeers(): nodeItem = NodeItem(node, mainNodeItem) - print("\t node : " + node.getText()+ " / " + nodeItem.data(0)) + logging.debug("\t node : " + node.getText()+ " / " + nodeItem.data(0)) mainNodeItem.appendChild(nodeItem) -- GitLab