diff --git a/res/ui/accountConfigurationDialog.ui b/res/ui/accountConfigurationDialog.ui index 28fa7b470949e431eecced76fa6acb510025703f..114ae46a919eda7237581de75589a55b1934222e 100644 --- a/res/ui/accountConfigurationDialog.ui +++ b/res/ui/accountConfigurationDialog.ui @@ -20,7 +20,7 @@ <item> <widget class="QStackedWidget" name="stacked_pages"> <property name="currentIndex"> - <number>0</number> + <number>1</number> </property> <widget class="QWidget" name="page_init"> <layout class="QVBoxLayout" name="verticalLayout_4"> @@ -102,30 +102,32 @@ <item> <layout class="QVBoxLayout" name="verticalLayout_6"> <item> - <layout class="QHBoxLayout" name="horizontalLayout_5"> - <item> - <widget class="QLineEdit" name="edit_secretkey_path"> - <property name="readOnly"> - <bool>true</bool> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="button_import"> - <property name="text"> - <string>Import a secret key</string> - </property> - </widget> - </item> - </layout> + <layout class="QHBoxLayout" name="horizontalLayout_5"/> + </item> + <item> + <widget class="QLineEdit" name="edit_email"> + <property name="placeholderText"> + <string>Your email</string> + </property> + </widget> </item> <item> - <widget class="QLabel" name="label_4"> + <widget class="QLineEdit" name="edit_password"> + <property name="echoMode"> + <enum>QLineEdit::Password</enum> + </property> + <property name="placeholderText"> + <string>Your password</string> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="edit_password_repeat"> <property name="text"> - <string>OR</string> + <string/> </property> - <property name="alignment"> - <set>Qt::AlignCenter</set> + <property name="placeholderText"> + <string>Please repeat your password</string> </property> </widget> </item> @@ -330,22 +332,6 @@ </hint> </hints> </connection> - <connection> - <sender>button_import</sender> - <signal>clicked()</signal> - <receiver>AccountConfigurationDialog</receiver> - <slot>open_import_key()</slot> - <hints> - <hint type="sourcelabel"> - <x>312</x> - <y>175</y> - </hint> - <hint type="destinationlabel"> - <x>199</x> - <y>149</y> - </hint> - </hints> - </connection> <connection> <sender>button_generate</sender> <signal>clicked()</signal> diff --git a/res/ui/createWalletDialog.ui b/res/ui/createWalletDialog.ui index c1e75a8b4708dc58d875f36977de78f6ee6632af..4a611d7a5caf318d910868867b3f63d65e2c6efb 100644 --- a/res/ui/createWalletDialog.ui +++ b/res/ui/createWalletDialog.ui @@ -53,98 +53,6 @@ </item> </layout> </widget> - <widget class="QWidget" name="page_key"> - <layout class="QVBoxLayout" name="verticalLayout_4"> - <item> - <widget class="QGroupBox" name="groupBox"> - <property name="title"> - <string>Private key</string> - </property> - <layout class="QVBoxLayout" name="verticalLayout_2"> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_5"> - <item> - <widget class="QLineEdit" name="edit_secretkey_path"/> - </item> - <item> - <widget class="QPushButton" name="button_import"> - <property name="text"> - <string>Import a secret key</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <widget class="QLabel" name="label_4"> - <property name="text"> - <string>OR</string> - </property> - <property name="alignment"> - <set>Qt::AlignCenter</set> - </property> - </widget> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_6"> - <property name="topMargin"> - <number>0</number> - </property> - <item> - <widget class="QLabel" name="label_fingerprint"> - <property name="text"> - <string/> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="button_generate"> - <property name="text"> - <string>Generate a secret key</string> - </property> - </widget> - </item> - </layout> - </item> - </layout> - </widget> - </item> - </layout> - </widget> - <widget class="QWidget" name="page_node"> - <layout class="QVBoxLayout" name="verticalLayout_5"> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_3"> - <property name="topMargin"> - <number>0</number> - </property> - <item> - <widget class="QLabel" name="label_2"> - <property name="text"> - <string>Main node :</string> - </property> - </widget> - </item> - <item> - <widget class="QLineEdit" name="edit_address"/> - </item> - <item> - <widget class="QSpinBox" name="spinbox_port"> - <property name="minimum"> - <number>1</number> - </property> - <property name="maximum"> - <number>65535</number> - </property> - <property name="value"> - <number>8881</number> - </property> - </widget> - </item> - </layout> - </item> - </layout> - </widget> </widget> </item> <item> @@ -202,70 +110,6 @@ </widget> <resources/> <connections> - <connection> - <sender>button_import</sender> - <signal>clicked()</signal> - <receiver>CreateWalletDialog</receiver> - <slot>open_import_key()</slot> - <hints> - <hint type="sourcelabel"> - <x>333</x> - <y>54</y> - </hint> - <hint type="destinationlabel"> - <x>199</x> - <y>86</y> - </hint> - </hints> - </connection> - <connection> - <sender>button_generate</sender> - <signal>clicked()</signal> - <receiver>CreateWalletDialog</receiver> - <slot>open_generate_key()</slot> - <hints> - <hint type="sourcelabel"> - <x>295</x> - <y>110</y> - </hint> - <hint type="destinationlabel"> - <x>199</x> - <y>86</y> - </hint> - </hints> - </connection> - <connection> - <sender>edit_address</sender> - <signal>textChanged(QString)</signal> - <receiver>CreateWalletDialog</receiver> - <slot>check()</slot> - <hints> - <hint type="sourcelabel"> - <x>200</x> - <y>83</y> - </hint> - <hint type="destinationlabel"> - <x>199</x> - <y>134</y> - </hint> - </hints> - </connection> - <connection> - <sender>spinbox_port</sender> - <signal>valueChanged(int)</signal> - <receiver>CreateWalletDialog</receiver> - <slot>check()</slot> - <hints> - <hint type="sourcelabel"> - <x>357</x> - <y>83</y> - </hint> - <hint type="destinationlabel"> - <x>199</x> - <y>134</y> - </hint> - </hints> - </connection> <connection> <sender>edit_name</sender> <signal>textChanged(QString)</signal> diff --git a/res/ui/transferDialog.ui b/res/ui/transferDialog.ui index 42436b5f256ec6fb0f1dabe9c37c4ca845ab59a4..1f08eac3c3d8d985af53d6b60f10110e70db6ecf 100644 --- a/res/ui/transferDialog.ui +++ b/res/ui/transferDialog.ui @@ -107,107 +107,6 @@ </item> </layout> </item> - <item> - <widget class="QGroupBox" name="groupBox_3"> - <property name="title"> - <string>Coins</string> - </property> - <layout class="QVBoxLayout" name="verticalLayout_5"> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_5"> - <property name="topMargin"> - <number>5</number> - </property> - <item> - <layout class="QVBoxLayout" name="verticalLayout_6"> - <property name="leftMargin"> - <number>6</number> - </property> - <item> - <widget class="QListView" name="list_wallet"/> - </item> - </layout> - </item> - <item> - <layout class="QVBoxLayout" name="verticalLayout_4"> - <property name="rightMargin"> - <number>0</number> - </property> - <item> - <widget class="QPushButton" name="button_add"> - <property name="text"> - <string>>></string> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="button_remove"> - <property name="text"> - <string><<</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QVBoxLayout" name="verticalLayout_7"> - <property name="spacing"> - <number>0</number> - </property> - <property name="leftMargin"> - <number>0</number> - </property> - <item> - <widget class="QLineEdit" name="edit_message"> - <property name="placeholderText"> - <string>A message</string> - </property> - </widget> - </item> - <item> - <widget class="QListView" name="list_coins_sent"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>8</verstretch> - </sizepolicy> - </property> - </widget> - </item> - </layout> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_6"> - <property name="topMargin"> - <number>5</number> - </property> - <item> - <spacer name="horizontalSpacer"> - <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="QLabel" name="label_total"> - <property name="text"> - <string/> - </property> - </widget> - </item> - </layout> - </item> - </layout> - </widget> - </item> </layout> </widget> </item> @@ -257,38 +156,6 @@ </hint> </hints> </connection> - <connection> - <sender>button_add</sender> - <signal>clicked()</signal> - <receiver>TransferMoneyDialog</receiver> - <slot>add_coins_to_transfer()</slot> - <hints> - <hint type="sourcelabel"> - <x>201</x> - <y>327</y> - </hint> - <hint type="destinationlabel"> - <x>199</x> - <y>244</y> - </hint> - </hints> - </connection> - <connection> - <sender>button_remove</sender> - <signal>clicked()</signal> - <receiver>TransferMoneyDialog</receiver> - <slot>remove_coins_from_transfer()</slot> - <hints> - <hint type="sourcelabel"> - <x>201</x> - <y>373</y> - </hint> - <hint type="destinationlabel"> - <x>199</x> - <y>244</y> - </hint> - </hints> - </connection> <connection> <sender>combo_wallets</sender> <signal>currentIndexChanged(int)</signal> diff --git a/res/ui/walletTabWidget.ui b/res/ui/walletTabWidget.ui deleted file mode 100644 index a8e08a353808a7ebec33ce02254abd125c4d3357..0000000000000000000000000000000000000000 --- a/res/ui/walletTabWidget.ui +++ /dev/null @@ -1,75 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>WalletTabWidget</class> - <widget class="QWidget" name="WalletTabWidget"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>400</width> - <height>300</height> - </rect> - </property> - <property name="windowTitle"> - <string>walletTabWidget</string> - </property> - <layout class="QHBoxLayout" name="horizontalLayout"> - <item> - <layout class="QVBoxLayout" name="verticalLayout_6"> - <item> - <widget class="QLabel" name="label"> - <property name="text"> - <string>Trusts and hosters</string> - </property> - </widget> - </item> - <item> - <widget class="QTreeView" name="trusts_tree_view"/> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_2"> - <property name="topMargin"> - <number>5</number> - </property> - <item> - <spacer name="horizontalSpacer"> - <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="QLabel" name="label_2"> - <property name="text"> - <string>Required trust to accept a transaction : </string> - </property> - </widget> - </item> - <item> - <widget class="QSpinBox" name="spinbox_trusts"> - <property name="maximum"> - <number>999</number> - </property> - </widget> - </item> - </layout> - </item> - </layout> - </item> - <item> - <layout class="QVBoxLayout" name="verticalLayout"/> - </item> - </layout> - </widget> - <resources/> - <connections/> - <slots> - <slot>required_trusts_changed(int)</slot> - </slots> -</ui> diff --git a/src/cutecoin/core/__init__.py b/src/cutecoin/core/__init__.py index 7be79c4fd556990173769a9518b9dd92816a888d..0a004636912e28563ee79e19e70b16499d97a630 100644 --- a/src/cutecoin/core/__init__.py +++ b/src/cutecoin/core/__init__.py @@ -73,13 +73,6 @@ class Core(object): data = json.load(json_data) json_data.close() - for account_name in data['local_accounts']: - account_path = os.path.join(config.parameters['home'], - account_name, 'properties') - json_data = open(account_path, 'r') - data = json.load(json_data) - self.accounts.append(Account.load(data)) - def save(self, account): with open(config.parameters['data'], 'w') as outfile: json.dump(self.jsonify(), outfile, indent=4, sort_keys=True) diff --git a/src/cutecoin/core/config.py b/src/cutecoin/core/config.py index 38c16c2322c9f35e483a42ddc325a2e3525517ca..7365757c161cd943b89130b4dbfa75eff2d8de68 100644 --- a/src/cutecoin/core/config.py +++ b/src/cutecoin/core/config.py @@ -7,7 +7,6 @@ Created on 7 févr. 2014 import logging from optparse import OptionParser from os import environ, path -import ucoin import gnupg @@ -48,8 +47,4 @@ def parse_arguments(argv): else: logging.getLogger().propagate = False - ucoin.settings['gpg'] = gnupg.GPG() - logger = logging.getLogger("gnupg") - logger.setLevel(logging.INFO) - pass diff --git a/src/cutecoin/gui/generateAccountKeyDialog.py b/src/cutecoin/gui/generateAccountKeyDialog.py index 05cbe9618f80044245b7d5b354d71231e6f8398d..63a66e1ec3e78581050aace2392591f1790875e7 100644 --- a/src/cutecoin/gui/generateAccountKeyDialog.py +++ b/src/cutecoin/gui/generateAccountKeyDialog.py @@ -3,6 +3,8 @@ Created on 22 mai 2014 @author: inso ''' +from ucoinpy.key import SigningKey + import re import logging from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QMessageBox, QProgressDialog @@ -32,47 +34,25 @@ class GenerateAccountKeyDialog(QDialog, Ui_GenerateKeyDialog): super(GenerateAccountKeyDialog, self).__init__() self.setupUi(self) self.account = account - self.main_window = parent self.button_box.button(QDialogButtonBox.Ok).setEnabled(False) def accept(self): name = self.edit_name.text() - passphrase = self.edit_password.text() - input_data = self.account.gpg.gen_key_input(key_type="RSA", key_length=2048, - name_real=name, passphrase=passphrase, - name_comment="Account generated by cutecoin") - - self.progress_dialog = QProgressDialog(self) - self.progress_dialog.setLabelText("Generating key...") - self.progress_dialog.setMinimum(0) - self.progress_dialog.setMaximum(0) - self.progress_dialog.setCancelButton(None) - self.progress_dialog.setValue(-1) - self.progress_dialog.show() - self.gen_task = TaskGenKey() - self.gen_task.input_data = input_data - self.gen_task.account = self.account - self.gen_task.taskFinished.connect(self.gen_finished) - self.gen_task.run() + password = self.edit_password.text() + password_repeat = self.edit_password_repeat.text() + salt = self.edit_email.text() def gen_finished(self): self.progress_dialog.close() - if self.account.keyid is not '': - self.account.gpg.delete_keys(self.account.keyid) - - key = self.gen_task.key - secret_keys = self.account.gpg.list_keys(True) - for k in secret_keys: - if k['fingerprint'] == key.fingerprint: - self.account.keyid = k['keyid'] + self.account.key = SigningKey(self.salt, self.password) logging.debug("Key generated : " + self.account.keyid) QMessageBox.information(self, "Key generation", "Key " + - key.fingerprint + " has been generated", + self.account.key.pubkey + " has been generated", QMessageBox.Ok) - self.main_window.label_fingerprint.setText("Key : " + key.fingerprint) + self.main_window.label_pubkey.setText("Key : " + self.account.key.public_key) self.main_window.button_next.setEnabled(True) self.close() @@ -81,8 +61,8 @@ class GenerateAccountKeyDialog(QDialog, Ui_GenerateKeyDialog): self.label_errors.setText("Please enter a password with more than 8 characters") self.button_box.button(QDialogButtonBox.Ok).setEnabled(False) return - elif self.edit_password.text() != self.edit_password_bis.text(): - self.label_errors.setText("Passphrases do not match") + elif self.edit_password.text() != self.edit_password_repeat.text(): + self.label_errors.setText("Passwords do not match") self.button_box.button(QDialogButtonBox.Ok).setEnabled(False) return else: diff --git a/src/cutecoin/gui/generateWalletKeyDialog.py b/src/cutecoin/gui/generateWalletKeyDialog.py deleted file mode 100644 index 01e1a158c6ff522b5318855fe4b66eb0d95c0842..0000000000000000000000000000000000000000 --- a/src/cutecoin/gui/generateWalletKeyDialog.py +++ /dev/null @@ -1,95 +0,0 @@ -''' -Created on 22 mai 2014 - -@author: inso -''' -import re -import logging -from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QMessageBox, QProgressDialog -from PyQt5.QtCore import QThread, pyqtSignal - -from cutecoin.gen_resources.generateKeyDialog_uic import Ui_GenerateKeyDialog - - -class TaskGenKey(QThread): - taskFinished = pyqtSignal() - - def run(self): - self.key = self.account.gpg.gen_key(self.input_data) - self.taskFinished.emit() - - -class GenerateWalletKeyDialog(QDialog, Ui_GenerateKeyDialog): - - ''' - classdocs - ''' - - def __init__(self, account, keyname): - ''' - Constructor - ''' - super(GenerateWalletKeyDialog, self).__init__() - self.setupUi(self) - self.account = account - self.keyname = keyname - self.edit_name.setText("Wallet %s owned by %s" % - (self.keyname, account.name)) - self.edit_name.setEnabled(False) - self.keyid = '' - self.fingerprint = '' - self.button_box.button(QDialogButtonBox.Ok).setEnabled(False) - - def accept(self): - passphrase = self.edit_password.text() - input_data = self.account.gpg.gen_key_input(key_type="RSA", - key_length=2048, - name_real="Wallet %s owned by %s" % - (self.keyname, self.account.name), - passphrase=passphrase, - name_comment="Wallet generated by cutecoin") - - self.progress_dialog = QProgressDialog(self) - self.progress_dialog.setLabelText("Generating key...") - self.progress_dialog.setMinimum(0) - self.progress_dialog.setMaximum(0) - self.progress_dialog.setCancelButton(None) - self.progress_dialog.setValue(-1) - self.progress_dialog.show() - self.gen_task = TaskGenKey() - self.gen_task.input_data = input_data - self.gen_task.account = self.account - self.gen_task.taskFinished.connect(self.gen_finished) - self.gen_task.run() - - def gen_finished(self): - self.progress_dialog.close() - - key = self.gen_task.key - secret_keys = self.account.gpg.list_keys(True) - for k in secret_keys: - if k['fingerprint'] == key.fingerprint: - self.keyid = k['keyid'] - self.fingerprint = k['fingerprint'] - - logging.debug("Key generated : %s" % self.keyid) - - QMessageBox.information(self, "Key generation", "Key " + - key.fingerprint + " has been generated", - QMessageBox.Ok) - - self.accepted.emit() - self.close() - - def check(self): - if len(self.edit_password.text()) < 8: - self.label_errors.setText("Please enter a password with more than 8 characters") - self.button_box.button(QDialogButtonBox.Ok).setEnabled(False) - return - elif self.edit_password.text() != self.edit_password_bis.text(): - self.label_errors.setText("Passphrases do not match") - self.button_box.button(QDialogButtonBox.Ok).setEnabled(False) - return - - self.label_errors.setText("") - self.button_box.button(QDialogButtonBox.Ok).setEnabled(True) diff --git a/src/cutecoin/gui/mainWindow.py b/src/cutecoin/gui/mainWindow.py index c34f4cee9afb39ae1fbef831223167b1eaca8334..86b9935269674ec34228ff835e14694ba5158d92 100644 --- a/src/cutecoin/gui/mainWindow.py +++ b/src/cutecoin/gui/mainWindow.py @@ -12,7 +12,6 @@ from cutecoin.gui.communityTabWidget import CommunityTabWidget from cutecoin.gui.addContactDialog import AddContactDialog from cutecoin.gui.importAccountDialog import ImportAccountDialog from cutecoin.models.account.wallets.listModel import WalletsListModel -from cutecoin.models.coin.listModel import CoinsListModel from cutecoin.models.transaction.sentListModel import SentListModel from cutecoin.models.transaction.receivedListModel import ReceivedListModel diff --git a/src/cutecoin/gui/processConfigureCommunity.py b/src/cutecoin/gui/processConfigureCommunity.py index fd55ab0e746e6fbcd20f3c685bf23a7755d8eba1..046ee1857e1e23d90ae43c5d7b9e3b3f8cd488f4 100644 --- a/src/cutecoin/gui/processConfigureCommunity.py +++ b/src/cutecoin/gui/processConfigureCommunity.py @@ -3,13 +3,12 @@ Created on 8 mars 2014 @author: inso ''' -import ucoin + +from ucoinpy.api import bma from cutecoin.gen_resources.communityConfigurationDialog_uic import Ui_CommunityConfigurationDialog from PyQt5.QtWidgets import QDialog, QMenu, QMessageBox, QWidget, QAction from PyQt5.QtCore import QSignalMapper -from cutecoin.gui.processCreateWallet import ProcessCreateWallet from cutecoin.models.node.treeModel import NodesTreeModel -from cutecoin.models.wallet.trustsTreeModel import TrustsTreeModel from cutecoin.models.node import Node from cutecoin.gui.walletTabWidget import WalletTabWidget @@ -32,7 +31,7 @@ class StepPageInit(Step): server = self.config_dialog.lineedit_server.text() port = self.config_dialog.spinbox_port.value() try: - ucoin.network.Peering(server, port) + bma.network.Peering(server, port) except: QMessageBox.critical(self, "Server error", "Cannot get node peering") @@ -45,7 +44,7 @@ class StepPageInit(Step): ''' server = self.config_dialog.lineedit_server.text() port = self.config_dialog.spinbox_port.value() - default_node = Node.create(server, port, trust=True, hoster=True) + default_node = Node.create(server, port) account = self.config_dialog.account self.config_dialog.community = account.add_community(default_node) @@ -68,11 +67,9 @@ class StepPageAddNodes(Step): def display_page(self): # We add already known nodes to the displayed list - for wallet in self.config_dialog.account.wallets: - for node in wallet.nodes: - if node not in self.config_dialog.nodes: - self.config_dialog.nodes.append(node) - + for node in self.config_dialog.community.nodes: + if node not in self.config_dialog.nodes: + self.config_dialog.nodes.append(node) tree_model = NodesTreeModel(self.config_dialog.nodes, self.config_dialog.community.name()) self.config_dialog.tree_nodes.setModel(tree_model) @@ -93,17 +90,6 @@ class StepPageSetWallets(Step): def display_page(self): self.config_dialog.tabs_wallets.clear() signal_mapper = QSignalMapper(self.config_dialog) - for wallet in self.config_dialog.account.wallets: - wallet_tab = WalletTabWidget(self.config_dialog.account, - self.config_dialog.community) - self.config_dialog.tabs_wallets.addTab(wallet_tab, wallet.name) - tree_model = TrustsTreeModel(wallet, - self.config_dialog.community.name()) - signal_mapper.setMapping(tree_model, wallet.name) - tree_model.dataChanged.connect(signal_mapper.map) - wallet_tab.trusts_tree_view.setModel(tree_model) - wallet_tab.spinbox_trusts.setValue(wallet.required_trusts) - wallet_tab.spinbox_trusts.valueChanged.connect(self.config_dialog.required_trusts_changed) self.config_dialog.tabs_wallets.addTab(QWidget(), "+") @@ -184,23 +170,11 @@ class ProcessConfigureCommunity(QDialog, Ui_CommunityConfigurationDialog): self.tree_nodes.setModel(NodesTreeModel(self.community, self.nodes)) - def current_wallet_changed(self, index): - if index == (self.tabs_wallets.count() - 1): - wallet_parameters = ProcessCreateWallet(self.account, - self.community) - wallet_parameters.accepted.connect(self.add_wallet) - wallet_parameters.exec_() - def add_wallet(self): self.wallet_edit[self.account.wallets[-1].name] = True self.tabs_wallets.disconnect() self.step.display_page() - def required_trusts_changed(self, value): - wallet = self.account.wallets[self.tabs_wallets.currentIndex()] - self.wallet_edit[self.account.wallets[-1].name] = True - wallet.required_trusts = value - def showContextMenu(self, point): if self.stacked_pages.currentIndex() == 1: menu = QMenu() diff --git a/src/cutecoin/gui/processCreateWallet.py b/src/cutecoin/gui/processCreateWallet.py deleted file mode 100644 index 23d2f68da74d95eb917f8da7c62298c146de067f..0000000000000000000000000000000000000000 --- a/src/cutecoin/gui/processCreateWallet.py +++ /dev/null @@ -1,198 +0,0 @@ -''' -Created on 22 mai 2014 - -@author: inso -''' -import re -from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QMessageBox, QErrorMessage, QFileDialog - -from cutecoin.models.node import Node -from cutecoin.tools.exceptions import Error -from cutecoin.gen_resources.createWalletDialog_uic import Ui_CreateWalletDialog -from cutecoin.gui.generateWalletKeyDialog import GenerateWalletKeyDialog - - -class Step(): - def __init__(self, config_dialog, previous_step=None, next_step=None): - self.previous_step = previous_step - self.next_step = next_step - self.config_dialog = config_dialog - - -class StepPageInit(Step): - ''' - First step when adding a community - ''' - def __init__(self, config_dialog): - super().__init__(config_dialog) - - def is_valid(self): - name = self.config_dialog.edit_name.text() - if name == "": - return False - wallets = self.config_dialog.account.wallets - currency = self.config_dialog.community.currency - for w in wallets.community_wallets(currency): - if w.name == name: - return False - return True - - def process_next(self): - self.config_dialog.keyname = self.config_dialog.edit_name.text() - - def display_page(self): - self.config_dialog.button_previous.setEnabled(False) - self.config_dialog.button_next.setEnabled(False) - - -class StepPageKey(Step): - ''' - The step where the user set its key - ''' - def __init__(self, config_dialog): - super().__init__(config_dialog) - - def is_valid(self): - return self.config_dialog.keyid != '' - - def process_next(self): - pass - - def display_page(self): - self.config_dialog.button_next.setEnabled(False) - - -class StepPageNode(Step): - ''' - The step where the user set default node - ''' - def __init__(self, config_dialog): - super().__init__(config_dialog) - - def is_valid(self): - address = self.config_dialog.edit_address.text() - port = self.config_dialog.spinbox_port.value() - try: - peering = Node.create(address, port).peering() - except ValueError as e: - self.config_dialog.label_error.setText("Cannot access node : %s" + str(e)) - return False - except ConnectionError as e: - self.config_dialog.label_error.setText("Cannot access node : %s" + str(e)) - return False - - if "currency" in peering: - if (peering['currency'] != self.config_dialog.community.currency): - self.config_dialog.label_error.setText("This node doesn't use currency %s" - % self.config_dialog.community.currency) - return False - else: - self.config_dialog.label_error.setText("Not a ucoin node") - return False - return True - - def process_next(self): - pass - - def display_page(self): - self.config_dialog.button_previous.setEnabled(False) - self.config_dialog.button_next.setEnabled(False) - - -class ProcessCreateWallet(QDialog, Ui_CreateWalletDialog): - - ''' - classdocs - ''' - - def __init__(self, account, community): - ''' - Constructor - ''' - super(ProcessCreateWallet, self).__init__() - self.setupUi(self) - self.keyid = '' - self.account = account - self.community = community - self.keygen_dialog = None - self.keyname = "" - self.step = StepPageInit(self) - step_key = StepPageKey(self) - step_node = StepPageNode(self) - self.step.next_step = step_key - step_key.next_step = step_node - self.step.display_page() - - def accept(self): - address = self.edit_address.text() - port = self.spinbox_port.value() - - self.account.wallets.add_wallet(self.account.gpg, - self.keyid, - self.community.currency, - Node.create(address, port), - name=self.edit_name.text()) - self.accepted.emit() - self.close() - - def open_generate_key(self): - self.keygen_dialog = GenerateWalletKeyDialog(self.account, - self.keyname) - self.keygen_dialog.accepted.connect(self.key_generated) - self.keygen_dialog.exec_() - - def key_generated(self): - if self.keyid is not '': - self.account.gpg.delete_keys(self.keyid) - - self.keyid = self.keygen_dialog.keyid - self.label_fingerprint.setText(self.keygen_dialog.fingerprint) - self.check() - - def open_import_key(self): - keyfile = QFileDialog.getOpenFileName(self, - "Choose a secret key", - "", - "All key files (*.asc);; Any file (*)") - keyfile = keyfile[0] - key = open(keyfile).read() - result = self.account.gpg.import_keys(key) - if result.count == 0: - QErrorMessage(self).showMessage("Bad key file") - else: - QMessageBox.information(self, "Key import", "Key " + - result.fingerprints[0] + " has been imported", - QMessageBox.Ok) - if self.keyid is not '': - self.account.gpg.delete_keys(self.account.keyid) - - secret_keys = self.account.gpg.list_keys(True) - for k in secret_keys: - if k['fingerprint'] == result.fingerprints[0]: - self.keyid = k['keyid'] - - self.label_fingerprint.setText("Key : " + result.fingerprints[0]) - self.edit_secretkey_path.setText(keyfile) - self.check() - - def next(self): - if self.step.next_step is not None: - if self.step.is_valid(): - self.step.process_next() - self.step = self.step.next_step - next_index = self.stacked_pages.currentIndex() + 1 - self.stacked_pages.setCurrentIndex(next_index) - self.step.display_page() - else: - self.accept() - - def previous(self): - if self.step.previous_step is not None: - self.step = self.step.previous_step - previous_index = self.stacked_pages.currentIndex() - 1 - self.stacked_pages.setCurrentIndex(previous_index) - self.step.display_page() - - def check(self): - if self.step.is_valid(): - self.button_next.setEnabled(True) diff --git a/src/cutecoin/gui/transferMoneyDialog.py b/src/cutecoin/gui/transferMoneyDialog.py index 1ba5dba3ad2c98eab04364e75fcaf1e648478809..6e829ca6a685d0b16df9593cf8f13650ef8272ae 100644 --- a/src/cutecoin/gui/transferMoneyDialog.py +++ b/src/cutecoin/gui/transferMoneyDialog.py @@ -6,10 +6,8 @@ Created on 2 févr. 2014 from PyQt5.QtWidgets import QDialog, QErrorMessage -import ucoin from cutecoin.models.person import Person from cutecoin.models.node import Node -from cutecoin.models.coin.listModel import CoinsListModel from cutecoin.gen_resources.transferDialog_uic import Ui_TransferMoneyDialog @@ -35,24 +33,8 @@ class TransferMoneyDialog(QDialog, Ui_TransferMoneyDialog): for contact in sender.contacts: self.combo_contact.addItem(contact.name) - self.refresh_transaction() - - def remove_coins_from_transfer(self): - selection = self.list_coins_sent.selectedIndexes() - for select in selection: - coins = self.list_coins_sent.model().remove_coins(select, 1) - self.list_wallet.model().add_coins(coins) - self.refresh_total() - - def add_coins_to_transfer(self): - selection = self.list_wallet.selectedIndexes() - for select in selection: - coins = self.list_wallet.model().remove_coins(select, 1) - self.list_coins_sent.model().add_coins(coins) - self.refresh_total() - def refresh_total(self): - dividend = self.wallet.get_amendment(None)['dividend'] + dividend = self.wallet.get_block()['dividend'] total = self.list_coins_sent.model().total() relative_total = total / int(dividend) self.label_total.setText("Total : \n \ @@ -60,38 +42,16 @@ class TransferMoneyDialog(QDialog, Ui_TransferMoneyDialog): %.2f UD" % (total, self.wallet.currency, relative_total)) def accept(self): - sent_coins = self.list_coins_sent.model().to_list() - recipient = None - - if self.radio_key_fingerprint.isChecked(): - recipient = Person("", self.edit_key_fingerprint.text(), "") - else: - recipient = self.sender.contacts[ - self.combo_contact.currentIndex()] - message = self.edit_message.text() - error = self.wallet.transfer_coins(recipient, sent_coins, message) - if error: - QErrorMessage(self).showMessage("Cannot transfer coins " + error) - else: - self.accepted.emit() - self.close() + #error = self.wallet.send_money(recipient, amount, message) + + self.accepted.emit() + self.close() def change_displayed_wallet(self, index): self.wallet = self.sender.wallets[index] self.refresh_transaction() - def refresh_transaction(self): - coins_sent_model = CoinsListModel(self.wallet, []) - self.list_coins_sent.setModel(coins_sent_model) - wallet_coins_model = CoinsListModel(self.wallet, - list(self.wallet.coins)) - self.list_wallet.setModel(wallet_coins_model) - def recipient_mode_changed(self, fingerprint_toggled): self.edit_key_fingerprint.setEnabled(fingerprint_toggled) self.combo_contact.setEnabled(not fingerprint_toggled) - - def transfer_mode_changed(self, node_address_toggled): - self.edit_node_address.setEnabled(node_address_toggled) - self.combo_trusted_node.setEnabled(not node_address_toggled) diff --git a/src/cutecoin/models/account/__init__.py b/src/cutecoin/models/account/__init__.py index 833b50050718191e7317fbbb4e5897685e4e70ab..ff18719232585a558eaab272d7dc5a79fb6ab858 100644 --- a/src/cutecoin/models/account/__init__.py +++ b/src/cutecoin/models/account/__init__.py @@ -4,8 +4,8 @@ Created on 1 févr. 2014 @author: inso ''' -import ucoin -import gnupg +from ucoinpy.api import bma +from ucoinpy.key import SigningKey import logging import json import os @@ -24,39 +24,29 @@ class Account(object): be locally referenced by only one account. ''' - def __init__(self, keyid, name, communities, wallets, contacts, - keyring, secret_keyring): + def __init__(self, key, name, communities, wallets, contacts): ''' Constructor ''' - self.keyid = keyid + self.key = key self.name = name self.communities = communities - print(len(communities)) self.wallets = wallets self.contacts = contacts - self.keyring = keyring - self.secret_keyring = secret_keyring - self.gpg = gnupg.GPG(keyring=self.keyring, - secret_keyring=self.secret_keyring) @classmethod def create(cls, name, communities, wallets, confpath): ''' Constructor ''' - keyring = os.path.join(confpath['home'], name, "keyring") - secret_keyring = os.path.join(confpath['home'], name, "secretkeyring") - account = cls('', name, communities, wallets, [], - keyring, secret_keyring) + account = cls(None, name, communities, wallets, []) return account @classmethod - def load(cls, json_data): - keyid = json_data['keyid'] + def load(cls, passwd, json_data): + salt = json_data['salt'] + name = json_data['name'] - keyring = json_data['keyring'] - secret_keyring = json_data['secret_keyring'] contacts = [] for contact_data in json_data['contacts']: @@ -65,8 +55,7 @@ class Account(object): wallets = Wallets.load(json_data['wallets']) communities = Communities.load(json_data['communities']) - account = cls(keyid, name, communities, wallets, contacts, - keyring, secret_keyring) + account = cls(SigningKey(passwd, salt), name, communities, wallets, contacts) return account def __eq__(self, other): @@ -79,55 +68,35 @@ class Account(object): self.contacts.append(person) def add_community(self, default_node): - promoted = ucoin.hdc.amendments.Promoted() - default_node.use(promoted) - amendment_data = promoted.get() + current = bma.blockchain.Current(default_node.connection_handler()) + amendment_data = current.get() currency = amendment_data['currency'] - community = self.communities.add_community(currency) - self.wallets.add_wallet(self.gpg, - self.keyid, - currency, - default_node) + community = self.communities.add_community(currency, default_node) + self.wallets.add_wallet(currency) return community - def fingerprint(self): - available_keys = self.gpg.list_keys() - logging.debug(self.keyid) - for k in available_keys: - logging.debug(k) - if k['keyid'] == self.keyid: - return k['fingerprint'] - return "" - def transactions_received(self): received = [] for w in self.wallets: - for r in w.transactions_received(self.gpg): + for r in w.transactions_received(): received.append(r) return received def transactions_sent(self): sent = [] for w in self.wallets: - for t in w.transactions_sent(self.gpg): + for t in w.transactions_sent(): sent.append(t) return sent def send_pubkey(self, community): - wallets = self.wallets.community_wallets(community.currency) - return community.send_pubkey(self, wallets) + return community.send_pubkey(self) def send_membership_in(self, community): - wallets = self.wallets.community_wallets(community.currency) - return community.send_membership(self, wallets, "IN") + return community.send_membership(self, "IN") def send_membership_out(self, community): - wallets = self.wallets.community_wallets(community.currency) - return community.send_membership(self, wallets, "OUT") - - def quality(self, community): - wallets = self.wallets.community_wallets(community.currency) - return community.person_quality(wallets, self.fingerprint()) + return community.send_membership(self, "OUT") def jsonify_contacts(self): data = [] @@ -137,10 +106,8 @@ class Account(object): def jsonify(self): data = {'name': self.name, - 'keyid': self.keyid, + 'salt': self.salt, 'communities': self.communities.jsonify(), 'wallets': self.wallets.jsonify(), - 'contacts': self.jsonify_contacts(), - 'keyring': self.keyring, - 'secret_keyring': self.secret_keyring} + 'contacts': self.jsonify_contacts()} return data diff --git a/src/cutecoin/models/account/communities/__init__.py b/src/cutecoin/models/account/communities/__init__.py index 22241f288312ef4f27b5a79b7610dc7ad8657625..7035dccf02d05b1826872d32e465fbbc1af6111e 100644 --- a/src/cutecoin/models/account/communities/__init__.py +++ b/src/cutecoin/models/account/communities/__init__.py @@ -4,7 +4,6 @@ Created on 5 févr. 2014 @author: inso ''' from cutecoin.models.community import Community -import ucoin import logging @@ -56,6 +55,23 @@ class Communities(object): return community return None + def request(self, request, get_args={}): + response = None + for community in self._communities_list: + try: + response = community.request(request, get_args) + except: + continue + return response + + def post(self, request, get_args={}): + for community in self._communities_list: + try: + response = community.post(request, get_args) + except: + continue + return response + def jsonify(self): ''' Return the list of communities in a key:value form. diff --git a/src/cutecoin/models/account/wallets/__init__.py b/src/cutecoin/models/account/wallets/__init__.py index 5dfb0df2e2bb296e807503ac7c7b4461642dfbd6..4bc7b0d356a1c617586d675ded06af60b51cb1f1 100644 --- a/src/cutecoin/models/account/wallets/__init__.py +++ b/src/cutecoin/models/account/wallets/__init__.py @@ -67,27 +67,6 @@ class Wallets(object): return wallet else: return self._wallets_list.get(wallet) - - def community_wallets(self, currency): - return Wallets([w for w in self._wallets_list if w.currency == currency]) - - def request(self, request, get_args={}): - response = None - for wallet in self._wallets_list: - try: - response = wallet.request(request, get_args) - except: - continue - return response - - def post(self, request, get_args={}): - for wallet in self._wallets_list: - try: - response = wallet.post(request, get_args) - except: - continue - return response - def jsonify(self): ''' Return the list of wallets in a key:value form. diff --git a/src/cutecoin/models/coin/__init__.py b/src/cutecoin/models/coin/__init__.py deleted file mode 100644 index 614010e24224fa09501adc6d05ec721c2d1110ef..0000000000000000000000000000000000000000 --- a/src/cutecoin/models/coin/__init__.py +++ /dev/null @@ -1,57 +0,0 @@ -''' -Created on 2 févr. 2014 - -@author: inso -''' - -import re -import math -import logging -import importlib -from cutecoin.tools.exceptions import AlgorithmNotImplemented - - -class Coin(object): - - ''' - A coin parsing a regex to read its value - ''' - - def __init__(self, issuer, am_number, coin_number): - self.issuer = issuer - self.am_number = am_number - self.coin_number = coin_number - - @classmethod - def from_id(cls, wallet, coin_id): - # Regex to parse the coin id - regex = "^([A-Z\d]{40})-(\d+)-(\d+)$" - m = re.search(regex, coin_id) - issuer = m.group(1) - am_number = int(m.group(2)) - power = int(m.group(3)) - return cls(issuer, am_number, power) - - def __eq__(self, other): - return self.get_id() == other.get_id() - - def value(self, wallet): - amendment = wallet.get_amendment(self.am_number) - if 'CoinAlgo' in amendment: - coin_algo_name = amendment['CoinAlgo'] - else: - coin_algo_name = 'Base2Draft' - - try: - module = importlib.import_module("cutecoin.models.coin.algorithms") - coin_algo_class = getattr(module, coin_algo_name) - coin_algo = coin_algo_class({}) - except AttributeError: - raise AlgorithmNotImplemented(coin_algo_name) - - return coin_algo(amendment, self.coin_number) - - def get_id(self): - return self.issuer + "-" \ - + str(self.am_number) + "-" \ - + str(self.coin_number) diff --git a/src/cutecoin/models/coin/algorithms.py b/src/cutecoin/models/coin/algorithms.py deleted file mode 100644 index 0888d262927be70b3ac40a935c6e6fdba44e6ee9..0000000000000000000000000000000000000000 --- a/src/cutecoin/models/coin/algorithms.py +++ /dev/null @@ -1,36 +0,0 @@ -''' -Created on 21 mai 2014 - -@author: inso -''' - -import math - - -class Algorithm(object): - ''' - classdocs - ''' - def __init__(self, parameters): - ''' - Constructor - ''' - self.parameters = parameters - - def __call__(self, amendment, coin_number): - pass - - -class Base2Draft(Algorithm): - - def __init__(self, parameters): - super().__init__(parameters) - - def __call__(self, amendment, coin_number): - coin_base = amendment['coinBase'] - coins_list = amendment['coinList'] - i = 0 - while coin_number > coins_list[i]: - coin_number -= coins_list[i] - i += 1 - return math.pow(2, coin_base + i) diff --git a/src/cutecoin/models/coin/listModel.py b/src/cutecoin/models/coin/listModel.py deleted file mode 100644 index a7a0820b56f102d53cb2186b0160d06be8362a5c..0000000000000000000000000000000000000000 --- a/src/cutecoin/models/coin/listModel.py +++ /dev/null @@ -1,82 +0,0 @@ -''' -Created on 8 févr. 2014 - -@author: inso -''' - -from PyQt5.QtCore import QAbstractListModel, Qt - - -class CoinsListModel(QAbstractListModel): - - ''' - A Qt abstract item model to display communities in a tree - ''' - - def __init__(self, wallet, coins, parent=None): - ''' - Constructor - ''' - super(CoinsListModel, self).__init__(parent) - self.sorted_coins = {} - self.coin_values = set() - for c in coins: - value = c.value(wallet) - - if value not in self.sorted_coins: - self.sorted_coins[value] = [] - - self.sorted_coins[value] += [c] - self.coin_values.update([value]) - - self.ordered_values = list(self.coin_values) - self.ordered_values.sort() - self.wallet = wallet - - def rowCount(self, parent): - return len(self.ordered_values) - - def data(self, index, role): - if role == Qt.DisplayRole: - row = index.row() - coins_list = self.sorted_coins[self.ordered_values[row]] - - text = """%d coins of %d""" % (len(coins_list), - self.ordered_values[row]) - return text - - def flags(self, index): - return Qt.ItemIsSelectable | Qt.ItemIsEnabled - - def remove_coins(self, index, number): - removed = [] - value = self.ordered_values[index.row()] - removed += self.sorted_coins[value][-number:] - self.sorted_coins[value] = self.sorted_coins[value][:-number] - self.dataChanged.emit(index, index, [Qt.DisplayRole]) - return removed - - def add_coins(self, coins): - for c in coins: - value = c.value(self.wallet) - if value not in self.sorted_coins: - self.sorted_coins[value] = [] - self.sorted_coins[value] += [c] - self.coin_values.update([value]) - self.ordered_values = list(self.coin_values) - self.ordered_values.sort() - self.layoutChanged.emit() - - def to_list(self): - coins_list = [] - for value in self.coin_values: - for coin in self.sorted_coins[value]: - coins_list.append(coin.get_id()) - return coins_list - - def total(self): - total = 0 - for value in self.coin_values: - for coin in self.sorted_coins[value]: - total += coin.value(self.wallet) - return total diff --git a/src/cutecoin/models/community/__init__.py b/src/cutecoin/models/community/__init__.py index 5336fd23aba2a7a9c6b182a170ab703540c6575d..8fc1633296d953736022fff7b896b851bd1d88b7 100644 --- a/src/cutecoin/models/community/__init__.py +++ b/src/cutecoin/models/community/__init__.py @@ -4,7 +4,7 @@ Created on 1 févr. 2014 @author: inso ''' -import ucoin +from ucoinpy.api import bma import hashlib import json import logging @@ -17,131 +17,91 @@ class Community(object): ''' classdocs ''' - def __init__(self, currency): + def __init__(self, currency, nodes): ''' A community is a group of nodes using the same currency. - They are all using the same amendment and are syncing their datas. - An account is a member of a community if he is a member of the current amendment. ''' self.currency = currency + self.nodes = nodes @classmethod - def create(cls, currency): - return cls(currency) + def create(cls, currency, default_node): + return cls(currency, default_node) @classmethod def load(cls, json_data): + nodes = [] + + for node_data in json_data['nodes']: + nodes.append(Node.load(node_data)) + currency = json_data['currency'] - community = cls(currency) + + community = cls(currency, nodes) return community def name(self): return self.currency def __eq__(self, other): - #current_amendment = self.network.request(ucoin.hdc.amendments.Promoted()) - #current_amendment_hash = hashlib.sha1( - # current_amendment['raw'].encode('utf-8')).hexdigest().upper() - - #other_amendment = other.network.request(ucoin.hdc.amendments.Promoted()) - #other_amendment_hash = hashlib.sha1( - # other_amendment['raw'].encode('utf-8')).hexdigest().upper() - return (other.currency == self.currency) - def dividend(self, wallets): - current_amendment = wallets.request(ucoin.hdc.amendments.Promoted()) - return int(current_amendment['dividend']) - - def coin_minimal_power(self, wallets): - current_amendment = wallets.request(ucoin.hdc.amendments.Promoted()) - if 'coinMinimalPower' in current_amendment.keys(): - return int(current_amendment['coinMinimalPower']) - else: - return 0 - - def amendment_id(self, wallets): - current_amendment = wallets.request(ucoin.hdc.amendments.Promoted()) - current_amendment_hash = hashlib.sha1( - current_amendment['raw'].encode('utf-8')).hexdigest().upper() - amendment_id = str( - current_amendment["number"]) + "-" + current_amendment_hash - logging.debug("Amendment : " + amendment_id) - return amendment_id - - def amendment_number(self, wallets): - current_amendment = wallets.request(ucoin.hdc.amendments.Promoted()) - return int(current_amendment['number']) + def dividend(self): + current_amendment = self.request(bma.blockchain.Current()) + return int(current_amendment['du']) def send_pubkey(self, account, wallets): - ascii_key = account.gpg.export_keys(account.keyid) - ascii_key = ascii_key.replace("\n", "\r\n") - #signature = account.gpg.sign(ascii_key, keyid=account.keyid, detach=True) - try: - wallets.post(ucoin.pks.Add(), - {'keytext': ascii_key}) - except ValueError as e: - return str(e) - - def send_membership(self, account, wallets, membership): - context_data = {'version': 1, - 'currency': self.currency, - 'fingerprint': account.fingerprint(), - 'date': int(time.time()), - 'membership': membership - } - message = """Version: %(version)d -Currency: %(currency)s -Registry: MEMBERSHIP -Issuer: %(fingerprint)s -Date: %(date)s -Membership: %(membership)s -""" % context_data - - message = message.replace("\n", "\r\n") - signature = account.gpg.sign(message, keyid=account.keyid, detach=True) - try: - wallets.post(ucoin.registry.community.Members(), - {'membership': message, 'signature': signature}) - except ValueError as e: - return str(e) - - def person_quality(self, wallets, fingerprint): - quality = 'nothing' - voter_req = ucoin.registry.community.voters.Current(fingerprint) - data = wallets.request(voter_req) - if data: - quality = 'voter' - else: - member_req = ucoin.registry.community.members.Current(fingerprint) - data = wallets.request(member_req) - if data: - membership = data['membership'] - if membership['membership'] == 'IN': - quality = 'member' - return quality - - def members_fingerprints(self, wallets): + pass + + def send_membership(self, account, membership): + pass + + def members_pubkeys(self, wallets): ''' Listing members of a community ''' - memberships = wallets.request( - ucoin.registry.community.Members()) + memberships = self.request(bma.wot.Members()) members = [] for m in memberships: - members.append(m['membership']['issuer']) + members.append(m['results']['pubkey']) return members - def voters_fingerprints(self, wallets): - ''' - Listing members of a community - ''' - votings = wallets.request( - ucoin.registry.community.Voters()) - voters = [] - for v in votings: - voters.append(v['voting']['issuer']) - return voters + def request(self, request, get_args={}): + for node in self.nodes(): + logging.debug("Trying to connect to : " + node.get_text()) + request.connection_handler = node.connection_handler() + try: + data = request.get(**get_args) + return data + except: + continue + return None + + def post(self, request, get_args={}): + error = None + for node in self.nodes(): + logging.debug("Trying to connect to : " + node.get_text()) + request.connection_handler = node.connection_handler() + try: + request.post(**get_args) + except ValueError as e: + error = str(e) + except: + continue + return error + + def broadcast(self, nodes, request, get_args={}): + error = None + for node in nodes: + logging.debug("Trying to connect to : " + node.get_text()) + request.connection_handler = node.connection_handler() + try: + request.post(**get_args) + except ValueError as e: + error = str(e) + except: + continue + return error def jsonify(self): data = {'currency': self.currency} diff --git a/src/cutecoin/models/node/__init__.py b/src/cutecoin/models/node/__init__.py index c4b1d3ce76f3776dc6110d788651ebf01b99b758..b1308766d299d2c8ab7e4566404ec0c02484bcb7 100644 --- a/src/cutecoin/models/node/__init__.py +++ b/src/cutecoin/models/node/__init__.py @@ -4,7 +4,7 @@ Created on 1 févr. 2014 @author: inso ''' -import ucoin +from ucoinpy.api import bma import re @@ -20,74 +20,41 @@ class Node(object): ''' self.server = server self.port = port - self.trust = trust - self.hoster = hoster @classmethod - def create(cls, server, port, trust=False, hoster=False): - return cls(server, port, trust, hoster) - - @classmethod - def from_endpoints(cls, endpoints): - #TODO: Manage multiple endpoints - for endpoint in endpoints: - bma_endpoints = re.compile('^BASIC_MERKLED_API( ([a-z_][a-z0-9-_.]+))?( ([0-9.]+))?( ([0-9a-f:]+))?( ([0-9]+))$') - m = bma_endpoints.match(endpoint) - server = m.group(4) - port = int(m.group(8)) - return cls(server, port, False, False) + def create(cls, server, port): + return cls(server, port) @classmethod def load(cls, json_data): server = json_data['server'] port = json_data['port'] - trust = json_data['trust'] - hoster = json_data['hoster'] - return cls(server, port, trust, hoster) + return cls(server, port) def __eq__(self, other): - hash = ucoin.network.Peering(server=self.server, - port=self.port).get()['fingerprint'] - other_hash = ucoin.network.Peering(server=other.server, - port=other.port).get()['fingerprint'] - return (hash == other_hash) + pubkey = bma.network.Peering(server=self.server, + port=self.port).get()['puubkey'] + other_pubkey = bma.network.Peering(server=other.server, + port=other.port).get()['pubkey'] + return (pubkey == other_pubkey) def get_text(self): return self.server + ":" + str(self.port) - ''' - TrustedNode is a node the community is reading to get informations. - The account sends data one of the community main nodes. - ''' - - def downstream_peers(self): - ucoin.settings['server'] = self.server - ucoin.settings['port'] = self.port - - peers = [] - for peer in ucoin.network.peering.peers.DownStream().get()['peers']: - node = Node.create(peer['ipv4'], peer['port']) - peers.append(node) - - return peers - def peering(self): - request = ucoin.network.Peering() - self.use(request) + request = bma.network.Peering(self.connection_handler()) return request.get() def peers(self): - request = ucoin.network.peering.Peers() - self.use(request) + request = bma.network.peering.Peers(self.connection_handler()) return request.get() - def use(self, request): - request.server = self.server - request.port = self.port - return request + def connection_handler(self): + if self.server is not None: + return bma.ConnectionHandler(self.server, self.port) + else: + return bma.ConnectionHandler(self.ipv4, self.port) def jsonify(self): return {'server': self.server, - 'port': self.port, - 'trust': self.trust, - 'hoster': self.hoster} + 'port': self.port} diff --git a/src/cutecoin/models/person/__init__.py b/src/cutecoin/models/person/__init__.py index a9c65aaec3cb897d1298570ed19ae0d56e389899..503bc14b407be03fcb0d66604b3a3c93c9820d6f 100644 --- a/src/cutecoin/models/person/__init__.py +++ b/src/cutecoin/models/person/__init__.py @@ -4,7 +4,7 @@ Created on 11 févr. 2014 @author: inso ''' -import ucoin +from ucoinpy.api import bma from cutecoin.tools.exceptions import PersonNotFoundError @@ -15,33 +15,18 @@ class Person(object): Created by the person.factory ''' - def __init__(self, name, fingerprint, email): + def __init__(self, name, pubkey): ''' Constructor ''' self.name = name - self.fingerprint = fingerprint - self.email = email + self.pubkey = pubkey @classmethod - def lookup(cls, fingerprint, wallet): + def lookup(cls, pubkey, community): ''' Create a person from the fngerprint found in a community ''' - keys = wallet.request( - ucoin.pks.Lookup(), - get_args={ - 'search': "0x" + - fingerprint, - 'op': 'index'})['keys'] - if len(keys) > 0: - json = keys[0]['key'] - name = json['name'] - fingerprint = json['fingerprint'] - email = json['email'] - return cls(name, fingerprint, email) - else: - raise PersonNotFoundError(fingerprint, "fingerprint", wallet) return None @classmethod @@ -50,12 +35,10 @@ class Person(object): Create a person from json data ''' name = json_person['name'] - fingerprint = json_person['fingerprint'] - email = json_person['email'] - return cls(name, fingerprint, email) + pubkey = json_person['pubkey'] + return cls(name, pubkey) def jsonify(self): data = {'name': self.name, - 'fingerprint': self.fingerprint, - 'email': self.email} + 'pubkey': self.pubkey} return data diff --git a/src/cutecoin/models/transaction/__init__.py b/src/cutecoin/models/transaction/__init__.py index 33c28edff37a4d94c8fafebf7d8a92079b8e5cc9..e4fe507139127b6b9c0fa0fa55bfc7ff1b1c7bca 100644 --- a/src/cutecoin/models/transaction/__init__.py +++ b/src/cutecoin/models/transaction/__init__.py @@ -4,8 +4,7 @@ Created on 1 févr. 2014 @author: inso ''' -import ucoin -from cutecoin.models.coin import Coin +from ucoinpy.api import bma from cutecoin.models.person import Person @@ -23,37 +22,15 @@ class Transaction(object): self.recipient = recipient @classmethod - def create(cls, pgp_fingerprint, tx_number, wallet): - transaction_view = wallet.request( - ucoin.hdc.transactions.sender.View(pgp_fingerprint, tx_number)) - transaction_data = transaction_view['transaction'] - - sender = Person.lookup(pgp_fingerprint, wallet) - recipient = Person.lookup( - transaction_data['recipient'], - wallet) - - return cls(sender, tx_number, wallet, recipient) + def create(cls, pubkey, tx_number, wallet): + return None def value(self): value = 0 - trx_data = self.wallet.request( - ucoin.hdc.transactions.sender.View(self.sender.fingerprint, - self.tx_number)) - for coin in trx_data['transaction']['coins']: - coin = coin.split(':')[0] - value += Coin.from_id(self.wallet, coin).value(self.wallet) return value def currency(self): - trx_data = self.wallet.request( - ucoin.hdc.transactions.sender.View(self.sender.fingerprint, - self.tx_number)) - currency = trx_data['transaction']['currency'] - return currency - - def transaction_id(self): - return self.sender_fingerprint + "-" + self.increment + return "" def get_receiver_text(self): return str(self.value()) + " from " + self.sender.name diff --git a/src/cutecoin/models/transaction/receivedListModel.py b/src/cutecoin/models/transaction/receivedListModel.py index 82c78f45b8b5bd1cb52b22fec3b57601acba494a..3e67a07fd80cdccaccfb7b2be5edf3431055856a 100644 --- a/src/cutecoin/models/transaction/receivedListModel.py +++ b/src/cutecoin/models/transaction/receivedListModel.py @@ -4,7 +4,6 @@ Created on 5 févr. 2014 @author: inso ''' -import ucoin import logging from PyQt5.QtCore import QAbstractListModel, Qt diff --git a/src/cutecoin/models/transaction/sentListModel.py b/src/cutecoin/models/transaction/sentListModel.py index 4e2e48a07457e1f19870e6f588b692f3a1bef375..3228554931c83cf79e36e9347c041c9268a161f7 100644 --- a/src/cutecoin/models/transaction/sentListModel.py +++ b/src/cutecoin/models/transaction/sentListModel.py @@ -4,7 +4,6 @@ Created on 5 févr. 2014 @author: inso ''' -import ucoin import logging from PyQt5.QtCore import QAbstractListModel, Qt diff --git a/src/cutecoin/models/wallet/__init__.py b/src/cutecoin/models/wallet/__init__.py index 1646933356e6932745264a8a2f05b03e5cc8eb1f..bb31f0ec889e1e95b52149c2a6e8e4876cf67304 100644 --- a/src/cutecoin/models/wallet/__init__.py +++ b/src/cutecoin/models/wallet/__init__.py @@ -4,7 +4,8 @@ Created on 1 févr. 2014 @author: inso ''' -import ucoin +from ucoinpy.api import bma +from ucoinpy.key import SigningKey import logging import gnupg import json @@ -12,8 +13,6 @@ import time import hashlib import importlib from decimal import Decimal -from cutecoin.models.coin import Coin -from cutecoin.models.coin import algorithms from cutecoin.models.node import Node from cutecoin.models.transaction import Transaction from cutecoin.tools.exceptions import AlgorithmNotImplemented @@ -26,293 +25,48 @@ class Wallet(object): It's only used to sort coins. ''' - def __init__(self, keyid, currency, - nodes, required_trusts, name): + def __init__(self, key, currency, name): ''' Constructor ''' self.coins = [] - self.keyid = keyid + self.key = key self.currency = currency self.name = name - self.nodes = nodes - self.required_trusts = required_trusts - self.amendments_cache = {} @classmethod - def create(cls, keyid, currency, node, required_trusts, name): - node.trust = True - node.hoster = True - return cls(keyid, currency, [node], required_trusts, name) + def create(cls, walletid, currency, name): + return cls(walletid, currency, name) @classmethod - def load(cls, json_data): - nodes = [] - - for node_data in json_data['nodes']: - nodes.append(Node.load(node_data)) - - keyid = json_data['keyid'] + def load(cls, passwd, json_data): + walletid = json_data['id'] name = json_data['name'] currency = json_data['currency'] - required_trusts = json_data['required_trusts'] - return cls(keyid, currency, nodes, required_trusts, name) + return cls(SigningKey(walletid, passwd), currency, name) def __eq__(self, other): return (self.keyid == other.keyid) - def relative_value(self): + def relative_value(self, community): value = self.value() - amendment = self.get_amendment(None) - relative_value = value / float(amendment['dividend']) + block = community.get_block() + relative_value = value / float(block['du']) return relative_value def value(self): value = 0 - for coin in self.coins: - value += coin.value(self) - return value - - def refresh_coins(self, gpg): - self.coins = [] - coins_list_request = ucoin.hdc.coins.List(self.fingerprint(gpg)) - data = self.request(coins_list_request) - for coin_data in data['coins']: - coin = Coin.from_id(self, coin_data) - self.coins.append(coin) - - def transfer_coins(self, recipient, coins, message, gpg): - coins.sort() - try: - lasttx_req = ucoin.hdc.transactions.sender.Last(count=1, - pgp_fingerprint=self.fingerprint()) - last_tx = self.request(lasttx_req) - last_tx = last_tx['transactions'][0] - txview_req = ucoin.hdc.transactions.sender.View(self.fingerprint(), - tx_number=last_tx['number']) - last_tx = self.request(txview_req) - except ValueError: - last_tx = None - - if last_tx: - previous_hash = hashlib.sha1(("%s%s" % (last_tx['raw'], - last_tx['transaction']['signature']) - ).encode('ascii')).hexdigest().upper() - else: - previous_hash = None - - context_data = {} - context_data['currency'] = self.currency - context_data['version'] = 1 - context_data['number'] = 0 if not last_tx else last_tx['transaction']['number']+1 - context_data['previousHash'] = previous_hash - context_data['message'] = message - context_data['fingerprint'] = self.fingerprint() - context_data['recipient'] = recipient.fingerprint - tx = """\ -Version: %(version)d -Currency: %(currency)s -Sender: %(fingerprint)s -Number: %(number)d -""" % context_data - - if last_tx: - tx += "PreviousHash: %(previousHash)s\n" % context_data - - tx += """\ -Recipient: %(recipient)s -Coins: -""" % context_data - - for coin in coins: - tx += '%s' % coin - ownership_req = ucoin.hdc.coins.view.Owner(coin) - ownership = self.request(ownership_req) - if 'transaction' in ownership: - tx += ':%(transaction)s\n' % ownership - else: - tx += "\n" - - tx += """\ -Comment: -%(message)s""" % context_data - - tx = tx.replace("\n", "\r\n") - txs = gpg.sign(tx, keyid=self.keyid, detach=True) - - try: - wht_request = ucoin.network.Wallet(recipient.fingerprint) - except ValueError as e: - return str(e) - - recipient_wht = self.request(wht_request) - nodes = self.get_nodes_in_peering(recipient_wht['entry']['trusts']) - nodes += [h for h in self.hosters() if h not in nodes] - result = self.broadcast(nodes, - ucoin.hdc.transactions.Process(), - {'transaction': tx, 'signature': str(txs)}) - if result: - return result - - def transactions_received(self, gpg): - received = [] - transactions_data = self.request( - ucoin.hdc.transactions.Recipient(self.fingerprint(gpg))) - for trx_data in transactions_data: - received.append( - Transaction.create( - trx_data['value']['transaction']['sender'], - trx_data['value']['transaction']['number'], - self)) - return received - def transactions_sent(self, gpg): - sent = [] - transactions_data = self.request( - ucoin.hdc.transactions.sender.Last( - self.fingerprint(gpg), 20)) - for trx_data in transactions_data['transactions']: - # Small bug in ucoinpy library - if not isinstance(trx_data, str): - sent.append( - Transaction.create( - trx_data['sender'], - trx_data['number'], - self)) - return sent - - def pull_wht(self, gpg): - wht = self.request(ucoin.network.Wallet(self.fingerprint(gpg))) - if wht is None: - return [] - else: - return wht['entry'] - - def push_wht(self, gpg): - hosters_fg = [] - trusts_fg = [] - for trust in self.trusts(): - peering = trust.peering() - logging.debug(peering) - trusts_fg.append(peering['fingerprint']) - for hoster in self.hosters(): - logging.debug(peering) - peering = hoster.peering() - hosters_fg.append(peering['fingerprint']) - wht_message = '''Version: 1 -Currency: %s -Key: %s -Date: %s -RequiredTrusts: %d -Hosters: -''' % (self.currency, self.fingerprint(gpg), int(time.time()), - self.required_trusts) - for hoster in hosters_fg: - wht_message += '''%s\n''' % hoster - wht_message += '''Trusts:\n''' - for trust in trusts_fg: - wht_message += '''%s\n''' % trust - - wht_message = wht_message.replace("\n", "\r\n") - signature = gpg.sign(wht_message, keyid=self.keyid, detach=True) - - data_post = {'entry': wht_message, - 'signature': str(signature)} - logging.debug(data_post) - - self.post(ucoin.network.Wallet(), data_post) - - # TODO: Check if its working - def _search_node_by_fingerprint(self, node_fg, next_node, traversed_nodes=[]): - next_fg = next_node.peering()['fingerprint'] - if next_fg not in traversed_nodes: - traversed_nodes.append(next_fg) - if node_fg == next_fg: - return next_node - else: - for peer in next_node.peers(): - # Look for next node informations - found = self._search_node_by_fingerprint( - node_fg, - Node.from_endpoints(peer['value']['endpoints']), - traversed_nodes) - if found is not None: - return found - return None - - def get_nodes_in_peering(self, fingerprints): - nodes = [] - for node_fg in fingerprints: - node = self._search_node_by_fingerprint( - node_fg, - self.trusts()[0], - []) - if node is not None: - nodes.append(node) - #TODO: Check that one trust exists - return nodes - - def request(self, request, get_args={}): - for node in self.trusts(): - logging.debug("Trying to connect to : " + node.get_text()) - node.use(request) - try: - data = request.get(**get_args) - return data - except: - continue - return None - - def post(self, request, get_args={}): - error = None - for node in self.hosters(): - logging.debug("Trying to connect to : " + node.get_text()) - node.use(request) - try: - request.post(**get_args) - except ValueError as e: - error = str(e) - except: - continue - return error - - def broadcast(self, nodes, request, get_args={}): - error = None - for node in nodes: - logging.debug("Trying to connect to : " + node.get_text()) - node.use(request) - try: - request.post(**get_args) - except ValueError as e: - error = str(e) - except: - continue - return error - - def trusts(self): - return [node for node in self.nodes if node.trust] + return value - def hosters(self): - return [node for node in self.nodes if node.hoster] + def send_money(self, recipient, amount, message): + pass - def get_amendment(self, am_number): - if am_number in self.amendments_cache: - return self.amendments_cache[am_number] - else: - amendment_req = ucoin.hdc.amendments.Promoted(am_number) - new_am = self.request(amendment_req) - number = int(new_am['number']) - self.amendments_cache[number] = new_am - return new_am + def transactions_received(self): + pass - def fingerprint(self, gpg): - available_keys = gpg.list_keys() - logging.debug(self.keyid) - for k in available_keys: - logging.debug(k) - if k['keyid'] == self.keyid: - return k['fingerprint'] - return "" + def transactions_sent(self): + pass def get_text(self): return "%s : \n \ @@ -320,12 +74,6 @@ Hosters: %.2f UD" % (self.name, self.value(), self.currency, self.relative_value()) - def jsonify_coins_list(self): - data = [] - for coin in self.coins: - data.append({'coin': coin.get_id()}) - return data - def jsonify_nodes_list(self): data = [] for node in self.nodes: @@ -334,7 +82,7 @@ Hosters: def jsonify(self): return {'required_trusts': self.required_trusts, - 'keyid': self.keyid, + 'key': self.key, 'name': self.name, 'currency': self.currency, 'nodes': self.jsonify_nodes_list()} diff --git a/src/cutecoin/models/wallet/trustsTreeModel.py b/src/cutecoin/models/wallet/trustsTreeModel.py deleted file mode 100644 index a47571ac9c6d02d06900a67639e9fbe409f32603..0000000000000000000000000000000000000000 --- a/src/cutecoin/models/wallet/trustsTreeModel.py +++ /dev/null @@ -1,133 +0,0 @@ -''' -Created on 5 févr. 2014 - -@author: inso -''' - -from PyQt5.QtCore import QAbstractItemModel, QModelIndex, Qt -from cutecoin.models.node.itemModel import NodeItem, RootItem -import logging - - -class TrustsTreeModel(QAbstractItemModel): - - ''' - A Qt abstract item model to display nodes of a community - ''' - - def __init__(self, wallet, community_name): - ''' - Constructor - ''' - super(TrustsTreeModel, self).__init__(None) - self.wallet = wallet - self.root_item = RootItem(community_name) - self.refresh_tree_nodes() - - def columnCount(self, parent): - return 3 - - def data(self, index, role): - if not index.isValid(): - return None - - item = index.internalPointer() - - if role == Qt.DisplayRole and index.column() == 0: - return item.data(0) - elif role == Qt.CheckStateRole and index.column() == 1: - return Qt.Checked if item.trust else Qt.Unchecked - elif role == Qt.CheckStateRole and index.column() == 2: - return Qt.Checked if item.hoster else Qt.Unchecked - - return None - - def flags(self, index): - if not index.isValid(): - return Qt.NoItemFlags - - if index.column() == 0: - return Qt.ItemIsEnabled | Qt.ItemIsSelectable - else: - return Qt.ItemIsEnabled | Qt.ItemIsSelectable | Qt.ItemIsUserCheckable - - def headerData(self, section, orientation, role): - if orientation == Qt.Horizontal and role == Qt.DisplayRole and section == 0: - return self.root_item.data(0) + " nodes" - elif orientation == Qt.Horizontal and role == Qt.DisplayRole and section == 1: - return "Trust" - elif orientation == Qt.Horizontal and role == Qt.DisplayRole and section == 2: - return "Hoster" - return None - - def index(self, row, column, parent): - if not self.hasIndex(row, column, parent): - return QModelIndex() - - if not parent.isValid(): - parent_item = self.root_item - else: - parent_item = parent.internalPointer() - - child_item = parent_item.child(row) - if child_item: - return self.createIndex(row, column, child_item) - else: - return QModelIndex() - - def parent(self, index): - if not index.isValid(): - return QModelIndex() - - child_item = index.internalPointer() - parent_item = child_item.parent() - - if parent_item == self.root_item: - return QModelIndex() - - return self.createIndex(parent_item.row(), 0, parent_item) - - def rowCount(self, parent): - if parent.column() > 0: - return 0 - - if not parent.isValid(): - parent_item = self.root_item - else: - parent_item = parent.internalPointer() - - return parent_item.childCount() - - def setData(self, index, value, role=Qt.EditRole): - if index.column() == 0: - return False - - if role == Qt.EditRole: - return False - if role == Qt.CheckStateRole: - item = index.internalPointer() - if index.column() == 1: - item.trust = value - elif index.column() == 2: - item.host = value - self.dataChanged.emit(index, index) - return True - - def refresh_tree_nodes(self): - logging.debug("root : " + self.root_item.data(0)) - for node in self.wallet.nodes: - node_item = NodeItem(node, self.root_item) - logging.debug( - "mainNode : " + - node.get_text() + - " / " + - node_item.data(0)) - self.root_item.appendChild(node_item) - for node in node.downstream_peers(): - child_node_item = NodeItem(node, node_item) - logging.debug( - "\t node : " + - node.get_text() + - " / " + - child_node_item.data(0)) - node_item.appendChild(child_node_item)