From 3b24514b9b5e7900a7b547746bd135d11caadc78 Mon Sep 17 00:00:00 2001
From: Inso <insomniak.fr@gmail.com>
Date: Tue, 11 Feb 2014 23:59:31 +0100
Subject: [PATCH] =?UTF-8?q?Sauvegarde=20de=20fichier,=20utilisation=20de?=
 =?UTF-8?q?=20"factory"=20pour=20cr=C3=A9er=20des=20models=20a=20partir=20?=
 =?UTF-8?q?de=20rien=20ou=20a=20partir=20de=20json.?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 data.txt                                      | 25 +++++++++
 res/ui/addAccountDialog.ui                    |  2 +-
 res/ui/mainwindow.ui                          | 51 +++++++++++++++++--
 src/cutecoin/core/__init__.py                 | 42 ++++++++++++++-
 src/cutecoin/core/appData.py                  | 30 -----------
 src/cutecoin/core/exceptions.py               | 32 ++++++++++--
 src/cutecoin/gui/addAccountDialog.py          | 16 +++---
 src/cutecoin/gui/addCommunityDialog.py        |  2 -
 src/cutecoin/gui/mainWindow.py                |  9 +++-
 src/cutecoin/models/account/__init__.py       | 50 ++++++++++++------
 .../models/account/communities/__init__.py    | 38 ++++++++++----
 src/cutecoin/models/account/factory.py        | 36 +++++++++++++
 .../models/account/wallets/__init__.py        | 24 +++++++--
 src/cutecoin/models/coin/__init__.py          | 10 ++--
 src/cutecoin/models/community/__init__.py     | 50 ++++++++++--------
 src/cutecoin/models/community/factory.py      | 24 +++++++++
 .../models/community/issuancesListModel.py    |  2 +-
 .../models/community/membersListModel.py      | 13 ++---
 src/cutecoin/models/node/__init__.py          |  9 ++--
 src/cutecoin/models/person/__init__.py        | 21 ++++++++
 src/cutecoin/models/person/factory.py         | 31 +++++++++++
 src/cutecoin/models/transaction/__init__.py   | 33 +++++++++---
 .../models/transaction/receivedListModel.py   | 33 ++++++++++++
 .../models/transaction/sentListModel.py       | 33 ++++++++++++
 src/cutecoin/models/wallet/__init__.py        | 18 +++++--
 src/cutecoin/models/wallet/factory.py         | 21 ++++++++
 26 files changed, 524 insertions(+), 131 deletions(-)
 create mode 100644 data.txt
 delete mode 100644 src/cutecoin/core/appData.py
 create mode 100644 src/cutecoin/models/account/factory.py
 create mode 100644 src/cutecoin/models/community/factory.py
 create mode 100644 src/cutecoin/models/person/__init__.py
 create mode 100644 src/cutecoin/models/person/factory.py
 create mode 100644 src/cutecoin/models/transaction/receivedListModel.py
 create mode 100644 src/cutecoin/models/transaction/sentListModel.py
 create mode 100644 src/cutecoin/models/wallet/factory.py

diff --git a/data.txt b/data.txt
new file mode 100644
index 00000000..ffba9fb0
--- /dev/null
+++ b/data.txt
@@ -0,0 +1,25 @@
+{
+    "localAccounts": [
+        {
+            "communities": [
+                {
+                    "currency": "beta_brousouf", 
+                    "nodes": [
+                        {
+                            "port": 9101, 
+                            "server": "ucoin.twiced.fr"
+                        }
+                    ]
+                }
+            ], 
+            "name": "Inso", 
+            "pgpKeyId": "3EA42BBCAAD72714", 
+            "wallets": [
+                {
+                    "coins": [], 
+                    "currency": "beta_brousouf"
+                }
+            ]
+        }
+    ]
+}
\ No newline at end of file
diff --git a/res/ui/addAccountDialog.ui b/res/ui/addAccountDialog.ui
index 94999db1..8cba07b0 100644
--- a/res/ui/addAccountDialog.ui
+++ b/res/ui/addAccountDialog.ui
@@ -47,7 +47,7 @@
          </widget>
         </item>
         <item>
-         <widget class="QComboBox" name="gpgKeysList"/>
+         <widget class="QComboBox" name="pgpKeysList"/>
         </item>
        </layout>
       </item>
diff --git a/res/ui/mainwindow.ui b/res/ui/mainwindow.ui
index 349fdfce..8d2640f9 100644
--- a/res/ui/mainwindow.ui
+++ b/res/ui/mainwindow.ui
@@ -6,8 +6,8 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>452</width>
-    <height>400</height>
+    <width>498</width>
+    <height>437</height>
    </rect>
   </property>
   <property name="windowTitle">
@@ -113,7 +113,7 @@
     <rect>
      <x>0</x>
      <y>0</y>
-     <width>452</width>
+     <width>498</width>
      <height>20</height>
     </rect>
    </property>
@@ -124,6 +124,8 @@
     <addaction name="actionChange_account"/>
     <addaction name="actionAdd_account"/>
     <addaction name="separator"/>
