From 401e2c9b78993b6e29e29d0b972f8cc2612486d1 Mon Sep 17 00:00:00 2001
From: inso <insomniak.fr@gmaiL.com>
Date: Sun, 15 Jan 2017 20:25:20 +0100
Subject: [PATCH] Load certifications in lookup

---
 src/sakia/data/entities/certification.py      |  2 +-
 src/sakia/data/graphs/wot_graph.py            |  4 ++
 src/sakia/data/processors/blockchain.py       |  4 +-
 .../gui/navigation/informations/controller.py |  5 +-
 src/sakia/services/identities.py              | 54 +++++++++++++++++--
 5 files changed, 61 insertions(+), 8 deletions(-)

diff --git a/src/sakia/data/entities/certification.py b/src/sakia/data/entities/certification.py
index d59b7ff7..1cd5959b 100644
--- a/src/sakia/data/entities/certification.py
+++ b/src/sakia/data/entities/certification.py
@@ -8,6 +8,6 @@ class Certification:
     certifier = attr.ib(convert=str)
     certified = attr.ib(convert=str)
     block = attr.ib(convert=int)
-    timestamp = attr.ib(convert=int)
+    timestamp = attr.ib(convert=int, cmp=False)
     signature = attr.ib(convert=str, cmp=False, hash=False)
     written_on = attr.ib(convert=int, default=0, cmp=False, hash=False)
diff --git a/src/sakia/data/graphs/wot_graph.py b/src/sakia/data/graphs/wot_graph.py
index d93d0d57..7d143e82 100644
--- a/src/sakia/data/graphs/wot_graph.py
+++ b/src/sakia/data/graphs/wot_graph.py
@@ -28,6 +28,10 @@ class WoTGraph(BaseGraph):
 
         certifier_list, certified_list = await asyncio.gather(*[certifier_coro, certified_coro])
 
+        certified_list, certified_list = await self.identities_service.load_certs_in_lookup(center_identity,
+                                                                                            certifier_list,
+                                                                                            certified_list)
+
         # populate graph with certifiers-of
         certifier_coro = asyncio.ensure_future(self.add_certifier_list(certifier_list,
                                                                        center_identity, connection_identity))
diff --git a/src/sakia/data/processors/blockchain.py b/src/sakia/data/processors/blockchain.py
index 7d3aaa54..5b2ae605 100644
--- a/src/sakia/data/processors/blockchain.py
+++ b/src/sakia/data/processors/blockchain.py
@@ -26,9 +26,9 @@ class BlockchainProcessor:
         return cls(app.db.blockchains_repo,
                    BmaConnector(NodesProcessor(app.db.nodes_repo), app.parameters))
 
-    async def timestamp(self, currency, blockstamp):
+    async def timestamp(self, currency, block_number):
         try:
-            block = await self._bma_connector.get(currency, bma.blockchain.block, {'number': blockstamp.number})
+            block = await self._bma_connector.get(currency, bma.blockchain.block, {'number': block_number})
             if block:
                 return block['medianTime']
         except NoPeerAvailable as e:
diff --git a/src/sakia/gui/navigation/informations/controller.py b/src/sakia/gui/navigation/informations/controller.py
index 074699c1..52cfdd83 100644
--- a/src/sakia/gui/navigation/informations/controller.py
+++ b/src/sakia/gui/navigation/informations/controller.py
@@ -24,6 +24,7 @@ class InformationsController(QObject):
         super().__init__(parent)
         self.view = view
         self.model = model
+        self._logger = logging.getLogger('sakia')
 
     @property
     def informations_view(self):
@@ -85,13 +86,13 @@ class InformationsController(QObject):
             all_data = {**simple_data, **localized_data}
             self.view.set_simple_informations(all_data, InformationsView.CommunityState.READY)
         except NoPeerAvailable as e:
-            logging.debug(str(e))
+            self._logger.debug(str(e))
             self.view.set_simple_informations(all_data, InformationsView.CommunityState.OFFLINE)
         except errors.DuniterError as e:
             if e.ucode == errors.BLOCK_NOT_FOUND:
                 self.view.set_simple_informations(all_data, InformationsView.CommunityState.NOT_INIT)
             else:
-                raise
+                self._logger.debug(str(e))
 
         self.view.set_general_text(localized_data)
         self.view.set_rules_text(localized_data)
