diff --git a/src/cutecoin/core/account.py b/src/cutecoin/core/account.py index 5786b85e65b2834cf24a37540948445fa88d8530..9e891be8ee88f9211d018c4c775c62bbce785b13 100644 --- a/src/cutecoin/core/account.py +++ b/src/cutecoin/core/account.py @@ -262,6 +262,7 @@ class Account(QObject): value += val return value + @asyncio.coroutine def amount(self, community): """ Get amount of money owned in a community by all the wallets @@ -272,7 +273,7 @@ class Account(QObject): """ value = 0 for w in self.wallets: - val = w.value(community) + val = yield from w.value(community) value += val return value diff --git a/src/cutecoin/core/community.py b/src/cutecoin/core/community.py index 8c2aec288908ef0c4762b6df187d047f7d46e319..ad75564beeb035d2c8fee27e9e8c94485b048264 100644 --- a/src/cutecoin/core/community.py +++ b/src/cutecoin/core/community.py @@ -117,20 +117,20 @@ class Community(QObject): u = ord('\u24B6') + ord(letter) - ord('A') return chr(u) - @property + @asyncio.coroutine def dividend(self): """ Get the last generated community universal dividend. :return: The last UD or 1 if no UD was generated. """ - block = self.get_ud_block() + block = yield from self.get_ud_block() if block: return block['dividend'] else: return 1 - @property + @asyncio.coroutine def computed_dividend(self): """ Get the computed community universal dividend. @@ -141,7 +141,7 @@ class Community(QObject): :return: The computed UD or 1 if no UD was generated. """ - block = self.get_ud_block() + block = yield from self.get_ud_block() if block and block != qtbma.blockchain.Block.null_value: return math.ceil( max( @@ -154,6 +154,7 @@ class Community(QObject): else: return 1 + @asyncio.coroutine def get_ud_block(self, x=0): """ Get a block with universal dividend @@ -161,19 +162,20 @@ class Community(QObject): :param int x: Get the 'x' older block with UD in it :return: The last block with universal dividend. """ - blocks = self.bma_access.get(self, qtbma.blockchain.UD)['result']['blocks'] + udblocks = yield from self.bma_access.future_request(qtbma.blockchain.UD) + blocks = udblocks['result']['blocks'] if len(blocks) > 0: index = len(blocks)-(1+x) if index < 0: index = 0 block_number = blocks[index] - block = self.bma_access.get(self, qtbma.blockchain.Block, + block = yield from self.bma_access.future_request(qtbma.blockchain.Block, req_args={'number': block_number}) return block else: return None - @property + @asyncio.coroutine def monetary_mass(self): """ Get the community monetary mass @@ -182,11 +184,11 @@ class Community(QObject): """ # Get cached block by block number block_number = self.network.latest_block_number - block = self.bma_access.get(self, qtbma.blockchain.Block, + block = yield from self.bma_access.future_request(self, qtbma.blockchain.Block, req_args={'number': block_number}) return block['monetaryMass'] - @property + @asyncio.coroutine def nb_members(self): """ Get the community members number @@ -196,7 +198,7 @@ class Community(QObject): try: # Get cached block by block number block_number = self.network.latest_block_number - block = self.bma_access.get(qtbma.blockchain.Block, + block = yield from self.bma_access.future_request(qtbma.blockchain.Block, req_args={'number': block_number}) return block['membersCount'] except ValueError as e: @@ -225,18 +227,20 @@ class Community(QObject): """ return self._bma_access - @property + @asyncio.coroutine def parameters(self): """ Return community parameters in bma format """ - return self.bma_access.get(self, qtbma.blockchain.Parameters) + return self.bma_access.future_request(qtbma.blockchain.Parameters) + @asyncio.coroutine def certification_expired(self, certtime): """ Return True if the certificaton time is too old """ - return time.time() - certtime > self.parameters['sigValidity'] + parameters = yield from self.parameters() + return time.time() - certtime > parameters['sigValidity'] def add_node(self, node): """ @@ -254,6 +258,7 @@ class Community(QObject): """ self._network.remove_root_node(index) + @asyncio.coroutine def get_block(self, number=None): """ Get a block @@ -261,10 +266,10 @@ class Community(QObject): :param int number: The block number. If none, returns current block. """ if number is None: - data = self.bma_access.get(self, qtbma.blockchain.Current) + data = self.bma_access.future_request(qtbma.blockchain.Current) else: logging.debug("Requesting block {0}".format(number)) - data = self.bma_access.get(self, qtbma.blockchain.Block, + data = self.bma_access.future_request(qtbma.blockchain.Block, req_args={'number': number}) return data @@ -281,13 +286,14 @@ class Community(QObject): block_number = block['number'] return {'number': block_number, 'hash': block_hash} + @asyncio.coroutine def members_pubkeys(self): """ Listing members pubkeys of a community :return: All members pubkeys. """ - memberships = self.bma_access.get(self, qtbma.wot.Members) + memberships = yield from self.bma_access.future_request(qtbma.wot.Members) return [m['pubkey'] for m in memberships["results"]] def start_coroutines(self): diff --git a/src/cutecoin/core/graph.py b/src/cutecoin/core/graph.py index 1665d83fabcead7d9225a05d9033ecb9decb7ccc..c46cf51f1dd3929dfecb416f3788dbbc672b3677 100644 --- a/src/cutecoin/core/graph.py +++ b/src/cutecoin/core/graph.py @@ -1,8 +1,9 @@ import logging import time -import datetime +import asyncio from PyQt5.QtCore import QLocale, QDateTime from ..core.registry import Identity, BlockchainState +from ..tools.decorators import asyncify from cutecoin.gui.views.wot import NODE_STATUS_HIGHLIGHTED, NODE_STATUS_OUT, ARC_STATUS_STRONG, ARC_STATUS_WEAK @@ -17,12 +18,16 @@ class Graph(object): """ self.app = app self.community = community - self.signature_validity = self.community.parameters['sigValidity'] - # arc considered strong during 75% of signature validity time - self.ARC_STATUS_STRONG_time = int(self.signature_validity * 0.75) # graph empty if None parameter self._graph = graph or (dict() and (graph is None)) + @asyncio.coroutine + def refresh_signature_validity(self): + parameters = yield from self.community.parameters() + self.signature_validity = parameters['sigValidity'] + # arc considered strong during 75% of signature validity time + self.ARC_STATUS_STRONG_time = int(self.signature_validity * 0.75) + def set(self, graph): """ Set the graph from dict @@ -38,6 +43,7 @@ class Graph(object): """ return self._graph + @asyncio.coroutine def get_shortest_path_between_members(self, from_identity, to_identity): """ Return path list of nodes from from_identity to to_identity @@ -50,17 +56,19 @@ class Graph(object): logging.debug("path between %s to %s..." % (from_identity.uid, to_identity.uid)) if from_identity.pubkey not in self._graph.keys(): self.add_identity(from_identity) - certifier_list = from_identity.certifiers_of(self.app.identities_registry, self.community) + certifier_list = yield from from_identity.certifiers_of(self.app.identities_registry, + self.community) self.add_certifier_list(certifier_list, from_identity, to_identity) - certified_list = from_identity.certified_by(self.app.identities_registry, self.community) + certified_list = yield from from_identity.certified_by(self.app.identities_registry, + self.community) self.add_certified_list(certified_list, from_identity, to_identity) if to_identity.pubkey not in self._graph.keys(): # recursively feed graph searching for account node... - self.explore_to_find_member(to_identity, self._graph[from_identity.pubkey]['connected'], list()) + yield from self.explore_to_find_member(to_identity, self._graph[from_identity.pubkey]['connected'], list()) if len(self._graph[from_identity.pubkey]['connected']) > 0: # calculate path of nodes between identity and to_identity - path = self.find_shortest_path(self._graph[from_identity.pubkey], self._graph[to_identity.pubkey]) + path = yield from self.find_shortest_path(self._graph[from_identity.pubkey], self._graph[to_identity.pubkey]) if path: logging.debug([node['text'] for node in path]) @@ -69,6 +77,7 @@ class Graph(object): return path + @asyncio.coroutine def explore_to_find_member(self, identity, connected=None, done=None): """ Scan graph recursively to find identity @@ -90,11 +99,13 @@ class Graph(object): if node['id'] in tuple(done): continue identity_selected = identity.from_handled_data(node['text'], node['id'], BlockchainState.VALIDATED) - certifier_list = identity_selected.unique_valid_certifiers_of(self.app.identities_registry, self.community) + certifier_list = yield from identity_selected.unique_valid_certifiers_of(self.app.identities_registry, + self.community) self.add_certifier_list(certifier_list, identity_selected, identity) if identity.pubkey in tuple(self._graph.keys()): return False - certified_list = identity_selected.unique_valid_certified_by(self.app.identities_registry, self.community) + certified_list = yield from identity_selected.unique_valid_certified_by(self.app.identities_registry, + self.community) self.add_certified_list(certified_list, identity_selected, identity) if identity.pubkey in tuple(self._graph.keys()): return False @@ -108,6 +119,7 @@ class Graph(object): return True + @asyncio.coroutine def find_shortest_path(self, start, end, path=None): """ Find recursively the shortest path between two nodes @@ -126,12 +138,13 @@ class Graph(object): for pubkey in tuple(self._graph[start['id']]['connected']): node = self._graph[pubkey] if node not in path: - newpath = self.find_shortest_path(node, end, path) + newpath = yield from self.find_shortest_path(node, end, path) if newpath: if not shortest or len(newpath) < len(shortest): shortest = newpath return shortest + @asyncio.coroutine def add_certifier_list(self, certifier_list, identity, identity_account): """ Add list of certifiers to graph @@ -140,6 +153,7 @@ class Graph(object): :param identity identity_account: Account identity instance :return: """ + yield from self.refresh_signature_validity() # add certifiers of uid for certifier in tuple(certifier_list): # add only valid certification... @@ -207,6 +221,7 @@ class Graph(object): # add certifier node to identity node self._graph[identity.pubkey]['connected'].append(certifier['identity'].pubkey) + @asyncio.coroutine def add_certified_list(self, certified_list, identity, identity_account): """ Add list of certified from api to graph @@ -215,6 +230,7 @@ class Graph(object): :param identity identity_account: Account identity instance :return: """ + yield from self.refresh_signature_validity() # add certified by uid for certified in tuple(certified_list): # add only valid certification... @@ -254,7 +270,8 @@ class Graph(object): current_validations = self.community.network.latest_block_number - certified['block_number'] else: current_validations = 0 - max_validations = self.community.network.fork_window(self.community.members_pubkeys()) + 1 + members_pubkeys = yield from self.community.members_pubkeys() + max_validations = self.community.network.fork_window(members_pubkeys) + 1 if max_validations > current_validations > 0: if self.app.preferences['expert_mode']: diff --git a/src/cutecoin/core/money/quant_zerosum.py b/src/cutecoin/core/money/quant_zerosum.py index 17a8dbc36027cd0686613100159ee6fcda7ccaf8..9c410877997a8a36c8a27c0ff7972cc1bd44f1ba 100644 --- a/src/cutecoin/core/money/quant_zerosum.py +++ b/src/cutecoin/core/money/quant_zerosum.py @@ -1,6 +1,6 @@ from PyQt5.QtCore import QCoreApplication, QT_TRANSLATE_NOOP, QLocale from . import Quantitative - +import asyncio class QuantitativeZSum: _NAME_STR_ = QT_TRANSLATE_NOOP('QuantitativeZSum', 'Quant Z-sum') @@ -24,6 +24,7 @@ class QuantitativeZSum: def diff_units(cls, currency): return QuantitativeZSum.units(currency) + @asyncio.coroutine def value(self): """ Return quantitative value of amount minus the average value @@ -32,18 +33,22 @@ class QuantitativeZSum: :param cutecoin.core.community.Community community: Community instance :return: int """ - ud_block = self.community.get_ud_block() + ud_block = yield from self.community.get_ud_block() if ud_block and ud_block['membersCount'] > 0: - average = self.community.monetary_mass / ud_block['membersCount'] + monetary_mass = yield from self.community.monetary_mass() + average = monetary_mass / ud_block['membersCount'] else: average = 0 return self.amount - average + @asyncio.coroutine def differential(self): - return Quantitative(self.amount, self.community, self.app).compute() + value = yield from Quantitative(self.amount, self.community, self.app).value() + return value + @asyncio.coroutine def localized(self, units=False, international_system=False): - value = self.value() + value = yield from self.value() if international_system: pass else: @@ -57,5 +62,7 @@ class QuantitativeZSum: else: return localized_value + @asyncio.coroutine def diff_localized(self, units=False, international_system=False): - return Quantitative(self.amount, self.community, self.app).localized(units, international_system) \ No newline at end of file + localized = yield from Quantitative(self.amount, self.community, self.app).localized(units, international_system) + return localized \ No newline at end of file diff --git a/src/cutecoin/core/money/quantitative.py b/src/cutecoin/core/money/quantitative.py index 7aac10fe79f60924521e3179e199be6f3aa37663..c299725903ee3ac5ce0974841c6c353cd0e9a5ae 100644 --- a/src/cutecoin/core/money/quantitative.py +++ b/src/cutecoin/core/money/quantitative.py @@ -1,5 +1,5 @@ from PyQt5.QtCore import QCoreApplication, QT_TRANSLATE_NOOP, QObject, QLocale - +import asyncio class Quantitative(): _NAME_STR_ = QT_TRANSLATE_NOOP('Quantitative', 'Units') @@ -23,6 +23,7 @@ class Quantitative(): def diff_units(cls, currency): return Quantitative.units(currency) + @asyncio.coroutine def value(self): """ Return quantitative value of amount @@ -33,8 +34,10 @@ class Quantitative(): """ return int(self.amount) + @asyncio.coroutine def differential(self): - return self.value() + value = yield from self.value() + return value def _to_si(self, value): prefixes = ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y', 'z', 'y'] @@ -54,8 +57,9 @@ class Quantitative(): return localized_value, prefix + @asyncio.coroutine def localized(self, units=False, international_system=False): - value = self.value() + value = yield from self.value() prefix = "" if international_system: localized_value, prefix = self._to_si(value) @@ -71,8 +75,9 @@ class Quantitative(): else: return localized_value + @asyncio.coroutine def diff_localized(self, units=False, international_system=False): - value = self.differential() + value = yield from self.differential() prefix = "" if international_system: localized_value, prefix = self._to_si(value) diff --git a/src/cutecoin/core/money/relative.py b/src/cutecoin/core/money/relative.py index 39aab280eb752d06bf2289b69a6f387fb75c5994..5cf9d8a760baada5e8b96211abecd6573190dde4 100644 --- a/src/cutecoin/core/money/relative.py +++ b/src/cutecoin/core/money/relative.py @@ -1,5 +1,5 @@ from PyQt5.QtCore import QObject, QCoreApplication, QT_TRANSLATE_NOOP, QLocale - +import asyncio class Relative(): _NAME_STR_ = QT_TRANSLATE_NOOP('Relative', 'UD') @@ -23,6 +23,7 @@ class Relative(): def diff_units(self, currency): return self.units(currency) + @asyncio.coroutine def value(self): """ Return relative value of amount @@ -30,13 +31,16 @@ class Relative(): :param cutecoin.core.community.Community community: Community instance :return: float """ - if self.community.dividend > 0: - return self.amount / float(self.community.dividend) + dividend = yield from self.community.dividend() + if dividend > 0: + return self.amount / float(dividend) else: return 0 + @asyncio.coroutine def differential(self): - return self.value() + value = yield from self.value() + return value def _to_si(self, value): prefixes = ['', 'd', 'c', 'm', 'µ', 'n', 'p', 'f', 'a', 'z', 'y'] @@ -59,8 +63,9 @@ class Relative(): return localized_value, prefix + @asyncio.coroutine def localized(self, units=False, international_system=False): - value = self.value() + value = yield from self.value() prefix = "" if international_system: localized_value, prefix = self._to_si(value) @@ -75,8 +80,9 @@ class Relative(): else: return localized_value + @asyncio.coroutine def diff_localized(self, units=False, international_system=False): - value = self.differential() + value = yield from self.differential() prefix = "" if international_system and value != 0: localized_value, prefix = self._to_si(value) diff --git a/src/cutecoin/core/money/relative_zerosum.py b/src/cutecoin/core/money/relative_zerosum.py index 788772acb957cca3d07a6db339add134a295520b..4202a72a5fd53a58fe301a76ea62ffeb4ab5f944 100644 --- a/src/cutecoin/core/money/relative_zerosum.py +++ b/src/cutecoin/core/money/relative_zerosum.py @@ -1,6 +1,6 @@ from PyQt5.QtCore import QCoreApplication, QT_TRANSLATE_NOOP, QLocale from .relative import Relative - +import asyncio class RelativeZSum: _NAME_STR_ = QT_TRANSLATE_NOOP('RelativeZSum', 'Relat Z-sum') @@ -24,6 +24,7 @@ class RelativeZSum: def diff_units(cls, currency): return RelativeZSum.units(currency) + @asyncio.coroutine def value(self): """ Return relative value of amount minus the average value @@ -32,20 +33,24 @@ class RelativeZSum: :param cutecoin.core.community.Community community: Community instance :return: float """ - ud_block = self.community.get_ud_block() + ud_block = yield from self.community.get_ud_block() if ud_block and ud_block['membersCount'] > 0: - median = self.community.monetary_mass / ud_block['membersCount'] - relative_value = self.amount / float(self.community.dividend) - relative_median = median / self.community.dividend + monetary_mass = yield from self.community.monetary_mass() + dividend = yield from self.community.dividend() + median = monetary_mass / ud_block['membersCount'] + relative_value = self.amount / float(dividend) + relative_median = median / dividend else: relative_median = 0 return relative_value - relative_median + @asyncio.coroutine def differential(self): return Relative(self.amount, self.community, self.app).value() + @asyncio.coroutine def localized(self, units=False, international_system=False): - value = self.value() + value = yield from self.value() if international_system: pass else: diff --git a/src/cutecoin/core/net/api/bma/access.py b/src/cutecoin/core/net/api/bma/access.py index c6e766a0f0696f2e828ce4775d80a45389519766..82b1c559817f3950277ae9181808058d4a7b0701 100644 --- a/src/cutecoin/core/net/api/bma/access.py +++ b/src/cutecoin/core/net/api/bma/access.py @@ -138,64 +138,6 @@ class BmaAccess(QObject): return True return False - def get(self, caller, request, req_args={}, get_args={}, tries=0): - """ - Get Json data from the specified URL and emit "inner_data_changed" - on the caller if the data changed. - - :param PyQt5.QtCore.QObject caller: The objet calling - :param class request: A bma request class calling for data - :param dict req_args: Arguments to pass to the request constructor - :param dict get_args: Arguments to pass to the request __get__ method - :return: The cached data - :rtype: dict - """ - - data = self._get_from_cache(request, req_args, get_args) - need_reload = data[0] - ret_data = data[1] - cache_key = BmaAccess._gen_cache_key(request, req_args, get_args) - - if need_reload: - if cache_key in self._pending_requests: - if caller not in self._pending_requests[cache_key]: - logging.debug("New caller".format(caller)) - self._pending_requests[cache_key].append(caller) - logging.debug("Callers".format(self._pending_requests[cache_key])) - else: - reply = self.simple_request(request, req_args, get_args) - logging.debug("New pending request {0}, caller {1}".format(cache_key, caller)) - self._pending_requests[cache_key] = [caller] - reply.finished.connect(lambda: self.handle_reply(request, req_args, get_args, tries)) - return ret_data - - @pyqtSlot(int, dict, dict, int) - def handle_reply(self, request, req_args, get_args, tries): - reply = self.sender() - logging.debug("Handling QtNetworkReply for {0}".format(str(request))) - cache_key = BmaAccess._gen_cache_key(request, req_args, get_args) - - if reply.error() == QNetworkReply.NoError: - strdata = bytes(reply.readAll()).decode('utf-8') - json_data = json.loads(strdata) - # If data changed, we emit a change signal to all callers - 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)) - caller.inner_data_changed.emit(str(request)) - self._pending_requests.pop(cache_key) - else: - logging.debug("Error in reply : {0}".format(reply.error())) - if tries < 3: - tries += 1 - try: - pending_request = self._pending_requests.pop(cache_key) - for caller in pending_request: - self.get(caller, request, req_args, get_args, tries=tries) - except KeyError: - logging.debug("{0} is not present anymore in pending requests".format(cache_key)) - def future_request(self, request, req_args={}, get_args={}): """ Start a request to the network and returns a future. diff --git a/src/cutecoin/core/registry/identity.py b/src/cutecoin/core/registry/identity.py index aa77a6cb782be986e1161a2e6c85076ebe1fd386..316af79561fa27086f14cc3d811e5333197b5aaf 100644 --- a/src/cutecoin/core/registry/identity.py +++ b/src/cutecoin/core/registry/identity.py @@ -233,7 +233,7 @@ class Identity(QObject): if data == qtbma.wot.CertifiersOf.null_value: logging.debug('bma.wot.CertifiersOf request error') - data = community.bma_access.get(self, qtbma.wot.Lookup, {'search': self.pubkey}) + data = yield from community.bma_access.future_request(qtbma.wot.Lookup, {'search': self.pubkey}) if data == qtbma.wot.Lookup.null_value: logging.debug('bma.wot.Lookup request error') else: @@ -247,7 +247,7 @@ class Identity(QObject): certifier['identity'] = identities_registry.from_handled_data(uid, certifier_data['pubkey'], BlockchainState.BUFFERED) - block = community.bma_access.get(self, qtbma.blockchain.Block, + block = yield from community.bma_access.future_request(qtbma.blockchain.Block, {'number': certifier_data['meta']['block_number']}) certifier['cert_time'] = block['medianTime'] certifier['block_number'] = None @@ -271,7 +271,8 @@ class Identity(QObject): # add certifiers of uid for certifier in tuple(certifier_list): # add only valid certification... - if community.certification_expired(certifier['cert_time']): + cert_expired = yield from community.certification_expired(certifier['cert_time']) + if cert_expired: continue # keep only the latest certification @@ -296,7 +297,7 @@ class Identity(QObject): certified_list = list() if data == qtbma.wot.CertifiedBy.null_value: logging.debug('bma.wot.CertifiersOf request error') - data = community.bma_access.get(self, qtbma.wot.Lookup, {'search': self.pubkey}) + data = yield from community.bma_access.future_request(qtbma.wot.Lookup, {'search': self.pubkey}) if data == qtbma.wot.Lookup.null_value: logging.debug('bma.wot.Lookup request error') else: @@ -328,7 +329,8 @@ class Identity(QObject): # add certifiers of uid for certified in tuple(certified_list): # add only valid certification... - if community.certification_expired(certified['cert_time']): + cert_expired = yield from community.certification_expired(certified['cert_time']) + if cert_expired: continue # keep only the latest certification diff --git a/src/cutecoin/core/txhistory.py b/src/cutecoin/core/txhistory.py index 9a7ac8dbdfcc11542f1b434578d93ba1f386f797..b958c878a3f10bfe96abe8c5f8fff83b212aa873 100644 --- a/src/cutecoin/core/txhistory.py +++ b/src/cutecoin/core/txhistory.py @@ -71,8 +71,10 @@ class TxHistory(): self._stop_coroutines = True @staticmethod + @asyncio.coroutine def _validation_state(community, block_number, current_block): - if block_number + community.network.fork_window(community.members_pubkeys()) + 1 < current_block["number"]: + members_pubkeys = yield from community.members_pubkeys() + if block_number + community.network.fork_window(members_pubkeys) + 1 < current_block["number"]: state = Transfer.VALIDATED else: state = Transfer.VALIDATING @@ -87,7 +89,7 @@ class TxHistory(): block_number = txdata['block_number'] mediantime = txdata['time'] - state = TxHistory._validation_state(community, block_number, current_block) + state = yield from TxHistory._validation_state(community, block_number, current_block) if len(receivers) == 0: receivers = [txdata['issuers'][0]] @@ -167,13 +169,13 @@ class TxHistory(): """ current_block = yield from community.bma_access.future_request(qtbma.blockchain.Block, req_args={'number': community.network.latest_block_number}) - + members_pubkeys = yield from community.members_pubkeys() # We look for the first block to parse, depending on awaiting and validating transfers and ud... blocks = [tx.metadata['block'] for tx in self._transfers if tx.state in (Transfer.AWAITING, Transfer.VALIDATING)] +\ [ud['block_number'] for ud in self._dividends if ud['state'] in (Transfer.AWAITING, Transfer.VALIDATING)] +\ - [max(0, self.latest_block - community.network.fork_window(community.members_pubkeys()))] + [max(0, self.latest_block - community.network.fork_window(members_pubkeys))] parsed_block = min(set(blocks)) logging.debug("Refresh from : {0} to {1}".format(self.latest_block, current_block['number'])) dividends_data = qtbma.ud.History.null_value @@ -210,7 +212,7 @@ class TxHistory(): udid = 0 for d in [ud for ud in dividends if ud['block_number'] in range(parsed_block, parsed_block+100)]: - state = TxHistory._validation_state(community, d['block_number'], current_block) + state = yield from TxHistory._validation_state(community, d['block_number'], current_block) if d['block_number'] not in [ud['block_number'] for ud in self._dividends]: d['id'] = udid diff --git a/src/cutecoin/core/wallet.py b/src/cutecoin/core/wallet.py index 0b3a2c8b0d8737ec2459f8ce11247b33a32e2c15..3f0cdc8a7ef2402547f99bc98d680e55ea8a5bca 100644 --- a/src/cutecoin/core/wallet.py +++ b/src/cutecoin/core/wallet.py @@ -132,6 +132,7 @@ class Wallet(QObject): key = SigningKey("{0}{1}".format(salt, self.walletid), password) return (key.pubkey == self.pubkey) + @asyncio.coroutine def relative_value(self, community): """ Get wallet value relative to last generated UD @@ -139,25 +140,12 @@ class Wallet(QObject): :param community: The community to get value :return: The wallet relative value """ - value = self.value(community) + value = yield from self.value(community) ud = community.dividend 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 @@ -166,7 +154,7 @@ class Wallet(QObject): :return: The wallet absolute value """ value = 0 - sources = self.sources(community) + sources = yield from self.sources(community) for s in sources: value += s.amount return value @@ -305,6 +293,7 @@ class Wallet(QObject): tx.append(InputSource.from_bma(s)) return tx + @asyncio.coroutine def sources(self, community): """ Get available sources in a given community @@ -312,7 +301,7 @@ class Wallet(QObject): :param cutecoin.core.community.Community community: The community where we want available sources :return: List of InputSource ucoinpy objects """ - data = community.bma_access.get(self, qtbma.tx.Sources, + data = yield from community.bma_access.future_request(qtbma.tx.Sources, req_args={'pubkey': self.pubkey}) tx = [] for s in data['sources']: diff --git a/src/cutecoin/gui/certification.py b/src/cutecoin/gui/certification.py index 23201927cc2193c54cc5859715a1270f13135e76..b90e9989d3786ad6a8ffa726e9fa5dcf6fedbda6 100644 --- a/src/cutecoin/gui/certification.py +++ b/src/cutecoin/gui/certification.py @@ -8,6 +8,7 @@ from PyQt5.QtCore import Qt, pyqtSlot from ..gen_resources.certification_uic import Ui_CertificationDialog from . import toast from ..core.net.api import bma as qtbma +from ..tools.decorators import asyncify import asyncio import logging @@ -70,25 +71,16 @@ class CertificationDialog(QDialog, Ui_CertificationDialog): self.account.broadcast_error.disconnect(self.handle_error) QApplication.restoreOverrideCursor() - def handle_community_data_change(self, request): - if request == qtbma.blockchain.Block: - self.refresh() - def change_current_community(self, index): - try: - self.community.inner_data_changed.disconnect(self.handle_community_data_change) - except TypeError as e: - if 'connect' in str(e): - logging.debug("Error when disconnecting community") - else: - raise self.community = self.account.communities[index] - self.community.inner_data_changed.connect(self.handle_community_data_change) self.refresh() + @asyncify + @asyncio.coroutine def refresh(self): - if self.account.pubkey in self.community.members_pubkeys() \ - or self.community.get_block(0) == qtbma.blockchain.Block.null_value: + is_member = yield from self.account.identity(self.community).is_member(self.community) + block_0 = yield from self.community.get_block(0) + if is_member or block_0 == qtbma.blockchain.Block.null_value: self.button_box.button(QDialogButtonBox.Ok).setEnabled(True) self.button_box.button(QDialogButtonBox.Ok).setText(self.tr("&Ok")) else: diff --git a/src/cutecoin/gui/community_tile.py b/src/cutecoin/gui/community_tile.py index 04fbedc875f7dd77d9e2bd92616f12c23382fd34..cfe1ec27b438dd9a61cacceee20596b8934f1d76 100644 --- a/src/cutecoin/gui/community_tile.py +++ b/src/cutecoin/gui/community_tile.py @@ -5,6 +5,8 @@ from PyQt5.QtWidgets import QFrame, QLabel, QVBoxLayout, QLayout, QPushButton from PyQt5.QtGui import QPalette from PyQt5.QtCore import QEvent, QSize, pyqtSignal +from ..tools.decorators import asyncify +import asyncio class CommunityTile(QFrame): @@ -26,9 +28,12 @@ class CommunityTile(QFrame): def sizeHint(self): return QSize(250, 250) + @asyncify + @asyncio.coroutine def refresh(self): - current_block = self.community.get_block(self.community.network.latest_block_number) - status = self.tr("Member") if self.app.current_account.pubkey in self.community.members_pubkeys() \ + current_block = yield from self.community.get_block(self.community.network.latest_block_number) + members_pubkeys = yield from self.community.members_pubkeys() + status = self.tr("Member") if self.app.current_account.pubkey in members_pubkeys \ else self.tr("Non-Member") description = """<html> <body> @@ -41,7 +46,7 @@ class CommunityTile(QFrame): <p><span style=" font-weight:600;">{balance_label}</span> : {balance}</p> </body> </html>""".format(currency=self.community.currency, - nb_members=len(self.community.members_pubkeys()), + nb_members=len(members_pubkeys), members_label=self.tr("members"), monetary_mass_label=self.tr("Monetary mass"), monetary_mass=current_block['monetaryMass'], diff --git a/src/cutecoin/gui/community_view.py b/src/cutecoin/gui/community_view.py index 186cb2a35e52c1da4015f0c7fcfe838363c6ac56..d6c78ef746bb0ee8c0d57187db4b96c7dc390ef1 100644 --- a/src/cutecoin/gui/community_view.py +++ b/src/cutecoin/gui/community_view.py @@ -154,7 +154,8 @@ class CommunityWidget(QWidget, Ui_CommunityWidget): self.tab_history.refresh_balance() self.refresh_status() - @pyqtSlot() + @asyncify + @asyncio.coroutine def refresh_status(self): """ Refresh status bar @@ -163,7 +164,7 @@ class CommunityWidget(QWidget, Ui_CommunityWidget): if self.community: text = self.tr(" Block {0}").format(self.community.network.latest_block_number) - block = self.community.get_block(self.community.network.latest_block_number) + block = yield from self.community.get_block(self.community.network.latest_block_number) if block != qtbma.blockchain.Block.null_value: text += " ( {0} )".format(QLocale.toString( QLocale(), diff --git a/src/cutecoin/gui/network_tab.py b/src/cutecoin/gui/network_tab.py index 0ff9795bd6fb78fc681653190aafe85bbab04041..44dfea169ae55a6883cbed141f97276827d496a4 100644 --- a/src/cutecoin/gui/network_tab.py +++ b/src/cutecoin/gui/network_tab.py @@ -52,7 +52,7 @@ class NetworkTabWidget(QWidget, Ui_NetworkTabWidget): @pyqtSlot() def refresh_nodes(self): logging.debug("Refresh nodes") - self.table_network.model().sourceModel().modelReset.emit() + self.table_network.model().sourceModel().refresh_nodes() def node_context_menu(self, point): index = self.table_network.indexAt(point) diff --git a/src/cutecoin/gui/transactions_tab.py b/src/cutecoin/gui/transactions_tab.py index 63cd6974f3f3f74facd70ba1e90727252d61ce38..e0b0f91219b1073a31193edf213656fca3b022a9 100644 --- a/src/cutecoin/gui/transactions_tab.py +++ b/src/cutecoin/gui/transactions_tab.py @@ -7,10 +7,12 @@ from ..models.txhistory import HistoryTableModel, TxFilterProxyModel from ..core.transfer import Transfer from ..core.wallet import Wallet from ..core.registry import Identity +from ..tools.decorators import asyncify from .transfer import TransferMoneyDialog from . import toast import logging +import asyncio class TransactionsTabWidget(QWidget, Ui_transactionsTabWidget): @@ -43,8 +45,10 @@ class TransactionsTabWidget(QWidget, Ui_transactionsTabWidget): self.refresh() self.stop_progress([]) + @asyncify + @asyncio.coroutine def refresh_minimum_maximum(self): - block = self.community.get_block(1) + block = yield from self.community.get_block(1) minimum_datetime = QDateTime() minimum_datetime.setTime_t(block['medianTime']) minimum_datetime.setTime(QTime(0, 0)) @@ -104,6 +108,8 @@ class TransactionsTabWidget(QWidget, Ui_transactionsTabWidget): self.table_history.model().sourceModel().refresh_transfers() self.table_history.resizeColumnsToContents() + @asyncify + @asyncio.coroutine def refresh_balance(self): if self.app.preferences['expert_mode']: # if referential is "units" @@ -118,9 +124,12 @@ class TransactionsTabWidget(QWidget, Ui_transactionsTabWidget): proxy = self.table_history.model() balance = proxy.deposits - proxy.payments - localized_deposits = self.app.current_account.current_ref(proxy.deposits, self.community, self.app).diff_localized() - localized_payments = self.app.current_account.current_ref(proxy.payments, self.community, self.app).diff_localized() - localized_balance = self.app.current_account.current_ref(balance, self.community, self.app).diff_localized() + localized_deposits = yield from self.app.current_account.current_ref(proxy.deposits, self.community, + self.app).diff_localized() + localized_payments = yield from self.app.current_account.current_ref(proxy.payments, self.community, + self.app).diff_localized() + localized_balance = yield from self.app.current_account.current_ref(balance, self.community, + self.app).diff_localized() self.label_deposit.setText(QCoreApplication.translate("TransactionsTabWidget", "<b>Deposits</b> {:} {:}").format( localized_deposits, @@ -136,8 +145,9 @@ class TransactionsTabWidget(QWidget, Ui_transactionsTabWidget): )) else: - amount = self.app.current_account.amount(self.community) - localized_amount = self.app.current_account.current_ref(amount, self.community, self.app).localized(units=True) + amount = yield from self.app.current_account.amount(self.community) + localized_amount = yield from self.app.current_account.current_ref(amount, self.community, + self.app).localized(units=True) # set infos in label self.label_balance.setText( diff --git a/src/cutecoin/gui/transfer.py b/src/cutecoin/gui/transfer.py index 273c76ad4c4fd83f99796c2aeb26cc629d039e5d..7d2991da7bd2f59fb4331b5edfb6ef22c1355c0d 100644 --- a/src/cutecoin/gui/transfer.py +++ b/src/cutecoin/gui/transfer.py @@ -9,6 +9,7 @@ from PyQt5.QtGui import QRegExpValidator from ..gen_resources.transfer_uic import Ui_TransferMoneyDialog from . import toast +from ..tools.decorators import asyncify import asyncio @@ -35,7 +36,6 @@ class TransferMoneyDialog(QDialog, Ui_TransferMoneyDialog): self.wallet = None self.community = self.account.communities[0] self.wallet = self.account.wallets[0] - self.dividend = self.community.dividend regexp = QRegExp('^([ a-zA-Z0-9-_:/;*?\[\]\(\)\\\?!^+=@&~#{}|<>%.]{0,255})$') validator = QRegExpValidator(regexp) @@ -105,44 +105,57 @@ class TransferMoneyDialog(QDialog, Ui_TransferMoneyDialog): self.wallet.broadcast_error.disconnect(self.handle_error) QApplication.restoreOverrideCursor() + @asyncify + @asyncio.coroutine def amount_changed(self): + dividend = yield from self.community.dividend() amount = self.spinbox_amount.value() - relative = amount / self.dividend + relative = amount / dividend self.spinbox_relative.blockSignals(True) self.spinbox_relative.setValue(relative) self.spinbox_relative.blockSignals(False) + @asyncify + @asyncio.coroutine def relative_amount_changed(self): + dividend = yield from self.community.dividend() relative = self.spinbox_relative.value() - amount = relative * self.dividend + amount = relative * dividend self.spinbox_amount.blockSignals(True) self.spinbox_amount.setValue(amount) self.spinbox_amount.blockSignals(False) + @asyncify + @asyncio.coroutine def change_current_community(self, index): self.community = self.account.communities[index] - self.dividend = self.community.dividend - amount = self.wallet.value(self.community) + amount = yield from self.wallet.value(self.community) - ref_text = self.account.current_ref(amount, self.community, self.app)\ - .diff_localized(units=True, international_system=self.app.preferences['international_system_of_units']) + ref_text = yield from self.account.current_ref(amount, self.community, self.app)\ + .diff_localized(units=True, + international_system=self.app.preferences['international_system_of_units']) self.label_total.setText("{0}".format(ref_text)) self.spinbox_amount.setSuffix(" " + self.community.currency) self.spinbox_amount.setValue(0) - amount = self.wallet.value(self.community) - relative = amount / self.dividend + amount = yield from self.wallet.value(self.community) + dividend = yield from self.community.dividend() + relative = amount / dividend self.spinbox_amount.setMaximum(amount) self.spinbox_relative.setMaximum(relative) + @asyncify + @asyncio.coroutine def change_displayed_wallet(self, index): self.wallet = self.account.wallets[index] - amount = self.wallet.value(self.community) - ref_text = self.account.current_ref(amount, self.community, self.app)\ - .diff_localized(units=True, international_system=self.app.preferences['international_system_of_units']) + amount = yield from self.wallet.value(self.community) + ref_text = yield from self.account.current_ref(amount, self.community, self.app)\ + .diff_localized(units=True, + international_system=self.app.preferences['international_system_of_units']) self.label_total.setText("{0}".format(ref_text)) self.spinbox_amount.setValue(0) - amount = self.wallet.value(self.community) - relative = amount / self.dividend + amount = yield from self.wallet.value(self.community) + dividend = yield from self.community.dividend() + relative = amount / dividend self.spinbox_amount.setMaximum(amount) self.spinbox_relative.setMaximum(relative) diff --git a/src/cutecoin/gui/wot_tab.py b/src/cutecoin/gui/wot_tab.py index f8a022d4ec86b0b9b838d26e963e800cc9f78f50..d5fb282a969e1aa1972714e245b5e04c255d8e82 100644 --- a/src/cutecoin/gui/wot_tab.py +++ b/src/cutecoin/gui/wot_tab.py @@ -188,9 +188,9 @@ class WotTabWidget(QWidget, Ui_WotTabWidget): graph.add_identity(identity, node_status) # populate graph with certifiers-of - graph.add_certifier_list(certifier_list, identity, identity_account) + yield from graph.add_certifier_list(certifier_list, identity, identity_account) # populate graph with certified-by - graph.add_certified_list(certified_list, identity, identity_account) + yield from graph.add_certified_list(certified_list, identity, identity_account) # draw graph in qt scene self.graphicsView.scene().update_wot(graph.get()) @@ -198,7 +198,7 @@ class WotTabWidget(QWidget, Ui_WotTabWidget): # if selected member is not the account member... if identity.pubkey != identity_account.pubkey: # add path from selected member to account member - path = graph.get_shortest_path_between_members(identity, identity_account) + path = yield from graph.get_shortest_path_between_members(identity, identity_account) if path: self.graphicsView.scene().update_path(path) diff --git a/src/cutecoin/models/identities.py b/src/cutecoin/models/identities.py index 52af9851a01f45ea599c9194fa902df19203dea2..9ec30c983a497d7dd7cf9232c14df5de78d3e509 100644 --- a/src/cutecoin/models/identities.py +++ b/src/cutecoin/models/identities.py @@ -45,7 +45,7 @@ class IdentitiesFilterProxyModel(QSortFilterProxyModel): expiration_index = self.sourceModel().index(source_index.row(), expiration_col) expiration_data = self.sourceModel().data(expiration_index, Qt.DisplayRole) current_time = QDateTime().currentDateTime().toMSecsSinceEpoch() - sig_validity = self.community.parameters['sigValidity'] + sig_validity = self.sourceModel().sig_validity() warning_expiration_time = int(sig_validity / 3) #logging.debug("{0} > {1}".format(current_time, expiration_data)) if expiration_data is not None: @@ -92,11 +92,14 @@ class IdentitiesTableModel(QAbstractTableModel): 'validation': self.tr('Validation')} self.columns_ids = ('uid', 'pubkey', 'renewed', 'expiration') self.identities_data = [] - self._identities = [] + self._sig_validity = 0 def change_community(self, community): self.community = community + def sig_validity(self): + return self._sig_validity + @property def pubkeys(self): """ @@ -125,12 +128,12 @@ class IdentitiesTableModel(QAbstractTableModel): """ logging.debug("Refresh {0} identities".format(len(identities))) self.identities_data = [] - self._identities = [] self.beginResetModel() for identity in identities: - self._identities.append(identity) data = yield from self.identity_data(identity) self.identities_data.append(data) + parameters = yield from self.community.parameters() + self._sig_validity = parameters['sigValidity'] self.endResetModel() def rowCount(self, parent): diff --git a/src/cutecoin/models/network.py b/src/cutecoin/models/network.py index 6282af4647fa54a265887a44730b5616c35fad6d..4e6000d4a383517521b4bff51e58db59f53ea3e4 100644 --- a/src/cutecoin/models/network.py +++ b/src/cutecoin/models/network.py @@ -5,11 +5,13 @@ Created on 5 févr. 2014 """ import logging +import asyncio from PyQt5.QtCore import QAbstractTableModel, Qt, QVariant, QSortFilterProxyModel from PyQt5.QtGui import QColor, QFont from ..tools.exceptions import NoPeerAvailable +from ..tools.decorators import asyncify from cutecoin.core.net.node import Node @@ -19,7 +21,7 @@ class NetworkFilterProxyModel(QSortFilterProxyModel): self.community = None def columnCount(self, parent): - return self.sourceModel().columnCount(None) - 1 + return self.sourceModel().columnCount(None) - 2 def change_community(self, community): self.community = community @@ -112,7 +114,8 @@ class NetworkTableModel(QAbstractTableModel): 'pubkey', 'software', 'version', - 'is_root' + 'is_root', + 'state' ) self.node_colors = { Node.ONLINE: QColor('#99ff99'), @@ -126,31 +129,13 @@ class NetworkTableModel(QAbstractTableModel): Node.DESYNCED: self.tr('Unsynchronized'), Node.CORRUPTED: self.tr('Corrupted') } + self.nodes_data = [] def change_community(self, community): - self.beginResetModel() self.community = community - self.endResetModel() - - @property - def nodes(self): - if self.community: - return self.community.network.nodes - else: - return [] - - def rowCount(self, parent): - return len(self.nodes) - - def columnCount(self, parent): - return len(self.columns_types) - - def headerData(self, section, orientation, role): - if role != Qt.DisplayRole: - return QVariant() - - return self.columns_types[section] + self.refresh_nodes() + @asyncio.coroutine def data_node(self, node: Node) -> tuple: """ Return node data tuple @@ -158,7 +143,8 @@ class NetworkTableModel(QAbstractTableModel): :return: """ try: - is_member = node.pubkey in self.community.members_pubkeys() + members_pubkey = yield from self.community.members_pubkeys() + is_member = node.pubkey in members_pubkey except NoPeerAvailable as e: logging.error(e) is_member = None @@ -175,7 +161,30 @@ class NetworkTableModel(QAbstractTableModel): is_root = self.community.network.is_root_node(node) return (address, port, node.block['number'], node.block['hash'], node.uid, - is_member, node.pubkey, node.software, node.version, is_root) + is_member, node.pubkey, node.software, node.version, is_root, node.state) + + @asyncify + @asyncio.coroutine + def refresh_nodes(self): + self.beginResetModel() + self.nodes_data = [] + if self.community: + for node in self.community.network.nodes: + data = yield from self.data_node(node) + self.nodes_data.append(data) + self.endResetModel() + + def rowCount(self, parent): + return len(self.nodes_data) + + def columnCount(self, parent): + return len(self.columns_types) + + def headerData(self, section, orientation, role): + if role != Qt.DisplayRole: + return QVariant() + + return self.columns_types[section] def data(self, index, role): row = index.row() @@ -184,13 +193,13 @@ class NetworkTableModel(QAbstractTableModel): if not index.isValid(): return QVariant() - node = self.nodes[row] + node = self.nodes_data[row] if role == Qt.DisplayRole: - return self.data_node(node)[col] + return node[col] if role == Qt.BackgroundColorRole: - return self.node_colors[node.state] + return self.node_colors[node[self.columns_types.index('state')]] if role == Qt.ToolTipRole: - return self.node_states[node.state] + return self.node_states[node[self.columns_types.index('state')]] return QVariant() diff --git a/src/cutecoin/models/txhistory.py b/src/cutecoin/models/txhistory.py index 4576cdaf82905efdca9e996902fb27b9f441d944..b95d7b61581085835e701c69bea638e4b9ad6ca3 100644 --- a/src/cutecoin/models/txhistory.py +++ b/src/cutecoin/models/txhistory.py @@ -6,8 +6,9 @@ Created on 5 févr. 2014 import datetime import logging -from ..core import money +import asyncio from ..core.transfer import Transfer +from ..tools.decorators import asyncify from PyQt5.QtCore import QAbstractTableModel, Qt, QVariant, QSortFilterProxyModel, \ QDateTime, QLocale, QModelIndex @@ -51,14 +52,14 @@ class TxFilterProxyModel(QSortFilterProxyModel): if in_period(date): # calculate sum total payments payment = source_model.data( - source_model.index(sourceRow, source_model.columns_types.index('payment')), + source_model.index(sourceRow, source_model.columns_types.index('amount')), Qt.DisplayRole ) if payment: self.payments += int(payment) # calculate sum total deposits deposit = source_model.data( - source_model.index(sourceRow, source_model.columns_types.index('deposit')), + source_model.index(sourceRow, source_model.columns_types.index('amount')), Qt.DisplayRole ) if deposit: @@ -67,7 +68,7 @@ class TxFilterProxyModel(QSortFilterProxyModel): return in_period(date) def columnCount(self, parent): - return self.sourceModel().columnCount(None) - 4 + return self.sourceModel().columnCount(None) - 5 def setSourceModel(self, sourceModel): self.community = sourceModel.community @@ -111,9 +112,7 @@ class TxFilterProxyModel(QSortFilterProxyModel): ) if source_index.column() == model.columns_types.index('payment') or \ source_index.column() == model.columns_types.index('deposit'): - if source_data is not "": - return self.account.current_ref(source_data, self.community, self.app)\ - .diff_localized(international_system=self.app.preferences['international_system_of_units']) + return source_data if role == Qt.FontRole: font = QFont() @@ -153,7 +152,7 @@ class TxFilterProxyModel(QSortFilterProxyModel): current_validations = self.community.network.latest_block_number - block_data else: current_validations = 0 - max_validations = self.community.network.fork_window(self.community.members_pubkeys()) + 1 + max_validations = self.sourceModel().max_validations() if self.app.preferences['expert_mode']: return self.tr("{0} / {1} validations").format(current_validations, max_validations) @@ -182,6 +181,7 @@ class HistoryTableModel(QAbstractTableModel): self.account._current_ref self.transfers_data = [] self.refresh_transfers() + self._max_validation = 0 self.columns_types = ( 'date', @@ -192,7 +192,8 @@ class HistoryTableModel(QAbstractTableModel): 'state', 'txid', 'pubkey', - 'block_number' + 'block_number', + 'amount' ) self.column_headers = ( @@ -215,8 +216,11 @@ class HistoryTableModel(QAbstractTableModel): def transfers(self): return self.account.transfers(self.community) + self.account.dividends(self.community) + @asyncio.coroutine def data_received(self, transfer): amount = transfer.metadata['amount'] + deposit = yield from self.account.current_ref(transfer.metadata['amount'], self.community, self.app)\ + .diff_localized(international_system=self.app.preferences['international_system_of_units']) comment = "" if transfer.metadata['comment'] != "": comment = transfer.metadata['comment'] @@ -229,12 +233,15 @@ class HistoryTableModel(QAbstractTableModel): txid = transfer.metadata['txid'] block_number = transfer.metadata['block'] - return (date_ts, sender, "", amount, + return (date_ts, sender, "", deposit, comment, transfer.state, txid, - transfer.metadata['issuer'], block_number) + transfer.metadata['issuer'], block_number, amount) + @asyncio.coroutine def data_sent(self, transfer): amount = transfer.metadata['amount'] + paiment = yield from self.account.current_ref(transfer.metadata['amount'], self.community, self.app)\ + .diff_localized(international_system=self.app.preferences['international_system_of_units']) comment = "" if transfer.metadata['comment'] != "": comment = transfer.metadata['comment'] @@ -247,12 +254,15 @@ class HistoryTableModel(QAbstractTableModel): txid = transfer.metadata['txid'] block_number = transfer.metadata['block'] - return (date_ts, receiver, amount, + return (date_ts, receiver, paiment, "", comment, transfer.state, txid, - transfer.metadata['receiver'], block_number) + transfer.metadata['receiver'], block_number, amount) + @asyncio.coroutine def data_dividend(self, dividend): amount = dividend['amount'] + deposit = yield from self.account.current_ref(dividend['amount'], self.community, self.app)\ + .diff_localized(international_system=self.app.preferences['international_system_of_units']) comment = "" receiver = self.account.name date_ts = dividend['time'] @@ -261,22 +271,32 @@ class HistoryTableModel(QAbstractTableModel): state = dividend['state'] return (date_ts, receiver, "", - amount, "", state, id, - self.account.pubkey, block_number) + deposit, "", state, id, + self.account.pubkey, block_number, amount) + @asyncify + @asyncio.coroutine def refresh_transfers(self): self.beginResetModel() self.transfers_data = [] for transfer in self.transfers: + data = None if type(transfer) is Transfer: if transfer.metadata['issuer'] == self.account.pubkey: - self.transfers_data.append(self.data_sent(transfer)) + data = yield from self.data_sent(transfer) else: - self.transfers_data.append(self.data_received(transfer)) + data = yield from self.data_received(transfer) elif type(transfer) is dict: - self.transfers_data.append(self.data_dividend(transfer)) + data = yield from self.data_dividend(transfer) + if data: + self.transfers_data.append(data) + members_pubkeys = yield from self.community.members_pubkeys() + self._max_validation = self.community.network.fork_window(members_pubkeys) + 1 self.endResetModel() + def max_validation(self): + return self._max_validation + def rowCount(self, parent): return len(self.transfers_data) diff --git a/src/cutecoin/tests/gui/identities_tab/test_identities_table.py b/src/cutecoin/tests/gui/identities_tab/test_identities_table.py index a5f582842e130c7a6817001c0ab68742eb9166a1..83e54e923d69619a75c5f6dbe27785a61e386160 100644 --- a/src/cutecoin/tests/gui/identities_tab/test_identities_table.py +++ b/src/cutecoin/tests/gui/identities_tab/test_identities_table.py @@ -97,9 +97,12 @@ class TestIdentitiesTable(unittest.TestCase): yield from asyncio.sleep(2) self.assertEqual(mock.get_request(3).method, 'GET') self.assertEqual(mock.get_request(3).url, - '/wot/lookup/doe') + '/blockchain/parameters') self.assertEqual(mock.get_request(4).method, 'GET') self.assertEqual(mock.get_request(4).url, + '/wot/lookup/doe') + self.assertEqual(mock.get_request(5).method, 'GET') + self.assertEqual(mock.get_request(5).url, '/wot/certifiers-of/FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn') self.assertEqual(identities_tab.table_identities.model().rowCount(), 1) yield from asyncio.sleep(2)