+    <addaction name="actionSave"/>
+    <addaction name="actionQuit"/>
    </widget>
    <widget class="QMenu" name="menuEdit">
     <property name="title">
@@ -191,6 +193,16 @@
     <string>Add account</string>
    </property>
   </action>
+  <action name="actionSave">
+   <property name="text">
+    <string>Save</string>
+   </property>
+  </action>
+  <action name="actionQuit">
+   <property name="text">
+    <string>Quit</string>
+   </property>
+  </action>
  </widget>
  <resources/>
  <connections>
@@ -210,8 +222,41 @@
     </hint>
    </hints>
   </connection>
+  <connection>
+   <sender>actionSave</sender>
+   <signal>triggered()</signal>
+   <receiver>MainWindow</receiver>
+   <slot>save()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>225</x>
+     <y>199</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>225</x>
+     <y>199</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>actionQuit</sender>
+   <signal>triggered()</signal>
+   <receiver>MainWindow</receiver>
+   <slot>close()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>-1</x>
+     <y>-1</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>225</x>
+     <y>199</y>
+    </hint>
+   </hints>
+  </connection>
  </connections>
  <slots>
   <slot>openAddAccountDialog()</slot>
+  <slot>save()</slot>
  </slots>
 </ui>
diff --git a/src/cutecoin/core/__init__.py b/src/cutecoin/core/__init__.py
index 0267f0dc..35bd0972 100644
--- a/src/cutecoin/core/__init__.py
+++ b/src/cutecoin/core/__init__.py
@@ -4,8 +4,14 @@ Created on 1 févr. 2014
 @author: inso
 '''
 
-from cutecoin.core.appData import AppData
 from cutecoin.core import config
+from cutecoin.core.exceptions import KeyAlreadyUsed
+
+import json
+from cutecoin.core import config
+from cutecoin.models.account import factory
+import os
+
 
 class Core(object):
 
@@ -16,15 +22,47 @@ class Core(object):
         self.accounts = []
         self.currentAccount = None
         config.parseArguments(argv)
-        AppData().load(self)
+        self.load()
 
     def getAccounts(self):
         return self.accounts
 
     def addAccount(self, account):
+        for a in self.accounts:
+            if a.pgpKeyId == account.pgpKeyId:
+                raise KeyAlreadyUsed(account, account.pgpKeyId, a)
+
         self.accounts.append(account)
         self.currentAccount = account
 
     def delAccount(self, account):
         self.accounts.remove(account)
 
+
+    def load(self):
+        if (os.path.exists(config.data['home'])):
+            json_data=open(config.data['home'], 'w+')
+            data = json.load(json_data)
+            json_data.close()
+
+            for accountData in data['localAccounts']:
+                self.accounts.append(factory.loadAccount(accountData))
+
+
+    def save(self):
+        with open(config.data['home'], 'w+') as outfile:
+            json.dump(self.jsonify(), outfile, indent = 4, sort_keys=True)
+
+
+
+
+    def jsonifyAccounts(self):
+        data = []
+        for account in self.accounts:
+            data.append(account.jsonify())
+        return data
+
+    def jsonify(self):
+        data = {'localAccounts' : self.jsonifyAccounts()}
+        return data
+
diff --git a/src/cutecoin/core/appData.py b/src/cutecoin/core/appData.py
deleted file mode 100644
index 617bda8e..00000000
--- a/src/cutecoin/core/appData.py
+++ /dev/null
@@ -1,30 +0,0 @@
-'''
-Created on 7 févr. 2014
-
-@author: inso
-'''
-import json
-from cutecoin.core import config
-import os
-
-class AppData(object):
-    '''
-    classdocs
-    '''
-
-
-    def __init__(self):
-        '''
-        Constructor
-        '''
-
-    def load(self, core):
-        if (os.path.exists(config.data['home'])):
-            json_data=open(config.data['home'], 'w+')
-            data = json.load(json_data)
-            json_data.close()
-
-
-    def save(self, core):
-        #TODO: Sauvegarde de l'état de l'application
-        pass
\ No newline at end of file
diff --git a/src/cutecoin/core/exceptions.py b/src/cutecoin/core/exceptions.py
index 40e712bc..ec4bc921 100644
--- a/src/cutecoin/core/exceptions.py
+++ b/src/cutecoin/core/exceptions.py
@@ -14,12 +14,38 @@ class Error(Exception):
 
 class NotMemberOfCommunityError(Error):
     '''
