diff --git a/res/ui/communityTabWidget.ui b/res/ui/communityTabWidget.ui index acee98be84461283ea56ef50585dfc4c005bb08c..41c5959856af00f6e1850d70bf949e6b4479c4b7 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 ca1ce159d622c6858f2051d34ebd4dd8bd356ce1..74b13d1fe3e6d3b5d9b1afe8932879a4e4bbb4ca 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 0000000000000000000000000000000000000000..40e712bc18e496729d2cd084180d5711ee9f0195 --- /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 00c2caec9ba2ed66a4bdc2f8de8a16f7d0502cbb..e4fdc2c2e9573354d4785d5af7b32b00e12a9c73 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 ad77ba7115001e87d58fbe2b8a4a8b9421bf8243..9c37f280308646da9dad397d4bebabeee98b120b 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 ffd81cd374fe31f443f883943f7370cb72503327..a87dfc380c8ce679196bc32a2b91557e858c74bb 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 1c3bb62a5d4c45620380e7ffebfac09a0823c9f7..f672267301977007da1ed6906e3a4a0fc61cb281 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 5234def89646bf559473d18d7341c45fedb5472c..64245b78645339aa9a8c9fb6be5854902f8da24f 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 56097ebe66ae93cfefadd40f4bb4ec2e8b4aa202..47a5ed0687d9194c4db95f061d3a4ebab5430c07 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 69db60d1e9d20902d014f83bc1a793c5eb877bf7..0a4d07847079c3d4f605d7f2631bd47546f5286e 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 0000000000000000000000000000000000000000..b3a52607ec38bbb0de724be02bb05d7540b1f297 --- /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 0000000000000000000000000000000000000000..06aeba9c6019597c8bcce4a3a75b9090f2671dbd --- /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 1515fc4084fd21c8f609c57f2e963e5176e14e18..2180564f5f657fc441606f56fd34251457c0b01e 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)