diff --git a/src/cutecoin/core/account.py b/src/cutecoin/core/account.py index 0effe4565f2a3d0127460ca3f87643189f08d494..c6b27e0528d5e97361051cf0b11dad9791fd0dab 100644 --- a/src/cutecoin/core/account.py +++ b/src/cutecoin/core/account.py @@ -120,6 +120,7 @@ class Account(QObject): ) loading_progressed = pyqtSignal(int, int) + loading_finished = pyqtSignal(list) inner_data_changed = pyqtSignal(str) wallets_changed = pyqtSignal() membership_broadcasted = pyqtSignal() @@ -135,9 +136,9 @@ class Account(QObject): is OK by comparing (salt, given_passwd) = (pubkey, privkey) \ with known pubkey :param str name: The account name, same as network identity uid - :param array communities: Community objects referenced by this account - :param array wallets: Wallet objects owned by this account - :param array contacts: Contacts of this account + :param list of cutecoin.core.Community communities: Community objects referenced by this account + :param list of cutecoin.core.Wallet wallets: Wallet objects owned by this account + :param list of dict contacts: Contacts of this account :param cutecoin.core.registry.IdentitiesRegistry: The identities registry intance .. warnings:: The class methods create and load should be used to create an account @@ -237,7 +238,7 @@ class Account(QObject): self.communities.append(community) return community - def refresh_cache(self): + def refresh_transactions(self, community): """ Refresh the local account cache This needs n_wallets * n_communities cache refreshing to end @@ -245,19 +246,21 @@ class Account(QObject): .. note:: emit the Account pyqtSignal loading_progressed during refresh """ loaded_wallets = 0 + received_list = [] def progressing(value, maximum): - account_value = maximum * len(self.communities) * loaded_wallets + value - account_max = maximum * len(self.communities) * len(self.wallets) + account_value = maximum * loaded_wallets + value + account_max = maximum * len(self.wallets) self.loading_progressed.emit(account_value, account_max) for w in self.wallets: w.refresh_progressed.connect(progressing) QCoreApplication.processEvents() - for c in self.communities: - w.init_cache(c) - loaded_wallets = loaded_wallets + 1 - QCoreApplication.processEvents() + w.init_cache(community) + w.refresh_transactions(community, received_list) + loaded_wallets += 1 + QCoreApplication.processEvents() + self.loading_finished.emit(received_list) def set_display_referential(self, index): self.referential = index @@ -410,6 +413,21 @@ class Account(QObject): sent.extend(w.transfers(community)) return sent + @asyncio.coroutine + def future_amount(self, community): + ''' + Get amount of money owned in a community by all the wallets + owned by this account + + :param community: The target community of this request + :return: The value of all wallets values accumulated + ''' + value = 0 + for w in self.wallets: + val = yield from w.future_value(community) + value += val + return value + def amount(self, community): ''' Get amount of money owned in a community by all the wallets @@ -420,7 +438,8 @@ class Account(QObject): ''' value = 0 for w in self.wallets: - value += w.value(community) + val = w.value(community) + value += val return value def send_selfcert(self, password, community): diff --git a/src/cutecoin/core/app.py b/src/cutecoin/core/app.py index 86cd4904e2a76e6e51ac0413221e3f7bcc32c8f6..3625fae14a06d5620f50b540da14f1b4ab28e218 100644 --- a/src/cutecoin/core/app.py +++ b/src/cutecoin/core/app.py @@ -122,17 +122,13 @@ class Application(QObject): ''' Change current account displayed and refresh its cache. - :param account: The account object to display + :param cutecoin.core.Account account: The account object to display .. note:: Emits the application pyqtSignal loading_progressed during cache refresh ''' - def progressing(value, maximum): - self.loading_progressed.emit(value, maximum) - if self.current_account is not None: self.save_cache(self.current_account) - account.loading_progressed.connect(progressing) - account.refresh_cache() + self.current_account = account def load(self): @@ -399,6 +395,11 @@ class Application(QObject): data = {'local_accounts': self.jsonify_accounts()} return data + def stop(self): + for c in self.current_account.communities: + c.network.stop_crawling() + self.loop.stop() + def get_last_version(self): url = QUrl("https://api.github.com/repos/ucoin-io/cutecoin/releases") request = QNetworkRequest(url) diff --git a/src/cutecoin/core/community.py b/src/cutecoin/core/community.py index 5a0eb89d7ffaac755ddd8e48c4e986ee77d5bcab..93c028de3a8a5691f3f7b7554df185dae4abdfbb 100644 --- a/src/cutecoin/core/community.py +++ b/src/cutecoin/core/community.py @@ -154,17 +154,11 @@ class Community(QObject): :return: The monetary mass value """ - try: - # Get cached block by block number - block_number = self.network.latest_block - block = self.bma_access.get(self, qtbma.blockchain.Block, - req_args={'number': block_number}) - return block['monetaryMass'] - except ValueError as e: - if '404' in e: - return 0 - except NoPeerAvailable as e: - return 0 + # Get cached block by block number + block_number = self.network.latest_block + block = self.bma_access.get(self, qtbma.blockchain.Block, + req_args={'number': block_number}) + return block['monetaryMass'] @property def nb_members(self): @@ -270,12 +264,6 @@ class Community(QObject): memberships = self.bma_access.get(self, qtbma.wot.Members) return [m['pubkey'] for m in memberships["results"]] - def refresh_cache(self): - ''' - Start the refresh processing of the cache - ''' - self._cache.refresh() - def post(self, request, req_args={}, post_args={}): ''' Post data to a community. diff --git a/src/cutecoin/core/net/api/bma/access.py b/src/cutecoin/core/net/api/bma/access.py index 6294ea4157d645c9b1cd15f56dc0972f62aeb9fc..3eba4896539b11da5376f75049a759ec3daf42bb 100644 --- a/src/cutecoin/core/net/api/bma/access.py +++ b/src/cutecoin/core/net/api/bma/access.py @@ -223,7 +223,7 @@ class BmaAccess(QObject): if reply.error() == QNetworkReply.NoError: strdata = bytes(reply.readAll()).decode('utf-8') json_data = json.loads(strdata) - if self._update_cache(request, req_args, get_args): + if self._update_cache(request, req_args, get_args, json_data): logging.debug(self._pending_requests.keys()) for caller in self._pending_requests[cache_key]: logging.debug("Emit change for {0} : {1} ".format(caller, request)) diff --git a/src/cutecoin/core/net/network.py b/src/cutecoin/core/net/network.py index b12932d325b578e7890a39908bc946a5c6b80252..669a9d11b62edba716f037959afa3413588f90fa 100644 --- a/src/cutecoin/core/net/network.py +++ b/src/cutecoin/core/net/network.py @@ -7,6 +7,7 @@ from cutecoin.core.net.node import Node import logging import time +import asyncio from ucoinpy.documents.peer import Peer from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject, QCoreApplication, QTimer @@ -189,20 +190,19 @@ class Network(QObject): node = self.nodes[index] return self._root_nodes.index(node) + @asyncio.coroutine def discover_network(self): ''' Start crawling which never stops. To stop this crawling, call "stop_crawling" method. ''' - if not self.continue_crawling(): - return - for (i, node) in enumerate(self.nodes): - if not self.continue_crawling(): - return - - if node == self.nodes[-1]: - QTimer.singleShot((i+1)*10000, self.discover_network) - QTimer.singleShot(i*10000, node.refresh) + while self.continue_crawling(): + for (i, node) in enumerate(self.nodes): + if self.continue_crawling(): + yield from asyncio.sleep(2000) + node.refresh() + else: + return @pyqtSlot(Peer) def handle_new_node(self, peer): diff --git a/src/cutecoin/core/transfer.py b/src/cutecoin/core/transfer.py index 4aae112187ed7b2bb3f9951fc0f0cd8de4af061f..483d16b52fc65d6823d147b845e8a1e69322f298 100644 --- a/src/cutecoin/core/transfer.py +++ b/src/cutecoin/core/transfer.py @@ -27,7 +27,7 @@ class Transfer(QObject): REFUSED = 3 DROPPED = 5 - transfer_broadcasted = pyqtSignal() + transfer_broadcasted = pyqtSignal(str) broadcast_error = pyqtSignal(str, str) def __init__(self, hash, state, metadata): @@ -118,7 +118,7 @@ class Transfer(QObject): strdata = bytes(reply.readAll()).decode('utf-8') logging.debug("Received reply : {0} : {1}".format(reply.error(), strdata)) if reply.error() == QNetworkReply.NoError: - self.transfer_broadcasted.emit() + self.transfer_broadcasted.emit(self.metadata['receiver_uid']) for r in replies: try: r.disconnect() diff --git a/src/cutecoin/core/wallet.py b/src/cutecoin/core/wallet.py index 6d757faa9ec93766a355d724276884a467159805..3f96c99a31be06a4bba256e01250152d174c9ffe 100644 --- a/src/cutecoin/core/wallet.py +++ b/src/cutecoin/core/wallet.py @@ -8,6 +8,7 @@ from ucoinpy.documents.transaction import InputSource, OutputSource, Transaction from ucoinpy.key import SigningKey from .net.api import bma as qtbma +from .net.api.bma import PROTOCOL_VERSION from ..tools.exceptions import NotEnoughMoneyError, NoPeerAvailable, LookupFailureError from .transfer import Transfer, Received from .registry import IdentitiesRegistry, Identity @@ -15,6 +16,7 @@ from .registry import IdentitiesRegistry, Identity from PyQt5.QtCore import QObject, pyqtSignal import logging +import asyncio class Cache(): @@ -66,6 +68,7 @@ class Cache(): def transfers(self): return [t for t in self._transfers if t.state != Transfer.DROPPED] + @asyncio.coroutine def _parse_transaction(self, community, txdata, received_list, txid): receivers = [o.pubkey for o in txdata['outputs'] if o.pubkey != txdata['issuers'][0]] @@ -75,24 +78,24 @@ class Cache(): if len(receivers) == 0: receivers = [txdata['issuers'][0]] - # - # try: - # issuer_uid = IdentitiesRegistry.lookup(txdata['issuers'][0], community).uid - # except LookupFailureError: - # issuer_uid = "" - # - # try: - # receiver_uid = IdentitiesRegistry.lookup(receivers[0], community).uid - # except LookupFailureError: - # receiver_uid = "" + + try: + issuer_uid = yield from IdentitiesRegistry.future_lookup(txdata['issuers'][0], community).uid + except LookupFailureError: + issuer_uid = "" + + try: + receiver_uid = yield from IdentitiesRegistry.future_lookup(receivers[0], community).uid + except LookupFailureError: + receiver_uid = "" metadata = {'block': block_number, 'time': mediantime, 'comment': txdata['comment'], 'issuer': txdata['issuers'][0], - 'issuer_uid': "",#issuer_uid, + 'issuer_uid': issuer_uid, 'receiver': receivers[0], - 'receiver_uid': "",#receiver_uid, + 'receiver_uid': receiver_uid, 'txid': txid} in_issuers = len([i for i in txdata['issuers'] @@ -128,34 +131,42 @@ class Cache(): received = Received(txdata, metadata.copy()) received_list.append(received) self._transfers.append(received) + return True + @asyncio.coroutine def refresh(self, community, received_list): + """ + Refresh last transactions + + :param cutecoin.core.Community community: The community + :param list received_list: List of transactions received + """ current_block = 0 - try: - block_data = community.current_blockid() - current_block = block_data['number'] + block_data = yield from community.blockid() + current_block = block_data['number'] - # Lets look if transactions took too long to be validated - awaiting = [t for t in self._transfers - if t.state == Transfer.AWAITING] - tx_history = community.bma_access.simple_request(qtbma.tx.history.Blocks, - req_args={'pubkey': self.wallet.pubkey, - 'from_':self.latest_block, - 'to_': self.current_block}) + # Lets look if transactions took too long to be validated + awaiting = [t for t in self._transfers + if t.state == Transfer.AWAITING] + tx_history = yield from community.bma_access.future_request(qtbma.tx.history.Blocks, + req_args={'pubkey': self.wallet.pubkey, + 'from_':self.latest_block, + 'to_': self.current_block}) - # We parse only blocks with transactions - for (txid, txdata) in enumerate(tx_history['history']['received'] + tx_history['history']['sent']): - self._parse_transaction(community, txdata, received_list, txid) + # We parse only blocks with transactions + transactions = tx_history['history']['received'] + tx_history['history']['sent'] + for (txid, txdata) in enumerate(transactions): + yield from self._parse_transaction(community, txdata, received_list, txid) + self.wallet.refresh_progressed.emit(txid, len(transactions)) - if current_block > self.latest_block: - self.available_sources = self.wallet.sources(community) - self.latest_block = current_block + if current_block > self.latest_block: + self.available_sources = yield from self.wallet.sources(community) + self.latest_block = current_block - for transfer in awaiting: - transfer.check_refused(current_block) + for transfer in awaiting: + transfer.check_refused(current_block) - except NoPeerAvailable: - return + self.wallet.refresh_finished.emit() class Wallet(QObject): @@ -165,6 +176,9 @@ class Wallet(QObject): inner_data_changed = pyqtSignal(str) refresh_progressed = pyqtSignal(int, int) + refresh_finished = pyqtSignal() + transfer_broadcasted = pyqtSignal(str) + broadcast_error = pyqtSignal(int, str) def __init__(self, walletid, pubkey, name, identities_registry): ''' @@ -242,13 +256,13 @@ class Wallet(QObject): if community.currency not in self.caches: self.caches[community.currency] = Cache(self) - def refresh_cache(self, community, received_list): + def refresh_transactions(self, community, received_list): ''' Refresh the cache of this wallet for the specified community. :param community: The community to refresh its cache ''' - self.caches[community.currency].refresh(community, received_list) + asyncio.async(self.caches[community.currency].refresh(community, received_list)) def check_password(self, salt, password): ''' @@ -278,6 +292,20 @@ class Wallet(QObject): relative_value = value / float(ud) return relative_value + @asyncio.coroutine + def future_value(self, community): + ''' + Get wallet absolute value + + :param community: The community to get value + :return: The wallet absolute value + ''' + value = 0 + sources = yield from self.future_sources(community) + for s in sources: + value += s.amount + return value + def value(self, community): ''' Get wallet absolute value @@ -286,7 +314,8 @@ class Wallet(QObject): :return: The wallet absolute value ''' value = 0 - for s in self.sources(community): + sources = self.sources(community) + for s in sources: value += s.amount return value @@ -338,6 +367,7 @@ class Wallet(QObject): outputs.append(OutputSource(self.pubkey, overhead)) return outputs + @asyncio.coroutine def send_money(self, salt, password, community, recipient, amount, message): ''' @@ -350,10 +380,11 @@ class Wallet(QObject): :param int amount: The amount of money to transfer :param str message: The message to send with the transfer ''' - time = community.get_block().mediantime - block_number = community.current_blockid()['number'] - block = community.simple_request(bma.blockchain.Block, + blockid = yield from community.blockid() + block_number = blockid['number'] + block = yield from community.bma_access.future_request(qtbma.blockchain.Block, req_args={'number': block_number}) + time = block['medianTime'] txid = len(block['transactions']) key = None logging.debug("Key : {0} : {1}".format(salt, password)) @@ -364,12 +395,14 @@ class Wallet(QObject): logging.debug("Sender pubkey:{0}".format(key.pubkey)) try: - issuer_uid = self.identities_registry.lookup(key.pubkey, community).uid + issuer = yield from self.identities_registry.future_lookup(key.pubkey, community) + issuer_uid = issuer.uid except LookupFailureError: issuer_uid = "" try: - receiver_uid = self.identities_registry.lookup(recipient, community).uid + receiver = yield from self.identities_registry.lookup(recipient, community) + receiver_uid = receiver.uid except LookupFailureError: receiver_uid = "" @@ -392,7 +425,7 @@ class Wallet(QObject): self.caches[community.currency].available_sources = result[1] logging.debug("Inputs : {0}".format(inputs)) - outputs = self.tx_outputs(recipient, amount, inputs) + outputs = self.tx_outputs(recipient, amount, inputs) logging.debug("Outputs : {0}".format(outputs)) tx = Transaction(PROTOCOL_VERSION, community.currency, [self.pubkey], inputs, @@ -401,8 +434,25 @@ class Wallet(QObject): tx.sign([key]) logging.debug("Transaction : {0}".format(tx.signed_raw())) + transfer.transfer_broadcasted.connect(self.transfer_broadcasted) + transfer.broadcast_error.connect(self.broadcast_error) transfer.send(tx, community) + @asyncio.coroutine + def future_sources(self, community): + ''' + Get available sources in a given community + + :param cutecoin.core.community.Community community: The community where we want available sources + :return: List of InputSource ucoinpy objects + ''' + data = yield from community.bma_access.future_request(qtbma.tx.Sources, + req_args={'pubkey': self.pubkey}) + tx = [] + for s in data['sources']: + tx.append(InputSource.from_bma(s)) + return tx + def sources(self, community): ''' Get available sources in a given community @@ -424,7 +474,10 @@ class Wallet(QObject): :param community: The community we want to get the executed transfers :return: A list of Transfer objects ''' - return self.caches[community.currency].transfers + if community.currency in self.caches: + return self.caches[community.currency].transfers + else: + return [] def jsonify(self): ''' diff --git a/src/cutecoin/gui/certification.py b/src/cutecoin/gui/certification.py index e1e9533cf86350198dc8592c0505ac6c53db3712..9de66b8fd2d86333b2a9feb339b39c801dd77b6b 100644 --- a/src/cutecoin/gui/certification.py +++ b/src/cutecoin/gui/certification.py @@ -56,9 +56,17 @@ class CertificationDialog(QDialog, Ui_CertificationDialog): toast.display(self.tr("Certification"), self.tr("Success certifying {0} from {1}").format(pubkey, currency)) self.account.certification_broadcasted.disconnect() + self.account.broadcast_error.disconnect(self.handle_error) QApplication.restoreOverrideCursor() super().accept() + @pyqtSlot(int, str) + def handle_error(self, error_code, text): + toast.display(self.tr("Error"), self.tr("{0} : {1}".format(error_code, text))) + self.account.certification_broadcasted.disconnect() + self.account.broadcast_error.disconnect(self.handle_error) + QApplication.restoreOverrideCursor() + def change_current_community(self, index): self.community = self.account.communities[index] if self.account.pubkey in self.community.members_pubkeys(): @@ -68,13 +76,6 @@ class CertificationDialog(QDialog, Ui_CertificationDialog): self.button_box.button(QDialogButtonBox.Ok).setEnabled(False) self.button_box.button(QDialogButtonBox.Ok).setText(self.tr("Not a member")) - @pyqtSlot(int, str) - def handle_error(self, error_code, text): - toast.display(self.tr("Error"), self.tr("{0} : {1}".format(error_code, text))) - self.account.certification_broadcasted.disconnect() - self.account.broadcast_error.disconnect(self.handle_error) - QApplication.restoreOverrideCursor() - def recipient_mode_changed(self, pubkey_toggled): self.edit_pubkey.setEnabled(pubkey_toggled) self.combo_contact.setEnabled(not pubkey_toggled) diff --git a/src/cutecoin/gui/currency_tab.py b/src/cutecoin/gui/currency_tab.py index 8ce4776ade36dea053b616c2c63116c7b24949df..c05aa6c93eb2c644f686d8fc9ac5f7b45c129e7e 100644 --- a/src/cutecoin/gui/currency_tab.py +++ b/src/cutecoin/gui/currency_tab.py @@ -17,6 +17,7 @@ from .transactions_tab import TransactionsTabWidget from .network_tab import NetworkTabWidget from .informations_tab import InformationsTabWidget from . import toast +import asyncio from ..tools.exceptions import MembershipNotFoundError from ..core.registry import IdentitiesRegistry @@ -208,7 +209,7 @@ class CurrencyTabWidget(QWidget, Ui_CurrencyTabWidget): self.tab_wallets.refresh() def showEvent(self, event): - self.community.network.discover_network() + asyncio.async(self.community.network.discover_network()) self.refresh_status() def referential_changed(self): diff --git a/src/cutecoin/gui/mainwindow.py b/src/cutecoin/gui/mainwindow.py index 583d753eb9840c85aa1d9911f3f54d33e1cb450b..5436774d4798c32584783eeff0c03b669682a455 100644 --- a/src/cutecoin/gui/mainwindow.py +++ b/src/cutecoin/gui/mainwindow.py @@ -65,8 +65,6 @@ class MainWindow(QMainWindow, Ui_MainWindow): self.setupUi(self) QApplication.setWindowIcon(QIcon(":/icons/cutecoin_logo")) self.app = app - logging.debug(app.thread()) - logging.debug(self.thread()) self.password_asker = None self.initialized = False @@ -399,6 +397,7 @@ class MainWindow(QMainWindow, Ui_MainWindow): if self.app.current_account: self.app.save_cache(self.app.current_account) self.app.save_registries() + self.app.stop() super().closeEvent(event) def showEvent(self, event): diff --git a/src/cutecoin/gui/transactions_tab.py b/src/cutecoin/gui/transactions_tab.py index e281654e25f56ef991ab9bd24a028a23302d14b6..4653f5a382f4d91eca32a6f7640b1dfd4c92696e 100644 --- a/src/cutecoin/gui/transactions_tab.py +++ b/src/cutecoin/gui/transactions_tab.py @@ -1,12 +1,12 @@ from PyQt5.QtWidgets import QWidget, QAbstractItemView, QHeaderView, QDialog, \ QMenu, QAction, QApplication, QMessageBox -from PyQt5.QtCore import Qt, QDateTime, QTime, QModelIndex, QLocale, QCoreApplication +from PyQt5.QtCore import Qt, QDateTime, QTime, QModelIndex, QLocale, QCoreApplication, pyqtSlot from PyQt5.QtGui import QCursor from ..gen_resources.transactions_tab_uic import Ui_transactionsTabWidget from ..models.txhistory import HistoryTableModel, TxFilterProxyModel from ..core.transfer import Transfer from ..core.wallet import Wallet -from ..core.registry import IdentitiesRegistry +from ..core.registry import Identity from .transfer import TransferMoneyDialog import logging @@ -72,10 +72,13 @@ class TransactionsTabWidget(QWidget, Ui_transactionsTabWidget): def progressing(value, maximum): self.progressbar.setValue(value) self.progressbar.setMaximum(maximum) - + self.app.current_account.loading_progressed.connect(progressing) + self.app.current_account.loading_finished.connect(self.stop_progress) + self.app.current_account.refresh_transactions(self.community) self.progressbar.show() - def stop_progress(self): + @pyqtSlot(list) + def stop_progress(self, received_list): self.progressbar.hide() self.table_history.resizeColumnsToContents() @@ -92,8 +95,9 @@ class TransactionsTabWidget(QWidget, Ui_transactionsTabWidget): proxy = self.table_history.model() balance = proxy.deposits - proxy.payments - localized_deposits = QLocale().toString( - self.app.current_account.units_to_diff_ref(proxy.deposits, self.community)) + ref = self.app.current_account.units_to_diff_ref + deposits = ref(proxy.deposits, self.community) + localized_deposits = QLocale().toString(deposits) localized_payments = QLocale().toString( self.app.current_account.units_to_diff_ref(proxy.payments, self.community)) localized_balance = QLocale().toString( @@ -124,9 +128,9 @@ class TransactionsTabWidget(QWidget, Ui_transactionsTabWidget): state_data = model.sourceModel().data(state_index, Qt.DisplayRole) pubkey_col = model.sourceModel().columns_types.index('pubkey') - person_index = model.sourceModel().index(source_index.row(), + identity_index = model.sourceModel().index(source_index.row(), pubkey_col) - person = model.sourceModel().data(person_index, Qt.DisplayRole) + identity = model.sourceModel().data(identity_index, Qt.DisplayRole) transfer = model.sourceModel().transfers[source_index.row()] if state_data == Transfer.REFUSED or state_data == Transfer.TO_SEND: send_back = QAction(self.tr("Send again"), self) @@ -139,31 +143,31 @@ class TransactionsTabWidget(QWidget, Ui_transactionsTabWidget): cancel.setData(transfer) menu.addAction(cancel) else: - if isinstance(person, Person): + if isinstance(identity, Identity): informations = QAction(self.tr("Informations"), self) informations.triggered.connect(self.currency_tab.tab_community.menu_informations) - informations.setData(person) + informations.setData(identity) menu.addAction(informations) add_as_contact = QAction(self.tr("Add as contact"), self) add_as_contact.triggered.connect(self.currency_tab.tab_community.menu_add_as_contact) - add_as_contact.setData(person) + add_as_contact.setData(identity) menu.addAction(add_as_contact) send_money = QAction(self.tr("Send money"), self) send_money.triggered.connect(self.currency_tab.tab_community.menu_send_money) - send_money.setData(person) + send_money.setData(identity) menu.addAction(send_money) - if isinstance(person, Person): + if isinstance(identity, identity): view_wot = QAction(self.tr("View in Web of Trust"), self) view_wot.triggered.connect(self.currency_tab.tab_community.view_wot) - view_wot.setData(person) + view_wot.setData(identity) menu.addAction(view_wot) copy_pubkey = QAction(self.tr("Copy pubkey to clipboard"), self) copy_pubkey.triggered.connect(self.copy_pubkey_to_clipboard) - copy_pubkey.setData(person) + copy_pubkey.setData(identity) menu.addAction(copy_pubkey) # Show the context menu. @@ -174,7 +178,7 @@ class TransactionsTabWidget(QWidget, Ui_transactionsTabWidget): clipboard = QApplication.clipboard() if data.__class__ is Wallet: clipboard.setText(data.pubkey) - elif data.__class__ is Person: + elif data.__class__ is Identity: clipboard.setText(data.pubkey) elif data.__class__ is str: clipboard.setText(data) diff --git a/src/cutecoin/gui/transfer.py b/src/cutecoin/gui/transfer.py index 070b4e2607dff70530334950a9a315cb6e7159b9..eaf1105a9f3d4254b3fa2f0672463b8a91b558a2 100644 --- a/src/cutecoin/gui/transfer.py +++ b/src/cutecoin/gui/transfer.py @@ -4,12 +4,12 @@ Created on 2 févr. 2014 @author: inso ''' from PyQt5.QtWidgets import QDialog, QMessageBox, QApplication -from PyQt5.QtCore import QRegExp, Qt, QLocale +from PyQt5.QtCore import QRegExp, Qt, QLocale, pyqtSlot from PyQt5.QtGui import QRegExpValidator -from ..tools.exceptions import NotEnoughMoneyError, NoPeerAvailable from ..gen_resources.transfer_uic import Ui_TransferMoneyDialog from . import toast +import asyncio class TransferMoneyDialog(QDialog, Ui_TransferMoneyDialog): @@ -73,37 +73,35 @@ class TransferMoneyDialog(QDialog, Ui_TransferMoneyDialog): try: QApplication.setOverrideCursor(Qt.WaitCursor) QApplication.processEvents() - self.wallet.send_money(self.account.salt, password, self.community, - recipient, amount, comment) + self.wallet.transfer_broadcasted.connect(self.money_sent) + asyncio.async(self.wallet.send_money(self.account.salt, password, self.community, + recipient, amount, comment)) toast.display(self.tr("Money transfer"), self.tr("Success transfering {0} {1} to {2}").format(amount, self.community.currency, recipient)) - except ValueError as e: - QMessageBox.critical(self, self.tr("Money transfer"), - self.tr("Something wrong happened : {0}").format(e), - QMessageBox.Ok) - return - except NotEnoughMoneyError as e: - QMessageBox.warning(self, self.tr("Money transfer"), - self.tr("""This transaction could not be sent on this block -Please try again later""")) - except NoPeerAvailable as e: - QMessageBox.critical(self, self.tr("Money transfer"), - self.tr("Couldn't connect to network : {0}").format(e), - QMessageBox.Ok) - return - except Exception as e: - QMessageBox.critical(self, self.tr("Error"), - "{0}".format(str(e)), - QMessageBox.Ok) - return finally: QApplication.restoreOverrideCursor() QApplication.processEvents() super().accept() + @pyqtSlot(str) + def money_sent(self, receiver_uid): + toast.display(self.tr("Transfer"), + self.tr("Success sending money to {0}").format(receiver_uid)) + self.wallet.transfer_broadcasted.disconnect() + self.wallet.broadcast_error.disconnect(self.handle_error) + QApplication.restoreOverrideCursor() + super().accept() + + @pyqtSlot(int, str) + def handle_error(self, error_code, text): + toast.display(self.tr("Error"), self.tr("{0} : {1}".format(error_code, text))) + self.wallet.transfer_broadcasted.disconnect() + self.wallet.broadcast_error.disconnect(self.handle_error) + QApplication.restoreOverrideCursor() + def amount_changed(self): amount = self.spinbox_amount.value() relative = amount / self.dividend @@ -113,7 +111,7 @@ Please try again later""")) def relative_amount_changed(self): relative = self.spinbox_relative.value() - amount = relative * self.dividend + amount = relative * self.dividend() self.spinbox_amount.blockSignals(True) self.spinbox_amount.setValue(amount) self.spinbox_amount.blockSignals(False) diff --git a/src/cutecoin/main.py b/src/cutecoin/main.py index ad3f78cf4b37ed075a9a0b141e6083165312b57d..2502a4b338ea5a0d6b5b5f402171bc6551a058c3 100755 --- a/src/cutecoin/main.py +++ b/src/cutecoin/main.py @@ -26,5 +26,4 @@ if __name__ == '__main__': window = MainWindow(app) window.showMaximized() loop.run_forever() - sys.exit(cutecoin.exec_()) - pass + sys.exit() diff --git a/src/cutecoin/models/wallets.py b/src/cutecoin/models/wallets.py index 8815c9224810d429f89594161f37e5a3cd794299..cb7de68bb83e65ed21704a3f50c5693b8b3549e6 100644 --- a/src/cutecoin/models/wallets.py +++ b/src/cutecoin/models/wallets.py @@ -3,7 +3,7 @@ Created on 8 févr. 2014 @author: inso ''' - +import asyncio from PyQt5.QtCore import QAbstractTableModel, QSortFilterProxyModel, Qt, QLocale, pyqtSlot