-    Exception raised for error in the input
+    Exception raised when adding a community the account is not a member of
     '''
+    def __init__(self, account, community):
+        '''
+        Constructor
+        '''
+        super(NotMemberOfCommunityError, self) \
+            .__init__(account + " is not a member of " + community)
 
+class PersonNotFoundError(Error):
+    '''
+    Exception raised when looking for a person in a community who isnt present in key list
+    '''
+    def __init__(self, classType, value, community):
+        '''
+        Constructor
+        '''
+        super(PersonNotFoundError, self) \
+            .__init("Person looked by " + classType \
+                    + " in " + type + " not present in community " + community.name)
 
-    def __init__(self, account, community):
+
+class KeyAlreadyUsed(Error):
+    '''
+    Exception raised trying to add an account using a key already used for another account.
+    '''
+    def __init__(self, newAccount, keyId, foundAccount):
         '''
         Constructor
         '''
-        super(NotMemberOfCommunityError, self).__init__(account + " is not a member of " + community)
+        super(KeyAlreadyUsed, self) \
+            .__init("Cannot add account " + newAccount.name + " : " \
+                    " the pgpKey " + keyId + " is already used by " + foundAccount.name)
+
+
diff --git a/src/cutecoin/gui/addAccountDialog.py b/src/cutecoin/gui/addAccountDialog.py
index e4fdc2c2..9c5a6b7e 100644
--- a/src/cutecoin/gui/addAccountDialog.py
+++ b/src/cutecoin/gui/addAccountDialog.py
@@ -6,7 +6,7 @@ Created on 2 févr. 2014
 from cutecoin.gen_resources.addAccountDialog_uic import Ui_AddAccountDialog
 from PyQt5.QtWidgets import QDialog
 from cutecoin.gui.addCommunityDialog import AddCommunityDialog
-from cutecoin.models.account import Account
+from cutecoin.models.account import factory
 from cutecoin.models.account.communities import Communities
 from cutecoin.models.account.communities.listModel import CommunitiesListModel
 
@@ -36,11 +36,11 @@ class AddAccountDialog(QDialog, Ui_AddAccountDialog):
         gpg = gnupg.GPG()
         availableKeys = gpg.list_keys(True)
         for key in availableKeys:
-            self.gpgKeysList.addItem(key['uids'][0])
+            self.pgpKeysList.addItem(key['uids'][0])
 
-        self.account = Account(availableKeys[0]['keyid'], "", Communities())
-        self.gpgKeysList.setEnabled(True)
-        self.gpgKeysList.currentIndexChanged[int].connect(self.keyChanged)
+        self.account = factory.createAccount(availableKeys[0]['keyid'], "", Communities())
+        self.pgpKeysList.setEnabled(True)
+        self.pgpKeysList.currentIndexChanged[int].connect(self.keyChanged)
         self.communityDialog = AddCommunityDialog(self)
 
     def openAddCommunityDialog(self):
@@ -48,12 +48,12 @@ class AddAccountDialog(QDialog, Ui_AddAccountDialog):
         self.communityDialog.exec_()
 
     def actionAddCommunity(self):
-        self.gpgKeysList.setEnabled(False)
-        self.gpgKeysList.disconnect()
+        self.pgpKeysList.setEnabled(False)
+        self.pgpKeysList.disconnect()
         self.communitiesList.setModel(CommunitiesListModel(self.account))
 
     def keyChanged(self, keyIndex):
         gpg = gnupg.GPG()
         availableKeys = gpg.list_keys(True)
-        self.account.gpgKey = availableKeys[keyIndex]['keyid']
+        self.account.pgpKeyId = availableKeys[keyIndex]['keyid']
 
diff --git a/src/cutecoin/gui/addCommunityDialog.py b/src/cutecoin/gui/addCommunityDialog.py
index 9c37f280..49570e4d 100644
--- a/src/cutecoin/gui/addCommunityDialog.py
+++ b/src/cutecoin/gui/addCommunityDialog.py
@@ -33,8 +33,6 @@ class AddCommunityDialog(QDialog, Ui_AddCommunityDialog):
         '''
         server = self.serverEdit.text()
         port = self.portBox.value()
-        #TODO: Manage case where account is not member of the community
-        #An error must be displayed and the community must not be added
         try:
             community = self.account.communities.addCommunity(MainNode(server, port), self.account.keyFingerprint())
             self.account.wallets.addWallet(community.currency)
diff --git a/src/cutecoin/gui/mainWindow.py b/src/cutecoin/gui/mainWindow.py
index f6722673..91b8ef70 100644
--- a/src/cutecoin/gui/mainWindow.py
+++ b/src/cutecoin/gui/mainWindow.py
@@ -9,6 +9,8 @@ from cutecoin.gui.addAccountDialog import AddAccountDialog
 from cutecoin.gui.communityTabWidget import CommunityTabWidget
 from cutecoin.models.account.wallets.listModel import WalletsListModel
 from cutecoin.models.wallet.listModel import WalletListModel
+from cutecoin.models.transaction.sentListModel import SentListModel
+from cutecoin.models.transaction.receivedListModel import ReceivedListModel
 
 class MainWindow(QMainWindow, Ui_MainWindow):
     '''
@@ -35,6 +37,9 @@ class MainWindow(QMainWindow, Ui_MainWindow):
         self.core.addAccount(self.addAccountDialog.account)
         self.refreshMainWindow()
 
+    def save(self):
+        self.core.save()
+
     '''
     Refresh main window
     When the selected account changes, all the widgets
@@ -50,7 +55,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
             self.walletContent.setModel(WalletListModel(self.core.currentAccount.wallets.walletsList[0]))
             for community in self.core.currentAccount.communities.communitiesList:
                 self.communitiesTab.addTab(CommunityTabWidget(community), community.name())
