From ac91a0156f5e96bb4f04bb07e0f1acece6f43dcd Mon Sep 17 00:00:00 2001
From: Inso <insomniak.fr@gmail.com>
Date: Tue, 20 May 2014 17:29:58 +0200
Subject: [PATCH] WHT management : we can now push a WHT

---
 lib/ucoin/pks/__init__.py                     |  2 +-
 res/ui/walletTabWidget.ui                     | 36 +++++++++-
 src/cutecoin/gui/processConfigureAccount.py   | 13 ++--
 src/cutecoin/gui/processConfigureCommunity.py | 14 +++-
 src/cutecoin/models/account/__init__.py       |  2 +-
 .../models/account/wallets/__init__.py        |  6 +-
 src/cutecoin/models/wallet/__init__.py        | 72 +++++++++++--------
 7 files changed, 105 insertions(+), 40 deletions(-)

diff --git a/lib/ucoin/pks/__init__.py b/lib/ucoin/pks/__init__.py
index d13a28a6..ecb92cac 100644
--- a/lib/ucoin/pks/__init__.py
+++ b/lib/ucoin/pks/__init__.py
@@ -24,7 +24,7 @@ logger = logging.getLogger("ucoin/pks")
 
 class PKS(API):
     def __init__(self, module='pks', server=None, port=None):
-        super().__init__(module=module, server, port)
+        super().__init__(module=module, server=server, port=port)
 
 
 class Add(PKS):
diff --git a/res/ui/walletTabWidget.ui b/res/ui/walletTabWidget.ui
index 7d041555..a8e08a35 100644
--- a/res/ui/walletTabWidget.ui
+++ b/res/ui/walletTabWidget.ui
@@ -26,6 +26,40 @@
      <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>
@@ -36,6 +70,6 @@
  <resources/>
  <connections/>
  <slots>
-  <slot>open_issuance_dialog()</slot>
+  <slot>required_trusts_changed(int)</slot>
  </slots>
 </ui>
diff --git a/src/cutecoin/gui/processConfigureAccount.py b/src/cutecoin/gui/processConfigureAccount.py
index f74222db..4dc3b0be 100644
--- a/src/cutecoin/gui/processConfigureAccount.py
+++ b/src/cutecoin/gui/processConfigureAccount.py
@@ -62,12 +62,14 @@ class StepPageCommunities(Step):
         self.config_dialog.community = account.communities.add_community(
             default_node)
         #TODO: Get existing Wallet from ucoin node