diff --git a/src/sakia/services/identities.py b/src/sakia/services/identities.py
index a3213271..0c60f35d 100644
--- a/src/sakia/services/identities.py
+++ b/src/sakia/services/identities.py
@@ -90,7 +90,8 @@ class IdentitiesService(QObject):
                     blockstamp = BlockUID(ms["blockNumber"], ms['blockHash'])
                     membership_data = ms
             if membership_data:
-                identity.membership_timestamp = await self._blockchain_processor.timestamp(self.currency, blockstamp)
+                identity.membership_timestamp = await self._blockchain_processor.timestamp(self.currency,
+                                                                                           blockstamp.number)
                 identity.membership_buid = blockstamp
                 identity.membership_type = ms["membership"]
                 identity.membership_written_on = ms["written"]
@@ -109,6 +110,53 @@ class IdentitiesService(QObject):
             logging.debug(str(e))
         return identity
 
+    async def load_certs_in_lookup(self, identity, certifiers, certified):
+        """
+        :param sakia.data.entities.Identity identity: the identity
+        :param sakia.data.entities.Certification certifiers: the list of certifiers got in /wot/certifiers-of
+        :param sakia.data.entities.Certification certified: the list of certified got in /wot/certified-by
+        """
+        try:
+            lookup_data = await self._bma_connector.get(self.currency, bma.wot.lookup,
+                                                 {'search': identity.pubkey})
+            for result in lookup_data['results']:
+                if result["pubkey"] == identity.pubkey:
+                    for uid_data in result['uids']:
+                        if uid_data["uid"] == identity.uid:
+                            for other_data in uid_data["others"]:
+                                cert = Certification(currency=self.currency,
+                                                     certified=identity.pubkey,
+                                                     certifier=other_data["pubkey"],
+                                                     block=other_data["meta"]["block_number"],
+                                                     timestamp=0,
+                                                     signature=other_data['signature'])
+                                if cert not in certifiers:
+                                    cert.timestamp = await self._blockchain_processor.timestamp(self.currency,
+                                                                                                cert.block)
+                                    certifiers.append(cert)
+                                    # We save connections pubkeys
+                                    if identity.pubkey in self._connections_processor.pubkeys():
+                                        self._certs_processor.insert_or_update_certification(cert)
+                for signed_data in result["signed"]:
+                    cert = Certification(currency=self.currency,
+                                         certified=signed_data["pubkey"],
+                                         certifier=identity.pubkey,
+                                         block=signed_data["cert_time"]["block"],
+                                         timestamp=0,
+                                         signature=signed_data['signature'])
+                    if cert not in certified:
+                        certified.append(cert)
+                        # We save connections pubkeys
+                        if identity.pubkey in self._connections_processor.pubkeys():
+                            cert.timestamp = await self._blockchain_processor.timestamp(self.currency,
+                                                                                        cert.block)
+                            self._certs_processor.insert_or_update_certification(cert)
+        except errors.DuniterError as e:
+            logging.debug("Certified by error : {0}".format(str(e)))
+        except NoPeerAvailable as e:
+            logging.debug(str(e))
+        return certifiers, certified
+
     async def load_certifiers_of(self, identity):
         """
         Request the identity data and save it to written certifications
@@ -273,7 +321,7 @@ class IdentitiesService(QObject):
             for identity in connections_identities:
                 if cert.pubkey_from == identity.pubkey or cert.pubkey_to in identity.pubkey:
                     identity.written = True
-                    timestamp = await self._blockchain_processor.timestamp(self.currency, cert.timestamp)
+                    timestamp = await self._blockchain_processor.timestamp(self.currency, cert.timestamp.number)
                     self._certs_processor.create_or_update_certification(self.currency, cert, timestamp, block.blockUID)
                     need_refresh.append(identity)
         return need_refresh
@@ -290,7 +338,7 @@ class IdentitiesService(QObject):
             identity_data = requirements['identities'][0]
             identity.uid = identity_data["uid"]
             identity.blockstamp = block_uid(identity_data["meta"]["timestamp"])
-            identity.timestamp = await self._blockchain_processor.timestamp(self.currency, identity.blockstamp)
+            identity.timestamp = await self._blockchain_processor.timestamp(self.currency, identity.blockstamp.number)
             identity.outdistanced = identity_data["outdistanced"]
             identity.member = identity_data["membershipExpiresIn"] > 0 and not identity_data["outdistanced"]
             median_time = self._blockchain_processor.time(self.currency)
-- 
GitLab