-            #TODO: self.transactionsReceived.setModel()
-            #TODO: self.transactionsSent.setModel()
+            self.transactionsSent.setModel(SentListModel(self.core.currentAccount))
+            self.transactionsReceived.setModel(ReceivedListModel(self.core.currentAccount))
 
 
diff --git a/src/cutecoin/models/account/__init__.py b/src/cutecoin/models/account/__init__.py
index 64245b78..7ad5030a 100644
--- a/src/cutecoin/models/account/__init__.py
+++ b/src/cutecoin/models/account/__init__.py
@@ -7,27 +7,25 @@ Created on 1 févr. 2014
 import ucoinpy as ucoin
 import gnupg
 import logging
+import json
 from cutecoin.models.account.wallets import Wallets
+from cutecoin.models.account.communities import Communities
+from cutecoin.models.transaction import Transaction
 
 class Account(object):
     '''
-    classdocs
+    An account is specific to a pgpKey.
+    Each account has only one pgpKey, and a key can
+    be locally referenced by only one account.
     '''
-
-    def __init__(self, gpgKey, name, communities):
+    def __init__(self):
         '''
         Constructor
         '''
-        self.gpgKey = gpgKey
-        self.name = name
-        self.communities = communities
+        self.pgpKeyId = ""
+        self.name = ""
+        self.communities = Communities()
         self.wallets = Wallets()
-        for community in self.communities.communitiesList:
-            wallet = self.wallets.addWallet(community.currency)
-            wallet.refreshCoins(community, self.keyFingerprint())
-
-        self.receivedTransactions = []
-        self.sentTransactions = []
 
     def addWallet(name, currency):
         self.wallets.addWallet(name, currency)
@@ -35,18 +33,38 @@ class Account(object):
     def keyFingerprint(self):
         gpg = gnupg.GPG()
         availableKeys = gpg.list_keys()
-        logging.debug(self.gpgKey)
+        logging.debug(self.pgpKeyId)
         for k in availableKeys:
             logging.debug(k)
-            if k['keyid'] == self.gpgKey:
+            if k['keyid'] == self.pgpKeyId:
                 return k['fingerprint']
         return ""
 
     def transactionsReceived(self):
-        pass
+        received = []
+        for community in self.communities.communitiesList:
+            transactionsData = community.ucoinRequest(ucoin.hdc.transactions.Recipient(self.keyFingerprint()))
+            for trxData in transactionsData:
+                logging.debug(trxData)
+                #received.append(Transaction(trxData['sender'], trxData['number']))
+        return received
 
     def transactionsSent(self):
-        pass
+        sent = []
+        for community in self.communities.communitiesList:
+            transactionsData = community.ucoinRequest(ucoin.hdc.transactions.sender.Last(self.keyFingerprint(), 20))
+            for trxData in transactionsData:
+                logging.debug(trxData)
+                #sent.append(Transaction(trxData['sender'], trxData['number']))
+        return sent
+
+    def jsonify(self):
+        data = {'name' : self.name,
+                'pgpKeyId' : self.pgpKeyId,
+                'communities' : self.communities.jsonify(),
+                'wallets' : self.wallets.jsonify()}
+        return data
+
 
 
 
diff --git a/src/cutecoin/models/account/communities/__init__.py b/src/cutecoin/models/account/communities/__init__.py
index 47a5ed06..6d0fad42 100644
--- a/src/cutecoin/models/account/communities/__init__.py
+++ b/src/cutecoin/models/account/communities/__init__.py
@@ -4,13 +4,13 @@ Created on 5 févr. 2014
 @author: inso
 '''
 import ucoinpy as ucoin
-from cutecoin.models.community import Community
+from cutecoin.models.community import factory
 from cutecoin.core.exceptions import NotMemberOfCommunityError
 import logging
 
 class Communities(object):
     '''
-    classdocs
+    The list of the communities an account is member of.
     '''
     def __init__(self):
         '''
@@ -19,24 +19,40 @@ class Communities(object):
         self.communitiesList = []
 
     def getCommunity(self, amendmentId):
+        '''
+        Get a community thanks to its amendmentId
+        '''
         for com in self.communitiesList:
-            if com.currentAmendmentId() == amendmentId:
+            if com.amendmentId() == amendmentId:
                 return com
 
     def addCommunity(self, mainNode, keyFingerprint):
-        community = Community(mainNode)
-        self.members = community.ucoinRequest(lambda:ucoin.hdc.amendments.view.Members(community.currentAmendmentId()).get)
+        '''
+        Add a community with a mainNode and the pgpFingerprint of the account
+        Check if the pgpFingerprint is present in the community members list
+        If its not, the account isnt added and an error is raised.
+        '''
+        community = factory.createCommunity(mainNode)
+        members = community.ucoinRequest(ucoin.hdc.amendments.view.Members(community.amendmentId()))
 
         logging.debug("Account fingerprint : " + keyFingerprint)
-        for member in self.members:
+        for member in members:
             logging.debug(member)
             if member['value'] == keyFingerprint:
                 self.communitiesList.append(community)
                 return community
 