-        account.wallets.add_wallet(account.fingerprint,
+        account.wallets.add_wallet(account.keyid,
                                    self.config_dialog.community)
 
     def display_page(self):
         self.config_dialog.button_previous.setEnabled(False)
         self.config_dialog.button_next.setText("Ok")
+        list_model = CommunitiesListModel(self.config_dialog.account)
+        self.config_dialog.list_communities.setModel(list_model)
 
 
 class ProcessConfigureAccount(QDialog, Ui_AccountConfigurationDialog):
@@ -88,6 +90,7 @@ class ProcessConfigureAccount(QDialog, Ui_AccountConfigurationDialog):
         step_communities = StepPageCommunities(self)
         step_init.next_step = step_communities
         self.step = step_init
+        self.step.display_page()
         if self.account is None:
             self.setWindowTitle("New account")
         else:
@@ -119,9 +122,9 @@ class ProcessConfigureAccount(QDialog, Ui_AccountConfigurationDialog):
         self.edit_account_name.setText(self.account.name)
 
     def open_process_add_community(self):
-            dialog = ProcessConfigureCommunity(self.account, None)
-            dialog.accepted.connect(self.action_add_community)
-            dialog.exec_()
+        dialog = ProcessConfigureCommunity(self.account, None)
+        dialog.accepted.connect(self.action_add_community)
+        dialog.exec_()
 
     def action_add_community(self):
         self.combo_keys_list.setEnabled(False)
@@ -142,7 +145,7 @@ class ProcessConfigureAccount(QDialog, Ui_AccountConfigurationDialog):
     def open_process_edit_community(self, index):
         community = self.account.communities[index.row()]
         dialog = ProcessConfigureCommunity(self.account, community)
-        dialog.button_box.accepted.connect(self.action_edit_community)
+        dialog.accepted.connect(self.action_edit_community)
         dialog.exec_()
 
     def key_changed(self, key_index):
diff --git a/src/cutecoin/gui/processConfigureCommunity.py b/src/cutecoin/gui/processConfigureCommunity.py
index 0a099fcb..1b9d5ddf 100644
--- a/src/cutecoin/gui/processConfigureCommunity.py
+++ b/src/cutecoin/gui/processConfigureCommunity.py
@@ -144,8 +144,7 @@ class ProcessConfigureCommunity(QDialog, Ui_CommunityConfigurationDialog):
                 self.stacked_pages.setCurrentIndex(next_index)
                 self.step.display_page()
         else:
-            self.accepted.emit()
-            self.close()
+            self.accept()
 
     def previous(self):
         if self.step.previous_step is not None:
@@ -165,6 +164,10 @@ class ProcessConfigureCommunity(QDialog, Ui_CommunityConfigurationDialog):
             self.tree_nodes.setModel(NodesTreeModel(self.community,
                                                     self.nodes))
 
+    def required_trusts_changed(self, value):
+        wallet = self.account.wallets[self.tabs_wallets.currentIndex()]
+        wallet.required_trusts = value
+
     def showContextMenu(self, point):
         if self.stacked_pages.currentIndex() == 1:
             menu = QMenu()
@@ -173,3 +176,10 @@ class ProcessConfigureCommunity(QDialog, Ui_CommunityConfigurationDialog):
                 if len(self.nodes) == 1:
                     action.setEnabled(False)
             menu.exec_(self.mapToGlobal(point))
+
+    def accept(self):
+        for wallet in self.account.wallets:
+            wallet.push_wht()
+
+        self.accepted.emit()
+        self.close()
diff --git a/src/cutecoin/models/account/__init__.py b/src/cutecoin/models/account/__init__.py
index 943c36a0..fb0da9ed 100644
--- a/src/cutecoin/models/account/__init__.py
+++ b/src/cutecoin/models/account/__init__.py
@@ -72,7 +72,7 @@ class Account(object):
         amendment_data = promoted.get()
         currency = amendment_data['currency']
         community = self.communities.add_community(currency)
-        self.wallets.add_wallet(self.fingerprint(),
+        self.wallets.add_wallet(self.keyid,
                                    currency,
                                    default_node)
         return community
diff --git a/src/cutecoin/models/account/wallets/__init__.py b/src/cutecoin/models/account/wallets/__init__.py
index 9dd15ef9..6f7c8683 100644
--- a/src/cutecoin/models/account/wallets/__init__.py
+++ b/src/cutecoin/models/account/wallets/__init__.py
@@ -46,13 +46,15 @@ class Wallets(object):
     def __getitem__(self, key):
         return self._wallets_list[key]
 
-    def add_wallet(self, fingerprint, community, node, name="Main Wallet"):
+    def add_wallet(self, keyid, community, node,
+                   required_trusts=1, name="Main Wallet"):
         '''
         Create a new wallet of a specific currency.
         This wallet must not already be present in the account,
         it means the wallet must have a different name or a different currency.
         '''
-        wallet = Wallet.create(fingerprint, community, node, name)
+        wallet = Wallet.create(keyid, community, node,
+                               required_trusts, name)
         if wallet not in self._wallets_list:
             self._wallets_list.append(wallet)
             return wallet
diff --git a/src/cutecoin/models/wallet/__init__.py b/src/cutecoin/models/wallet/__init__.py
index 843af0b5..54971e9b 100644
--- a/src/cutecoin/models/wallet/__init__.py
+++ b/src/cutecoin/models/wallet/__init__.py
@@ -8,6 +8,7 @@ import ucoin
 import logging
 import gnupg
 import json
+import time
 from cutecoin.models.coin import Coin
 from cutecoin.models.node import Node
 from cutecoin.models.transaction import Transaction
@@ -21,21 +22,23 @@ class Wallet(object):
     It's only used to sort coins.
     '''
 
-    def __init__(self, fingerprint, coins, currency, nodes, name):
+    def __init__(self, keyid, coins, currency,
+                 nodes, required_trusts, name):
         '''
         Constructor
         '''
         self.coins = coins
-        self.fingerprint = fingerprint
+        self.keyid = keyid
         self.currency = currency
         self.name = name
         self.nodes = nodes
+        self.required_trusts = required_trusts
 
     @classmethod
-    def create(cls, fingerprint, currency, node, name):
+    def create(cls, keyid, currency, node, required_trusts, name):
         node.trust = True
         node.hoster = True
-        return cls(fingerprint, [], currency, [node], name)
+        return cls(keyid, [], currency, [node], required_trusts, name)
 
     @classmethod
     def load(cls, json_data):
@@ -47,10 +50,11 @@ class Wallet(object):
         for node_data in json_data['nodes']:
             nodes.append(Node.load(node_data))
 
-        fingerprint = json_data['fingerprint']
+        keyid = json_data['keyid']
         name = json_data['name']
         currency = json_data['currency']
-        return cls(fingerprint, coins, currency, nodes, name)
+        required_trusts = json_data['required_trusts']
+        return cls(keyid, coins, currency, nodes, required_trusts, name)
 
     def __eq__(self, other):
         return (self.community == other.community)
@@ -64,7 +68,7 @@ class Wallet(object):
     def transactions_received(self):
         received = []
         transactions_data = self.request(
-            ucoin.hdc.transactions.Recipient(self.fingerprint))
+            ucoin.hdc.transactions.Recipient(self.fingerprint()))
         for trx_data in transactions_data:
             received.append(
                 Transaction.create(
@@ -77,7 +81,7 @@ class Wallet(object):
         sent = []
         transactions_data = self.request(
             ucoin.hdc.transactions.sender.Last(
-                self.fingerprint, 20))
+                self.fingerprint(), 20))
         for trx_data in transactions_data:
             # Small bug in ucoinpy library
             if not isinstance(trx_data, str):
@@ -95,7 +99,7 @@ class Wallet(object):
         except ValueError:
             return None
 
-    def push_wht(self, community):
+    def push_wht(self):
         hosters_fg = []
         trusts_fg = []
         for trust in self.trusts():
@@ -106,27 +110,29 @@ class Wallet(object):
             logging.debug(peering)
             peering = hoster.peering()
             hosters_fg.append(peering['fingerprint'])
-        entry = {
-            'version': '1',
-            'currency': self.currency,
-            'issuer': self.fingerprint(),
-            'requiredTrusts': self.required_trusts,
-            'hosters': hosters_fg,
-            'trusts': trusts_fg
-        }
-        logging.debug(entry)
-        json_entry = json.JSONEncoder(indent=2).encode(entry)
+        wht_message = '''Version: 1
+Currency: %s
+Key: %s
+Date: %s
+RequiredTrusts: %d
+Hosters:
+''' % (self.currency, self.fingerprint(), 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")
         gpg = gnupg.GPG()
-        signature = gpg.sign(json_entry, keyid=self.keyid, clearsign=True)
+        signature = gpg.sign(wht_message, keyid=self.keyid, detach=True)
 
-        dataPost = {
-            'entry': entry,
-            'signature': str(signature)
-        }
+        data_post = {'entry': wht_message,
+                     'signature': str(signature)}
+        logging.debug(data_post)
 
-        self.post(ucoin.network.Wallet(
-                pgp_fingerprint=self.fingerprint()),
-            dataPost)
+        self.post(ucoin.network.Wallet(), data_post)
 
     # TODO: Check if its working
     def _search_node_by_fingerprint(self, node_fg, next_node, traversed_nodes=[]):
@@ -175,6 +181,16 @@ class Wallet(object):
     def hosters(self):
         return [node for node in self.nodes if node.hoster]
 
+    def fingerprint(self):
+        gpg = gnupg.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 get_text(self):
         return self.name + " : " + \
             str(self.value()) + " " + self.currency
@@ -193,7 +209,7 @@ class Wallet(object):
 
     def jsonify(self):
         return {'coins': self.jsonify_coins_list(),
-                'fingerprint': self.fingerprint,
+                'fingerprint': self.fingerprint(),
                 'name': self.name,
                 'currency': self.currency,
                 'nodes': self.jsonify_nodes_list()}
-- 
GitLab