URI: 
       tWork in progress on Label syncing - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit e8b97e5326df188422529ccd12a0ff64bea1c3d0
   DIR parent 18bcf5b206664e3a9d2392ba54c349423eb9456b
  HTML Author: Maran <maran.hidskes@gmail.com>
       Date:   Sun, 10 Mar 2013 17:04:00 +0100
       
       Work in progress on Label syncing
       
       Diffstat:
         M gui/gui_classic.py                  |      12 +++++++++++-
         M icons.qrc                           |       1 +
         A plugins/labels.py                   |     118 +++++++++++++++++++++++++++++++
       
       3 files changed, 130 insertions(+), 1 deletion(-)
       ---
   DIR diff --git a/gui/gui_classic.py b/gui/gui_classic.py
       t@@ -273,6 +273,8 @@ class ElectrumWindow(QMainWindow):
                self.config = config
                self.init_plugins()
        
       +        self.create_status_bar()
       +
                self.wallet.interface.register_callback('updated', lambda: self.emit(QtCore.SIGNAL('update_wallet')))
                self.wallet.interface.register_callback('banner', lambda: self.emit(QtCore.SIGNAL('banner_signal')))
                self.wallet.interface.register_callback('disconnected', lambda: self.emit(QtCore.SIGNAL('update_status')))
       t@@ -295,7 +297,6 @@ class ElectrumWindow(QMainWindow):
                tabs.setMinimumSize(600, 400)
                tabs.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
                self.setCentralWidget(tabs)
       -        self.create_status_bar()
        
                g = self.config.get("winpos-qt",[100, 100, 840, 400])
                self.setGeometry(g[0], g[1], g[2], g[3])
       t@@ -520,6 +521,9 @@ class ElectrumWindow(QMainWindow):
                text = unicode( item.text(2) )
                if text: 
                    self.wallet.labels[tx_hash] = text
       +            # Label changed
       +            self.run_hook('label_changed',(self, str(tx_hash), text))
       +
                    item.setForeground(2, QBrush(QColor('black')))
                else:
                    if s: self.wallet.labels.pop(tx_hash)
       t@@ -562,6 +566,7 @@ class ElectrumWindow(QMainWindow):
                            if old_addr != addr:
                                self.wallet.labels[addr] = text
                                changed = True
       +                        self.run_hook('label_changed',(self, addr, text))
                        else:
                            print_error("Error: This is one of your aliases")
                            label = self.wallet.labels.get(addr,'')
       t@@ -1195,6 +1200,8 @@ class ElectrumWindow(QMainWindow):
                self.status_button = StatusBarButton( QIcon(":icons/status_disconnected.png"), _("Network"), lambda: self.network_dialog(self.wallet, self) ) 
                sb.addPermanentWidget( self.status_button )
        
       +        self.run_hook('create_status_bar', (sb,))
       +
                self.setStatusBar(sb)
                
            def go_lite(self):
       t@@ -1866,6 +1873,7 @@ class ElectrumWindow(QMainWindow):
                vbox = QVBoxLayout()
        
                tabs = QTabWidget(self)
       +        self.settings_tab = tabs
                vbox.addWidget(tabs)
        
                tab1 = QWidget()
       t@@ -2040,6 +2048,8 @@ class ElectrumWindow(QMainWindow):
                            traceback.print_exc(file=sys.stdout)
                    grid_plugins.setRowStretch(i+1,1)
        
       +        self.run_hook('create_settings_tab', (self,tabs,))
       +
                vbox.addLayout(ok_cancel_buttons(d))
                d.setLayout(vbox) 
        
   DIR diff --git a/icons.qrc b/icons.qrc
       t@@ -16,5 +16,6 @@
            <file>icons/switchgui.png</file>
            <file>icons/unconfirmed.png</file>
            <file>icons/network.png</file>
       +    <file>icons/cloud.png</file>
          </qresource>
        </RCC>
   DIR diff --git a/plugins/labels.py b/plugins/labels.py
       t@@ -0,0 +1,118 @@
       +from electrum.util import print_error
       +import httplib, urllib
       +import hashlib
       +import json
       +from urlparse import urlparse, parse_qs
       +try:
       +    import PyQt4
       +except:
       +    sys.exit("Error: Could not import PyQt4 on Linux systems, you may try 'sudo apt-get install python-qt4'")
       +
       +from PyQt4.QtGui import *
       +from PyQt4.QtCore import *
       +import PyQt4.QtCore as QtCore
       +import PyQt4.QtGui as QtGui
       +
       +target_host = 'localhost:3000'
       +auth_token = 'jEnsNBb5fAR5rYSBNYnR'
       +
       +def init(gui):
       +    cloud_wallet = CloudWallet(gui.wallet)
       +    gui.set_hook('create_settings_tab', add_settings_tab)
       +    gui.set_hook('label_changed', label_changed)
       +    cloud_wallet.full_pull()
       +
       +def wallet_id(wallet):
       +    return hashlib.sha256(str(wallet.get_master_public_key())).digest().encode('hex')
       +
       +
       +def label_changed(gui,item,label):
       +    print "Label changed! Item: %s Label: %s label" % ( item, label)
       +    global auth_token, target_host
       +    hashed = hashlib.sha256(item).digest().encode('hex')
       +    bundle = {"label": {"external_id": hashed, "text": label}}
       +    params = json.dumps(bundle)
       +    connection = httplib.HTTPConnection(target_host)
       +    connection.request("POST", ("/api/wallets/%s/labels.json?auth_token=%s" % (wallet_id(gui.wallet), auth_token)), params, {'Content-Type': 'application/json'})
       +
       +    response = connection.getresponse()
       +    if response.reason == httplib.responses[httplib.NOT_FOUND]:
       +        return
       +    response = json.loads(response.read())
       +
       +def add_settings_tab(gui, tabs):
       +      cloud_tab = QWidget()
       +      layout = QGridLayout(cloud_tab)
       +      layout.addWidget(QLabel("API Key: "),0,0)
       +      layout.addWidget(QLineEdit(), 0,2)
       +
       +      layout.addWidget(QLabel("Label sync options: "),1,0)
       +      layout.addWidget(QPushButton("Force upload"), 1,1)
       +      layout.addWidget(QPushButton("Force download"), 1,2)
       +
       +      tabs.addTab(cloud_tab, "Label cloud")
       +
       +def show():
       +    print 'showing'
       +
       +def get_info():
       +    return 'Label sync', "Syncs your labels with LabElectrum. Labels are not encrypted, transactions and addresses are however."
       +
       +def is_enabled():
       +    return True
       +
       +def toggle(gui):
       +    return is_enabled()
       +
       +
       +class CloudWallet():
       +    def __init__(self, wallet):
       +        self.mpk = hashlib.sha256(str(wallet.get_master_public_key())).digest().encode('hex')
       +        self.labels = wallet.labels
       +        self.transactions = wallet.transactions
       +
       +        addresses = [] 
       +        for k, account in wallet.accounts.items():
       +            for address in account[0]:
       +                addresses.append(address)
       +
       +        self.addresses = addresses
       +
       +
       +    def full_pull(self):
       +        global target_host, auth_token
       +        connection = httplib.HTTPConnection(target_host)
       +        connection.request("GET", ("/api/wallets/%s/labels.json?auth_token=%s" % (self.mpk, auth_token)),"", {'Content-Type': 'application/json'})
       +        response = connection.getresponse()
       +        if response.reason == httplib.responses[httplib.NOT_FOUND]:
       +            return
       +
       +        response = json.loads(response.read())
       +        for label in response:
       +            for key in self.addresses:
       +                target_hashed = hashlib.sha256(key).digest().encode('hex')
       +                if label["external_id"] == target_hashed:
       +                   if not self.labels.get(key):
       +                       self.labels[key] = label["text"] 
       +            for key, value in self.transactions.iteritems():
       +                target_hashed = hashlib.sha256(key).digest().encode('hex')
       +                if label["external_id"] == target_hashed:
       +                   if not self.labels.get(key):
       +                       self.labels[key] = label["text"] 
       +
       +    def full_push(self):
       +        global target_host, auth_token
       +
       +        bundle = {"labels": {}}
       +        for key, value in self.labels.iteritems():
       +            hashed = hashlib.sha256(key).digest().encode('hex')
       +            bundle["labels"][hashed] = value
       +
       +        params = json.dumps(bundle)
       +        connection = httplib.HTTPConnection(target_host)
       +        connection.request("POST", ("/api/wallets/%s/labels/batch.json?auth_token=%s" % (self.mpk, auth_token)), params, {'Content-Type': 'application/json'})
       +
       +        response = connection.getresponse()
       +        if response.reason == httplib.responses[httplib.NOT_FOUND]:
       +            return
       +        response = json.loads(response.read())