-        raise NotMemberOfCommunityError(keyFingerprint, community.currency + "-" + community.currentAmendmentId())
-        return None
+        raise NotMemberOfCommunityError(keyFingerprint, community.currency + "-" + community.amendmentId())
+
+
+    def jsonify(self):
+        '''
+        Return the list of communities in a key:value form.
+        '''
+        data = []
+        for community in self.communitiesList:
+            data.append(community.jsonify())
+        return data
+
+
 
-    #TODO: Jsonify this model
-    def saveJson(self):
-        pass
diff --git a/src/cutecoin/models/account/factory.py b/src/cutecoin/models/account/factory.py
new file mode 100644
index 00000000..07d40bca
--- /dev/null
+++ b/src/cutecoin/models/account/factory.py
@@ -0,0 +1,36 @@
+'''
+Created on 11 févr. 2014
+
+@author: inso
+'''
+from cutecoin.models.account import Account
+from cutecoin.models.account.wallets import Wallets
+from cutecoin.models.account.communities import Communities
+from cutecoin.models.wallet import factory as walletFactory
+from cutecoin.models.community import factory as communityFactory
+
+def createAccount(pgpKeyId, name, communities):
+    '''
+    Constructor
+    '''
+    account = Account()
+    account.pgpKeyId = pgpKeyId
+    account.name = name
+    account.communities = communities
+    account.wallets = Wallets()
+    for community in account.communities.communitiesList:
+        wallet = account.wallets.addWallet(community.currency)
+        wallet.refreshCoins(community, account.keyFingerprint())
+    return account
+
+def loadAccount(jsonData):
+    account = Account()
+    account.pgpKeyId = jsonData['pgpKeyId']
+    account.name = jsonData['name']
+    account.communities = Communities()
+    for communityData in jsonData['communities']:
+        account.communities.communitiesList.append(communityFactory.loadCommunity(communityData))
+    account.wallets = Wallets()
+    for walletData in jsonData['wallets']:
+        account.wallets.walletsList.append(walletFactory.loadWallet(jsonData))
+    return account
\ No newline at end of file
diff --git a/src/cutecoin/models/account/wallets/__init__.py b/src/cutecoin/models/account/wallets/__init__.py
index 8cc4fa2f..f3b15fe1 100644
--- a/src/cutecoin/models/account/wallets/__init__.py
+++ b/src/cutecoin/models/account/wallets/__init__.py
@@ -4,11 +4,11 @@ Created on 7 févr. 2014
 @author: inso
 '''
 
-from cutecoin.models.wallet import Wallet
+from cutecoin.models.wallet import factory
 
 class Wallets(object):
     '''
-    classdocs
+    The list of the wallets owned by an account.
     '''
     def __init__(self):
         '''
@@ -17,14 +17,32 @@ class Wallets(object):
         self.walletsList = []
 
     def addWallet(self, currency):
-        wallet = Wallet(currency)
+        '''
+        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 = factory.createWallet(currency)
         if wallet not in self.walletsList:
             self.walletsList.append(wallet)
         else:
             return self.walletsList.get(wallet)
 
     def getWallet(self, wallet):
+        '''
+        Look for a wallet in the wallets list.
+        '''
         for w in self.walletsLists:
             if w == wallet:
                 return w
         return None
+
+    def jsonify(self):
+        '''
+        Return the list of wallets in a key:value form.
+        '''
+        data = []
+        for wallet in self.walletsList:
+            data.append(wallet.jsonify())
+        return data
+
diff --git a/src/cutecoin/models/coin/__init__.py b/src/cutecoin/models/coin/__init__.py
index ddf7eff5..4ed54734 100644
--- a/src/cutecoin/models/coin/__init__.py
+++ b/src/cutecoin/models/coin/__init__.py
@@ -13,10 +13,7 @@ class Coin(object):
     '''
 
 
-    def __init__(self, ownerFingerprint, coin_id):
-        '''
-        Constructor
-        '''
+    def __init__(self, coin_id):
         # Regex to parse the coin id
         regex = "/^([A-Z\d]{40})-(\d+)-(\d)-(\d+)-((A|F|D)-\d+))$/"
         m = re.search(regex, coin_id)
@@ -25,7 +22,6 @@ class Coin(object):
         self.base = int(m.group(2))
         self.power = int(m.group(3))
         self.origin = m.group(4)
-        self.ownerFingerprint = ownerFingerprint
 
     def value(self):
         return math.pow(self.base, self.power)
@@ -35,4 +31,6 @@ class Coin(object):
             + str(self.number) + "-" \
             + str(self.base) + "-" \
             + str(self.power) + "-" \
-            + self.origin
\ No newline at end of file
+            + self.origin
+
+
diff --git a/src/cutecoin/models/community/__init__.py b/src/cutecoin/models/community/__init__.py
index 0a4d0784..c86cecbb 100644
--- a/src/cutecoin/models/community/__init__.py
+++ b/src/cutecoin/models/community/__init__.py
@@ -13,40 +13,43 @@ class Community(object):
     '''
     classdocs
     '''
-    def __init__(self, mainNode):
+    def __init__(self):
         '''
         Constructor
         '''
         self.knownNodes = []
-        self.knownNodes.append(mainNode)
-        self.ucoinInstance = ucoin
+        self.currency = ""
 
-        currentAmendment = self.ucoinRequest(lambda : self.ucoinInstance.hdc.amendments.Current().get)
-        self.currency = currentAmendment['currency']
-
-    def members(self):
+    def membersFingerprints(self):
         '''
         Listing members of a community
         '''
-        membersList = self.ucoinRequest(lambda : self.ucoinInstance.hdc.amendments.view.Members(self.currentAmendmentId()).get)
+        fingerprints = self.ucoinRequest(ucoin.hdc.amendments.view.Members(self.amendmentId()))
         members = []
-        for m in membersList:
-            members.append(m['value'])
+        for f in fingerprints:
+            members.append(f['value'])
         return members
 
-    def ucoinRequest(self, request):
+    def issuances(self):
+        '''
+        Listing issuances the accounted emitted
+        '''
+        #TODO:Return issuances
+        #issuances = self.ucoinRequest(ucoin.hdc.amendments.view.Members(amendmentId)
+        return []
+
+    def ucoinRequest(self, request, get_args={}):
         for node in self.knownNodes:
-            if node.available == True:
-                self.ucoinInstance.settings['server'] = node.server
-                self.ucoinInstance.settings['port'] = node.port
                 logging.debug("Trying to connect to : " + node.getText())
-                return (request())()
+                request.server = node.server
+                request.port = node.port
+                return request.get(**get_args)
 
         raise RuntimeError("Cannot connect to any node")
 
 
-    def currentAmendmentId(self):
-        currentAmendment = self.ucoinRequest(lambda:ucoin.hdc.amendments.Current().get)
+    def amendmentId(self):
+        currentAmendment = self.ucoinRequest(ucoin.hdc.amendments.Current())
         currentAmendmentHash = hashlib.sha1(currentAmendment['raw'].encode('utf-8')).hexdigest().upper()
         amendmentId = str(currentAmendment["number"]) + "-" + currentAmendmentHash
         logging.debug("Amendment : " + amendmentId)
@@ -55,7 +58,14 @@ class Community(object):
     def name(self):
         return self.currency
 
-    #TODO: Jsonify this model
-    def saveJson(self):
-        pass
+    def jsonifyNodesList(self):
+        data = []
+        for node in self.knownNodes:
+            data.append(node.jsonify())
+        return data
+
+    def jsonify(self):
+        data = {'nodes' : self.jsonifyNodesList(),
+                'currency' : self.currency}
+        return data
 
diff --git a/src/cutecoin/models/community/factory.py b/src/cutecoin/models/community/factory.py
new file mode 100644
index 00000000..eb9ffdc3
--- /dev/null
+++ b/src/cutecoin/models/community/factory.py
@@ -0,0 +1,24 @@
+'''
+Created on 11 févr. 2014
+
+@author: inso
+'''
+from cutecoin.models.community import Community
+from cutecoin.models.node import MainNode
+import ucoinpy as ucoin
+
+def createCommunity(mainNode):
+    community = Community()
+    community.knownNodes.append(mainNode)
+    currentAmendment = community.ucoinRequest(ucoin.hdc.amendments.Current())
+    community.currency = currentAmendment['currency']
+    return community
+
+
+def loadCommunity(jsonData):
+    community = Community()
+    for nodeData in jsonData['nodes']:
+        community.knownNodes.append(MainNode(jsonData['server'], jsonData['port']))
+    community.currency = jsonData['currency']
+    return community
+
diff --git a/src/cutecoin/models/community/issuancesListModel.py b/src/cutecoin/models/community/issuancesListModel.py
index b3a52607..bbbec80f 100644
--- a/src/cutecoin/models/community/issuancesListModel.py
+++ b/src/cutecoin/models/community/issuancesListModel.py
@@ -20,7 +20,7 @@ class IssuancesListModel(QAbstractListModel):
 
 
     def rowCount(self ,parent):
-        return len(self.issuanes)
+        return len(self.issuances)
 
     def data(self,index,role):
 
diff --git a/src/cutecoin/models/community/membersListModel.py b/src/cutecoin/models/community/membersListModel.py
index 06aeba9c..855df3b3 100644
--- a/src/cutecoin/models/community/membersListModel.py
+++ b/src/cutecoin/models/community/membersListModel.py
@@ -4,7 +4,7 @@ Created on 5 févr. 2014
 @author: inso
 '''
 
-import ucoinpy as ucoin
+from cutecoin.models.person import factory
 from PyQt5.QtCore import QAbstractListModel, Qt
 
 class MembersListModel(QAbstractListModel):
@@ -16,13 +16,10 @@ class MembersListModel(QAbstractListModel):
         Constructor
         '''
         super(MembersListModel, self).__init__(parent)
-        fingerprints = community.members()
+        fingerprints = community.membersFingerprints()
         self.members = []
-        '''for f in fingerprints:
-            keys = community.ucoinRequest(lambda : ucoin.pks.Lookup().get)
-            if len(keys) > 0:
-                self.members.append(keys[0]['key']['name'])
-        '''
+        for f in fingerprints:
+            self.members.append(factory.createPerson(f, community))
 
     def rowCount(self ,parent):
         return len(self.members)
@@ -31,7 +28,7 @@ class MembersListModel(QAbstractListModel):
 
         if role == Qt.DisplayRole:
             row=index.row()
-            value = self.members[row]
+            value = self.members[row].name
             return value
 
     def flags(self,index):
diff --git a/src/cutecoin/models/node/__init__.py b/src/cutecoin/models/node/__init__.py
index 14221ddb..be33fcb5 100644
--- a/src/cutecoin/models/node/__init__.py
+++ b/src/cutecoin/models/node/__init__.py
@@ -16,8 +16,6 @@ class Node(object):
         '''
         self.server = server
         self.port = port
-        self.available = True
-
 
     def __eq__(self, other):
         return ( self.server == other.server and self.port == other.port )
@@ -27,7 +25,6 @@ class Node(object):
 
 
 class MainNode(Node):
-
     def downstreamPeers(self):
         ucoin.settings['server'] = self.server
         ucoin.settings['port'] = self.port
@@ -38,7 +35,7 @@ class MainNode(Node):
             peers.append(node)
         return peers
 
-    #TODO: Jsonify this model
-    def saveJson(self):
-        pass
+    def jsonify(self):
+        return {'server' : self.server,
+                'port' : self.port}
 
diff --git a/src/cutecoin/models/person/__init__.py b/src/cutecoin/models/person/__init__.py
new file mode 100644
index 00000000..c33cc8c6
--- /dev/null
+++ b/src/cutecoin/models/person/__init__.py
@@ -0,0 +1,21 @@
+'''
+Created on 11 févr. 2014
+
+@author: inso
+'''
+
+import ucoinpy as ucoin
+
+class Person(object):
+    '''
+    classdocs
+    '''
+
+
+    def __init__(self):
+        '''
+        Constructor
+        '''
+        self.name = ""
+        self.fingerprint = ""
+        self.email = ""
\ No newline at end of file
diff --git a/src/cutecoin/models/person/factory.py b/src/cutecoin/models/person/factory.py
new file mode 100644
index 00000000..12fa25c8
--- /dev/null
+++ b/src/cutecoin/models/person/factory.py
@@ -0,0 +1,31 @@
+'''
+Created on 11 févr. 2014
+
+@author: inso
+'''
+from cutecoin.core.exceptions import PersonNotFoundError
+from cutecoin.models.person import Person
+import ucoinpy as ucoin
+
+def createPerson(pgpFingerprint, community):
+        #TODO: Raise an exception and display a popup if member isnt found
+        #Maybe generate a person whose name is the fingerprint, and email is 'unknown'
+        keys = community.ucoinRequest(ucoin.pks.Lookup(),
+                                          get_args={'search':"0x"+pgpFingerprint, 'op':'index'})['keys']
+        if len(keys) > 0:
+            person = Person()
+            json = keys[0]['key']
+            person.name = json['name']
+            person.fingerprint = json['fingerprint']
+            person.email = json['email']
+            return person
+        else:
+            raise PersonNotFoundError(pgpFingerprint, "pgpFingerprint", community)
+        return None
+
+def createPersonFromJson(jsonPerson):
+    person = Person()
+    person.name = jsonPerson['name']
+    person.pgpFingerprint = jsonPerson['fingerprint']
+    person.email = jsonPerson['email']
+    pass
\ No newline at end of file
diff --git a/src/cutecoin/models/transaction/__init__.py b/src/cutecoin/models/transaction/__init__.py
index 49d71cbb..26e4347f 100644
--- a/src/cutecoin/models/transaction/__init__.py
+++ b/src/cutecoin/models/transaction/__init__.py
@@ -4,18 +4,39 @@ Created on 1 févr. 2014
 @author: inso
 '''
 
+import ucoinpy as ucoin
+from cutecoin.models.coin import Coin
+from cutecoin.models.person import factory
+
 class Transaction(object):
     '''
     classdocs
     '''
+    def __init__(self, senderFingerprint, increment, community):
+        self.increment = increment
+        self.community = community
+        self.sender = factory.createPerson(senderFingerprint, community)
+        ucoinTransactionView = ucoin.hdc.transactions.View(self.transactionID())
+        trxData = self.community.ucoinRequest(ucoinTransactionView)
+        self.recipient = factory.createPerson(trxData['transaction']['recipient'], community)
 
+    def value(self):
+        value = 0
+        trxData = self.community.ucoinRequest(ucoin.hdc.transactions.View(self.sender.pgpFingerprint + "-" + self.increment))
+        for coin in trxData['transaction']['coins']:
+            value += Coin(coin[id]).value()
+        return value
 
-    def __init__(self, senderFingerprint, increment):
-        '''
-        Constructor
-        '''
-        self.senderFingerprint = senderFingerprint
-        self.increment = increment
+    def currency(self):
+        trxData = self.community.ucoinRequest(ucoin.hdc.transactions.View(self.sender.pgpFingerprint + "-" + self.increment))
+        currency = trxData['transaction']['currency']
+        return currency
 
     def transactionID(self):
         return self.senderFingerprint + "-" + self.increment
+
+    def getReceivedText(self):
+        return str(self.value) + " " + self.currency + " from " + self.sender.name
+
+    def getSentText(self):
+        return str(self.value) + " " + self.currency + " from " + self.recipient.name
diff --git a/src/cutecoin/models/transaction/receivedListModel.py b/src/cutecoin/models/transaction/receivedListModel.py
new file mode 100644
index 00000000..dcfd8fcb
--- /dev/null
+++ b/src/cutecoin/models/transaction/receivedListModel.py
@@ -0,0 +1,33 @@
+'''
+Created on 5 févr. 2014
+
+@author: inso
+'''
+
+import ucoinpy as ucoin
+import logging
+from PyQt5.QtCore import QAbstractListModel, Qt
+
+class ReceivedListModel(QAbstractListModel):
+    '''
+    A Qt abstract item model to display communities in a tree
+    '''
+    def __init__(self, account, parent=None):
+        '''
+        Constructor
+        '''
+        super(ReceivedListModel, self).__init__(parent)
+        self.transactions = account.transactionsReceived()
+
+    def rowCount(self ,parent):
+        return len(self.transactions)
+
+    def data(self,index,role):
+
+        if role == Qt.DisplayRole:
+            row=index.row()
+            value = self.transactions[row].getReceivedText()
+            return value
+
+    def flags(self,index):
+        return Qt.ItemIsSelectable | Qt.ItemIsEnabled
diff --git a/src/cutecoin/models/transaction/sentListModel.py b/src/cutecoin/models/transaction/sentListModel.py
new file mode 100644
index 00000000..10cedd1e
--- /dev/null
+++ b/src/cutecoin/models/transaction/sentListModel.py
@@ -0,0 +1,33 @@
+'''
+Created on 5 févr. 2014
+
+@author: inso
+'''
+
+import ucoinpy as ucoin
+import logging
+from PyQt5.QtCore import QAbstractListModel, Qt
+
+class SentListModel(QAbstractListModel):
+    '''
+    A Qt abstract item model to display communities in a tree
+    '''
+    def __init__(self, account, parent=None):
+        '''
+        Constructor
+        '''
+        super(SentListModel, self).__init__(parent)
+        self.transactions = account.transactionsSent()
+
+    def rowCount(self ,parent):
+        return len(self.transactions)
+
+    def data(self,index,role):
+
+        if role == Qt.DisplayRole:
+            row=index.row()
+            value = self.transactions[row].getSendText()
+            return value
+
+    def flags(self,index):
+        return Qt.ItemIsSelectable | Qt.ItemIsEnabled
diff --git a/src/cutecoin/models/wallet/__init__.py b/src/cutecoin/models/wallet/__init__.py
index 8f2eb592..6ba8e60e 100644
--- a/src/cutecoin/models/wallet/__init__.py
+++ b/src/cutecoin/models/wallet/__init__.py
@@ -14,12 +14,12 @@ class Wallet(object):
     '''
 
 
-    def __init__(self, currency):
+    def __init__(self):
         '''
         Constructor
         '''
         self.coins = []
-        self.currency = currency
+        self.currency = ""
 
 
     def __eq__(self, other):
@@ -32,7 +32,7 @@ class Wallet(object):
         return value
 
     def refreshCoins(self, community, pgpFingerprint):
-        dataList = community.ucoinRequest(lambda:ucoin.hdc.coins.List(pgpFingerprint).get)
+        dataList = community.ucoinRequest(lambda : ucoin.hdc.coins.List, ctor_args={'pgp_fingerprint':pgpFingerprint})
         for issaunces in dataList['coins']:
             issuer = issaunces['issuer']
             for coinsIds in issaunces['ids']:
@@ -42,3 +42,15 @@ class Wallet(object):
 
     def getText(self):
         return str(self.value()) + " " + self.currency
+
+    def jsonifyCoinsList(self):
+        data = []
+        for coin in self.coins:
+            data.append({'coin' : coin.getId()})
+        return data
+
+    def jsonify(self):
+        return {'coins': self.jsonifyCoinsList(),
+                'currency': self.currency}
+
+
diff --git a/src/cutecoin/models/wallet/factory.py b/src/cutecoin/models/wallet/factory.py
new file mode 100644
index 00000000..bb64558f
--- /dev/null
+++ b/src/cutecoin/models/wallet/factory.py
@@ -0,0 +1,21 @@
+'''
+Created on 11 févr. 2014
+
+@author: inso
+'''
+from cutecoin.models.wallet import Wallet
+from cutecoin.models.coin import Coin
+
+def createWallet(currency):
+    wallet = Wallet()
+    wallet.currency = currency
+    return wallet
+
+
+def loadWallet(jsonData):
+    wallet = Wallet()
+    for coinData in jsonData['coins']:
+        wallet.coins.append(Coin(coinData['coin']))
+    wallet.currency = jsonData['currency']
+    return wallet
+
-- 
GitLab