URI: 
       tmisc python3 updates: - use jsonrpclib-pelix - update the kivy gui - update plugins - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit c3388d967723965ecaff9663ddc9ada50a5dbee6
   DIR parent e562b0b5653568740f5933ad98e51044b863e4e4
  HTML Author: ThomasV <thomasv@electrum.org>
       Date:   Thu, 16 Feb 2017 10:54:24 +0100
       
       misc python3 updates:
        - use jsonrpclib-pelix
        - update the kivy gui
        - update plugins
       
       Diffstat:
         M electrum                            |       5 +++--
         M gui/kivy/Makefile                   |       2 +-
         M gui/kivy/__init__.py                |       2 +-
         M gui/kivy/main_window.py             |      41 +++++++++++++++----------------
         M gui/kivy/tools/buildozer.spec       |       2 +-
         M gui/kivy/uix/dialogs/choice_dialog… |       1 +
         M gui/kivy/uix/dialogs/installwizard… |      17 ++++++++---------
         M gui/kivy/uix/dialogs/settings.py    |       2 +-
         M gui/kivy/uix/dialogs/wallets.py     |       7 ++++---
         M gui/kivy/uix/qrcodewidget.py        |       2 +-
         M gui/kivy/uix/screens.py             |      14 +++++++-------
         M gui/kivy/uix/ui_screens/history.kv  |       4 ++--
         M gui/kivy/uix/ui_screens/receive.kv  |       4 ++--
         M gui/kivy/uix/ui_screens/send.kv     |       4 ++--
         M gui/qt/main_window.py               |       2 +-
         M gui/qt/transaction_dialog.py        |       2 +-
         M gui/stdio.py                        |      16 ++++++++--------
         M gui/text.py                         |      13 +++++++++----
         M lib/daemon.py                       |      61 +++++++++++++++----------------
         M lib/network.py                      |       2 +-
         M lib/util.py                         |       2 --
         M lib/wallet.py                       |       7 +++----
         M plugins/digitalbitbox/digitalbitbo… |       4 ++--
         M plugins/digitalbitbox/qt.py         |       2 +-
         M plugins/keepkey/qt.py               |       2 +-
         M plugins/ledger/auth2fa.py           |       6 +++---
         M plugins/ledger/ledger.py            |      20 ++++++++++----------
         M plugins/ledger/qt.py                |       2 +-
         M plugins/trezor/qt.py                |       2 +-
         M plugins/trustedcoin/qt.py           |       2 +-
         M plugins/trustedcoin/trustedcoin.py  |       5 ++---
         M setup.py                            |       2 +-
       
       32 files changed, 130 insertions(+), 129 deletions(-)
       ---
   DIR diff --git a/electrum b/electrum
       t@@ -68,7 +68,7 @@ def check_imports():
                import qrcode
                import pbkdf2
                import google.protobuf
       -        # import jsonrpclib
       +        import jsonrpclib
            except ImportError as e:
                sys.exit("Error: %s. Try 'sudo pip install <module-name>'"%e.message)
            # the following imports are for pyinstaller
       t@@ -76,7 +76,7 @@ def check_imports():
            from google.protobuf import message
            from google.protobuf import reflection
            from google.protobuf import descriptor_pb2
       -    # from jsonrpclib import SimpleJSONRPCServer
       +    from jsonrpclib import SimpleJSONRPCServer
            # check that we have the correct version of ecdsa
            try:
                from ecdsa.ecdsa import curve_secp256k1, generator_secp256k1
       t@@ -95,6 +95,7 @@ if is_bundle or is_local or is_android:
            imp.load_module('electrum', *imp.find_module('lib'))
            imp.load_module('electrum_gui', *imp.find_module('gui'))
        
       +
        from electrum import bitcoin, network
        from electrum import SimpleConfig, Network
        from electrum.wallet import Wallet, Imported_Wallet
   DIR diff --git a/gui/kivy/Makefile b/gui/kivy/Makefile
       t@@ -1,4 +1,4 @@
       -PYTHON = python
       +PYTHON = python3
        
        # needs kivy installed or in PYTHONPATH
        
   DIR diff --git a/gui/kivy/__init__.py b/gui/kivy/__init__.py
       t@@ -39,7 +39,6 @@ except ImportError:
        # minimum required version for kivy
        kivy.require('1.8.0')
        from kivy.logger import Logger
       -from main_window import ElectrumWindow
        
        
        
       t@@ -54,6 +53,7 @@ class ElectrumGui:
                self.plugins = plugins
        
            def main(self):
       +        from .main_window import ElectrumWindow
                self.config.open_last_wallet()
                w = ElectrumWindow(config=self.config,
                                   network=self.network,
   DIR diff --git a/gui/kivy/main_window.py b/gui/kivy/main_window.py
       t@@ -29,23 +29,23 @@ from kivy.factory import Factory
        from kivy.metrics import inch
        from kivy.lang import Builder
        
       -# lazy imports for factory so that widgets can be used in kv
       -Factory.register('InstallWizard',
       -                 module='electrum_gui.kivy.uix.dialogs.installwizard')
       -Factory.register('InfoBubble', module='electrum_gui.kivy.uix.dialogs')
       -Factory.register('OutputList', module='electrum_gui.kivy.uix.dialogs')
       -Factory.register('OutputItem', module='electrum_gui.kivy.uix.dialogs')
       +## lazy imports for factory so that widgets can be used in kv
       +#Factory.register('InstallWizard', module='electrum_gui.kivy.uix.dialogs.installwizard')
       +#Factory.register('InfoBubble', module='electrum_gui.kivy.uix.dialogs')
       +#Factory.register('OutputList', module='electrum_gui.kivy.uix.dialogs')
       +#Factory.register('OutputItem', module='electrum_gui.kivy.uix.dialogs')
        
       +from .uix.dialogs.installwizard import InstallWizard
       +from .uix.dialogs import InfoBubble
       +from .uix.dialogs import OutputList, OutputItem
        
        #from kivy.core.window import Window
        #Window.softinput_mode = 'below_target'
        
       -
        # delayed imports: for startup speed on android
        notification = app = ref = None
        util = False
        
       -
        # register widget cache for keeping memory down timeout to forever to cache
        # the data
        Cache.register('electrum_widgets', timeout=0)
       t@@ -239,12 +239,11 @@ class ElectrumWindow(App):
                self.is_exit = False
                self.wallet = None
        
       -        super(ElectrumWindow, self).__init__(**kwargs)
       +        App.__init__(self)#, **kwargs)
        
                title = _('Electrum App')
                self.electrum_config = config = kwargs.get('config', None)
                self.language = config.get('language', 'en')
       -
                self.network = network = kwargs.get('network', None)
                if self.network:
                    self.num_blocks = self.network.get_local_height()
       t@@ -361,7 +360,7 @@ class ElectrumWindow(App):
                popup.open()
        
            def qr_dialog(self, title, data, show_text=False):
       -        from uix.dialogs.qr_dialog import QRDialog
       +        from .uix.dialogs.qr_dialog import QRDialog
                popup = QRDialog(title, data, show_text)
                popup.open()
        
       t@@ -540,8 +539,8 @@ class ElectrumWindow(App):
                    return True
        
            def settings_dialog(self):
       +        from .uix.dialogs.settings import SettingsDialog
                if self._settings_dialog is None:
       -            from uix.dialogs.settings import SettingsDialog
                    self._settings_dialog = SettingsDialog(self)
                self._settings_dialog.update()
                self._settings_dialog.open()
       t@@ -550,7 +549,7 @@ class ElectrumWindow(App):
                if name == 'settings':
                    self.settings_dialog()
                elif name == 'wallets':
       -            from uix.dialogs.wallets import WalletDialog
       +            from .uix.dialogs.wallets import WalletDialog
                    d = WalletDialog()
                    d.open()
                else:
       t@@ -562,7 +561,7 @@ class ElectrumWindow(App):
                ''' Initialize The Ux part of electrum. This function performs the basic
                tasks of setting up the ui.
                '''
       -        from weakref import ref
       +        #from weakref import ref
        
                self.funds_error = False
                # setup UX
       t@@ -663,7 +662,7 @@ class ElectrumWindow(App):
            def format_amount_and_units(self, x):
                return format_satoshis_plain(x, self.decimal_point()) + ' ' + self.base_unit
        
       -    @profiler
       +    #@profiler
            def update_wallet(self, *dt):
                self._trigger_update_status()
                if self.wallet and (self.wallet.up_to_date or not self.network or not self.network.is_connected()):
       t@@ -779,7 +778,7 @@ class ElectrumWindow(App):
                info_bubble.show(pos, duration, width, modal=modal, exit=exit)
        
            def tx_dialog(self, tx):
       -        from uix.dialogs.tx_dialog import TxDialog
       +        from .uix.dialogs.tx_dialog import TxDialog
                d = TxDialog(self, tx)
                d.open()
        
       t@@ -818,7 +817,7 @@ class ElectrumWindow(App):
                    self.show_info(_('Cannot broadcast transaction') + ':\n' + _('Not connected'))
        
            def description_dialog(self, screen):
       -        from uix.dialogs.label_dialog import LabelDialog
       +        from .uix.dialogs.label_dialog import LabelDialog
                text = screen.message
                def callback(text):
                    screen.message = text
       t@@ -827,7 +826,7 @@ class ElectrumWindow(App):
        
            @profiler
            def amount_dialog(self, screen, show_max):
       -        from uix.dialogs.amount_dialog import AmountDialog
       +        from .uix.dialogs.amount_dialog import AmountDialog
                amount = screen.amount
                if amount:
                    amount, u = str(amount).split()
       t@@ -844,7 +843,7 @@ class ElectrumWindow(App):
                    f(*(args + (None,)))
        
            def delete_wallet(self):
       -        from uix.dialogs.question import Question
       +        from .uix.dialogs.question import Question
                basename = os.path.basename(self.wallet.storage.path)
                d = Question(_('Delete wallet?') + '\n' + basename, self._delete_wallet)
                d.open()
       t@@ -917,10 +916,10 @@ class ElectrumWindow(App):
                    self.show_error("PIN numbers do not match")
        
            def password_dialog(self, msg, f, args):
       +        from .uix.dialogs.password_dialog import PasswordDialog
                def callback(pw):
       -            Clock.schedule_once(lambda _: f(*(args + (pw,))), 0.1)
       +            Clock.schedule_once(lambda x: f(*(args + (pw,))), 0.1)
                if self._password_dialog is None:
       -            from uix.dialogs.password_dialog import PasswordDialog
                    self._password_dialog = PasswordDialog()
                self._password_dialog.init(msg, callback)
                self._password_dialog.open()
   DIR diff --git a/gui/kivy/tools/buildozer.spec b/gui/kivy/tools/buildozer.spec
       t@@ -31,7 +31,7 @@ version.filename = %(source.dir)s/contrib/versions.py
        #version = 1.9.8
        
        # (list) Application requirements
       -requirements = hostpython2, android, openssl, pycrypto, pil, plyer, kivy==master
       +requirements = python3crystax, android, openssl, pycrypto, pil, plyer, kivy==master
        
        # (str) Presplash of the application
        #presplash.filename = %(source.dir)s/gui/kivy/theming/splash.png
   DIR diff --git a/gui/kivy/uix/dialogs/choice_dialog.py b/gui/kivy/uix/dialogs/choice_dialog.py
       t@@ -46,6 +46,7 @@ class ChoiceDialog(Factory.Popup):
        
            def __init__(self, title, choices, key, callback):
                Factory.Popup.__init__(self)
       +        print(choices, type(choices))
                if type(choices) is list:
                    choices = dict(map(lambda x: (x,x), choices))
                layout = self.ids.choices
   DIR diff --git a/gui/kivy/uix/dialogs/installwizard.py b/gui/kivy/uix/dialogs/installwizard.py
       t@@ -14,15 +14,14 @@ from kivy.core.window import Window
        from kivy.clock import Clock
        from kivy.utils import platform
        
       -from electrum_gui.kivy.uix.dialogs import EventsDialog
       -from electrum_gui.kivy.i18n import _
        from electrum.base_wizard import BaseWizard
        
       -from password_dialog import PasswordDialog
        
       -# global Variables
       -app = App.get_running_app()
       +from . import EventsDialog
       +from ...i18n import _
       +from .password_dialog import PasswordDialog
        
       +# global Variables
        is_test = (platform == "linux")
        test_seed = "time taxi field recycle tiny license olive virus report rare steel portion achieve"
        test_xpub = "xpub661MyMwAqRbcEbvVtRRSjqxVnaWVUMewVzMiURAKyYratih4TtBpMypzzefmv8zUNebmNVzB3PojdC5sV2P9bDgMoo9B3SARw1MXUUfU1GL"
       t@@ -429,7 +428,7 @@ class WizardDialog(EventsDialog):
            crcontent = ObjectProperty(None)
        
            def __init__(self, wizard, **kwargs):
       -        super(WizardDialog, self).__init__(**kwargs)
       +        super(WizardDialog, self).__init__()
                self.wizard = wizard
                self.ids.back.disabled = not wizard.can_go_back()
                self.app = App.get_running_app()
       t@@ -624,9 +623,7 @@ class RestoreSeedDialog(WizardDialog):
        
            def get_text(self):
                ti = self.ids.text_input_seed
       -        text = unicode(ti.text).strip()
       -        text = ' '.join(text.split())
       -        return text
       +        return ' '.join(ti.text.strip().split())
        
            def update_text(self, c):
                c = c.lower()
       t@@ -752,6 +749,7 @@ class InstallWizard(BaseWizard, Widget):
                    # on  completion hide message
                    Clock.schedule_once(lambda dt: app.info_bubble.hide(now=True), -1)
        
       +        app = App.get_running_app()
                app.show_info_bubble(
                    text=msg, icon='atlas://gui/kivy/theming/light/important',
                    pos=Window.center, width='200sp', arrow_pos=None, modal=True)
       t@@ -793,6 +791,7 @@ class InstallWizard(BaseWizard, Widget):
            def show_xpub_dialog(self, **kwargs): ShowXpubDialog(self, **kwargs).open()
        
            def show_error(self, msg):
       +        app = App.get_running_app()
                Clock.schedule_once(lambda dt: app.show_error(msg))
        
            def password_dialog(self, message, callback):
   DIR diff --git a/gui/kivy/uix/dialogs/settings.py b/gui/kivy/uix/dialogs/settings.py
       t@@ -10,7 +10,7 @@ from electrum.plugins import run_hook
        from electrum import coinchooser
        from electrum.util import fee_levels
        
       -from choice_dialog import ChoiceDialog
       +from .choice_dialog import ChoiceDialog
        
        Builder.load_string('''
        #:import partial functools.partial
   DIR diff --git a/gui/kivy/uix/dialogs/wallets.py b/gui/kivy/uix/dialogs/wallets.py
       t@@ -1,13 +1,14 @@
       +import os
       +
        from kivy.app import App
        from kivy.factory import Factory
        from kivy.properties import ObjectProperty
        from kivy.lang import Builder
        
       -from electrum_gui.kivy.i18n import _
        from electrum.util import base_units
        
       -import os
       -from label_dialog import LabelDialog
       +from ...i18n import _
       +from .label_dialog import LabelDialog
        
        Builder.load_string('''
        #:import os os
   DIR diff --git a/gui/kivy/uix/qrcodewidget.py b/gui/kivy/uix/qrcodewidget.py
       t@@ -104,7 +104,7 @@ class QRCodeWidget(FloatLayout):
                    for c in range(k):
                        bext([0, 0, 0] if matrix[k-1-r][c] else [cr, cg, cb])
                # then blit the buffer
       -        buff = ''.join(map(chr, buff))
       +        buff = bytes(buff)
                # update texture
                self._upd_texture(buff)
        
   DIR diff --git a/gui/kivy/uix/screens.py b/gui/kivy/uix/screens.py
       t@@ -22,7 +22,7 @@ from electrum import bitcoin
        from electrum.util import timestamp_to_datetime
        from electrum.paymentrequest import PR_UNPAID, PR_PAID, PR_UNKNOWN, PR_EXPIRED
        
       -from context_menu import ContextMenu
       +from .context_menu import ContextMenu
        
        
        from electrum_gui.kivy.i18n import _
       t@@ -235,7 +235,7 @@ class SendScreen(CScreen):
                    self.payment_request = None
        
            def do_paste(self):
       -        contents = unicode(self.app._clipboard.paste())
       +        contents = self.app._clipboard.paste()
                if not contents:
                    self.app.show_info(_("Clipboard is empty"))
                    return
       t@@ -261,7 +261,7 @@ class SendScreen(CScreen):
                        self.app.show_error(_('Invalid amount') + ':\n' + self.screen.amount)
                        return
                    outputs = [(bitcoin.TYPE_ADDRESS, address, amount)]
       -        message = unicode(self.screen.message)
       +        message = self.screen.message
                amount = sum(map(lambda x:x[2], outputs))
                if self.app.electrum_config.get('use_rbf'):
                    from dialogs.question import Question
       t@@ -344,7 +344,7 @@ class ReceiveScreen(CScreen):
                req = self.app.wallet.get_payment_request(addr, self.app.electrum_config)
                self.screen.status = ''
                if req:
       -            self.screen.message = unicode(req.get('memo', ''))
       +            self.screen.message = req.get('memo', '')
                    amount = req.get('amount')
                    self.screen.amount = self.app.format_amount_and_units(amount) if amount else ''
                    status = req.get('status', PR_UNKNOWN)
       t@@ -376,9 +376,9 @@ class ReceiveScreen(CScreen):
                self.app.show_info(_('Request copied to clipboard'))
        
            def save_request(self):
       -        addr = str(self.screen.address)
       -        amount = str(self.screen.amount)
       -        message = unicode(self.screen.message)
       +        addr = self.screen.address
       +        amount = self.screen.amount
       +        message = self.screen.message
                amount = self.app.get_amount(amount) if amount else 0
                req = self.app.wallet.make_payment_request(addr, amount, message, None)
                self.app.wallet.add_payment_request(req, self.app.electrum_config)
   DIR diff --git a/gui/kivy/uix/ui_screens/history.kv b/gui/kivy/uix/ui_screens/history.kv
       t@@ -1,8 +1,8 @@
        #:import _ electrum_gui.kivy.i18n._
        #:import Factory kivy.factory.Factory
        #:set font_light 'gui/kivy/data/fonts/Roboto-Condensed.ttf'
       -#:set btc_symbol unichr(171)
       -#:set mbtc_symbol unichr(187)
       +#:set btc_symbol chr(171)
       +#:set mbtc_symbol chr(187)
        
        
        
   DIR diff --git a/gui/kivy/uix/ui_screens/receive.kv b/gui/kivy/uix/ui_screens/receive.kv
       t@@ -1,7 +1,7 @@
        #:import _ electrum_gui.kivy.i18n._
        #:import Decimal decimal.Decimal
       -#:set btc_symbol unichr(171)
       -#:set mbtc_symbol unichr(187)
       +#:set btc_symbol chr(171)
       +#:set mbtc_symbol chr(187)
        #:set font_light 'gui/kivy/data/fonts/Roboto-Condensed.ttf'
        
        
   DIR diff --git a/gui/kivy/uix/ui_screens/send.kv b/gui/kivy/uix/ui_screens/send.kv
       t@@ -1,7 +1,7 @@
        #:import _ electrum_gui.kivy.i18n._
        #:import Decimal decimal.Decimal
       -#:set btc_symbol unichr(171)
       -#:set mbtc_symbol unichr(187)
       +#:set btc_symbol chr(171)
       +#:set mbtc_symbol chr(187)
        #:set font_light 'gui/kivy/data/fonts/Roboto-Condensed.ttf'
        
        
   DIR diff --git a/gui/qt/main_window.py b/gui/qt/main_window.py
       t@@ -38,7 +38,7 @@ from PyQt4.QtGui import *
        from PyQt4.QtCore import *
        import PyQt4.QtCore as QtCore
        
       -from lib.util import bh2u, bfh
       +from electrum.util import bh2u, bfh
        from . import icons_rc
        
        from electrum import keystore
   DIR diff --git a/gui/qt/transaction_dialog.py b/gui/qt/transaction_dialog.py
       t@@ -42,7 +42,7 @@ from electrum.bitcoin import base_encode
        from electrum.i18n import _
        from electrum.plugins import run_hook
        
       -from lib.util import bfh
       +from electrum.util import bfh
        from .util import *
        
        dialogs = []  # Otherwise python randomly garbage collects the dialogs...
   DIR diff --git a/gui/stdio.py b/gui/stdio.py
       t@@ -23,7 +23,7 @@ class ElectrumGui:
                self.network = daemon.network
                storage = WalletStorage(config.get_wallet_path())
                if not storage.file_exists:
       -            print "Wallet not found. try 'electrum create'"
       +            print("Wallet not found. try 'electrum create'")
                    exit()
                if storage.is_encrypted():
                    password = getpass.getpass('Password:', stream=None)
       t@@ -63,8 +63,8 @@ class ElectrumGui:
        
            def main_command(self):
                self.print_balance()
       -        c = raw_input("enter command: ")
       -        if   c == "h" : self.print_commands()
       +        c = input("enter command: ")
       +        if c == "h" : self.print_commands()
                elif c == "i" : self.print_history()
                elif c == "o" : self.enter_order()
                elif c == "p" : self.print_order()
       t@@ -144,10 +144,10 @@ class ElectrumGui:
                      + "\nfee: " + self.str_fee + ", desc: " + self.str_description)
        
            def enter_order(self):
       -        self.str_recipient = raw_input("Pay to: ")
       -        self.str_description = raw_input("Description : ")
       -        self.str_amount = raw_input("Amount: ")
       -        self.str_fee = raw_input("Fee: ")
       +        self.str_recipient = input("Pay to: ")
       +        self.str_description = input("Description : ")
       +        self.str_amount = input("Amount: ")
       +        self.str_fee = input("Fee: ")
        
            def send_order(self):
                self.do_send()
       t@@ -192,7 +192,7 @@ class ElectrumGui:
        
                c = ""
                while c != "y":
       -            c = raw_input("ok to send (y/n)?")
       +            c = input("ok to send (y/n)?")
                    if c == "n": return
        
                try:
   DIR diff --git a/gui/text.py b/gui/text.py
       t@@ -25,7 +25,7 @@ class ElectrumGui:
                self.network = daemon.network
                storage = WalletStorage(config.get_wallet_path())
                if not storage.file_exists:
       -            print "Wallet not found. try 'electrum create'"
       +            print("Wallet not found. try 'electrum create'")
                    exit()
                if storage.is_encrypted():
                    password = getpass.getpass('Password:', stream=None)
       t@@ -186,8 +186,13 @@ class ElectrumGui:
                    self.print_list( self.network.banner.split('\n'))
        
            def print_qr(self, data):
       -        import qrcode, StringIO
       -        s = StringIO.StringIO()
       +        import qrcode
       +        try:
       +            from StringIO import StringIO
       +        except ImportError:
       +            from io import StringIO
       +
       +        s = StringIO()
                self.qr = qrcode.QRCode()
                self.qr.add_data(data)
                self.qr.print_ascii(out=s, invert=False)
       t@@ -218,7 +223,7 @@ class ElectrumGui:
        
            def main_command(self):
                c = self.stdscr.getch()
       -        print c
       +        print(c)
                if   c == curses.KEY_RIGHT: self.tab = (self.tab + 1)%self.num_tabs
                elif c == curses.KEY_LEFT: self.tab = (self.tab - 1)%self.num_tabs
                elif c == curses.KEY_DOWN: self.pos +=1
   DIR diff --git a/lib/daemon.py b/lib/daemon.py
       t@@ -34,8 +34,8 @@ import sys
        import time
        
        # from jsonrpc import JSONRPCResponseManager
       -# import jsonrpclib
       -# from jsonrpclib.SimpleJSONRPCServer import SimpleJSONRPCServer, SimpleJSONRPCRequestHandler
       +import jsonrpclib
       +from jsonrpclib.SimpleJSONRPCServer import SimpleJSONRPCServer, SimpleJSONRPCRequestHandler
        
        from .version import ELECTRUM_VERSION
        from .network import Network
       t@@ -96,17 +96,17 @@ def get_server(config):
                time.sleep(1.0)
        
        
       -# class RequestHandler(SimpleJSONRPCRequestHandler):
       -#
       -#     def do_OPTIONS(self):
       -#         self.send_response(200)
       -#         self.end_headers()
       -#
       -#     def end_headers(self):
       -#         self.send_header("Access-Control-Allow-Headers",
       -#                          "Origin, X-Requested-With, Content-Type, Accept")
       -#         self.send_header("Access-Control-Allow-Origin", "*")
       -#         SimpleJSONRPCRequestHandler.end_headers(self)
       +class RequestHandler(SimpleJSONRPCRequestHandler):
       +
       +     def do_OPTIONS(self):
       +         self.send_response(200)
       +         self.end_headers()
       +
       +     def end_headers(self):
       +         self.send_header("Access-Control-Allow-Headers",
       +                          "Origin, X-Requested-With, Content-Type, Accept")
       +         self.send_header("Access-Control-Allow-Origin", "*")
       +         SimpleJSONRPCRequestHandler.end_headers(self)
        
        
        class Daemon(DaemonThread):
       t@@ -132,24 +132,23 @@ class Daemon(DaemonThread):
            def init_server(self, config, fd):
                host = config.get('rpchost', '127.0.0.1')
                port = config.get('rpcport', 0)
       -        # try:
       -        #     server = SimpleJSONRPCServer((host, port), logRequests=False, requestHandler=RequestHandler)
       -        # except Exception as e:
       -        #     self.print_error('Warning: cannot initialize RPC server on host', host, e)
       -        #     self.server = None
       -        #     os.close(fd)
       -        #     return
       -        # os.write(fd, bytes(repr((server.socket.getsockname(), time.time())), 'utf8'))
       -        # os.close(fd)
       -        # server.timeout = 0.1
       -        # for cmdname in known_commands:
       -        #     server.register_function(getattr(self.cmd_runner, cmdname), cmdname)
       -        # server.register_function(self.run_cmdline, 'run_cmdline')
       -        # server.register_function(self.ping, 'ping')
       -        # server.register_function(self.run_daemon, 'daemon')
       -        # server.register_function(self.run_gui, 'gui')
       -        # self.server = server
       -        self.server = None
       +        try:
       +            server = SimpleJSONRPCServer((host, port), logRequests=False, requestHandler=RequestHandler)
       +        except Exception as e:
       +            self.print_error('Warning: cannot initialize RPC server on host', host, e)
       +            self.server = None
       +            os.close(fd)
       +            return
       +        os.write(fd, bytes(repr((server.socket.getsockname(), time.time())), 'utf8'))
       +        os.close(fd)
       +        server.timeout = 0.1
       +        for cmdname in known_commands:
       +            server.register_function(getattr(self.cmd_runner, cmdname), cmdname)
       +        server.register_function(self.run_cmdline, 'run_cmdline')
       +        server.register_function(self.ping, 'ping')
       +        server.register_function(self.run_daemon, 'daemon')
       +        server.register_function(self.run_gui, 'gui')
       +        self.server = server
        
            def ping(self):
                return True
   DIR diff --git a/lib/network.py b/lib/network.py
       t@@ -122,7 +122,7 @@ def parse_servers(result):
                            pruning_level = v[1:]
                        if pruning_level == '': pruning_level = '0'
                try:
       -            is_recent = cmp(util.normalize_version(version), util.normalize_version(PROTOCOL_VERSION)) >= 0
       +            is_recent = util.normalize_version(version) >= util.normalize_version(PROTOCOL_VERSION)
                except Exception as e:
                    print_error(e)
                    is_recent = False
   DIR diff --git a/lib/util.py b/lib/util.py
       t@@ -1,5 +1,3 @@
       -#!/usr/bin/env python
       -#
        # Electrum - lightweight Bitcoin client
        # Copyright (C) 2011 Thomas Voegtlin
        #
   DIR diff --git a/lib/wallet.py b/lib/wallet.py
       t@@ -42,7 +42,7 @@ from functools import partial
        from collections import namedtuple, defaultdict
        
        from .i18n import _
       -from .util import NotEnoughFunds, PrintError, UserCancelled, profiler
       +from .util import NotEnoughFunds, PrintError, UserCancelled, profiler, format_satoshis
        
        from .bitcoin import *
        from .version import *
       t@@ -59,6 +59,7 @@ from .verifier import SPV
        from .mnemonic import Mnemonic
        
        from . import paymentrequest
       +from .paymentrequest import PR_PAID, PR_UNPAID, PR_UNKNOWN, PR_EXPIRED
        
        from .storage import WalletStorage
        
       t@@ -1183,12 +1184,11 @@ class Abstract_Wallet(PrintError):
                return False, None
        
            def get_payment_request(self, addr, config):
       -        import util
                r = self.receive_requests.get(addr)
                if not r:
                    return
                out = copy.copy(r)
       -        out['URI'] = 'bitcoin:' + addr + '?amount=' + util.format_satoshis(out.get('amount'))
       +        out['URI'] = 'bitcoin:' + addr + '?amount=' + format_satoshis(out.get('amount'))
                status, conf = self.get_request_status(addr)
                out['status'] = status
                if conf is not None:
       t@@ -1219,7 +1219,6 @@ class Abstract_Wallet(PrintError):
                return out
        
            def get_request_status(self, key):
       -        from paymentrequest import PR_PAID, PR_UNPAID, PR_UNKNOWN, PR_EXPIRED
                r = self.receive_requests.get(key)
                if r is None:
                    return PR_UNKNOWN
   DIR diff --git a/plugins/digitalbitbox/digitalbitbox.py b/plugins/digitalbitbox/digitalbitbox.py
       t@@ -157,7 +157,7 @@ class DigitalBitbox_Client():
                    self.isInitialized = True # Wallet exists. Electrum code later checks if the device matches the wallet
                elif not self.isInitialized:
                    reply = self.hid_send_encrypt('{"device":"info"}')
       -            if reply['device']['id'] <> "":
       +            if reply['device']['id'] != "":
                        self.recover_or_erase_dialog() # Already seeded
                    else:
                        self.seed_device_dialog() # Seed if not initialized
       t@@ -594,7 +594,7 @@ class DigitalBitboxPlugin(HW_PluginBase):
                handler = keystore.handler
                with devmgr.hid_lock:
                    client = devmgr.client_for_keystore(self, handler, keystore, force_pair)        
       -        if client <> None:
       +        if client is not None:
                    client.check_device_dialog()
                return client
        
   DIR diff --git a/plugins/digitalbitbox/qt.py b/plugins/digitalbitbox/qt.py
       t@@ -1,6 +1,6 @@
        from PyQt4.Qt import (QInputDialog, QLineEdit)
        from ..hw_wallet.qt import QtHandlerBase, QtPluginBase
       -from digitalbitbox import DigitalBitboxPlugin
       +from .digitalbitbox import DigitalBitboxPlugin
        
        
        class Plugin(DigitalBitboxPlugin, QtPluginBase):
   DIR diff --git a/plugins/keepkey/qt.py b/plugins/keepkey/qt.py
       t@@ -1,5 +1,5 @@
        from ..trezor.qt_generic import QtPlugin
       -from keepkey import KeepKeyPlugin
       +from .keepkey import KeepKeyPlugin
        
        
        class Plugin(KeepKeyPlugin, QtPlugin):
   DIR diff --git a/plugins/ledger/auth2fa.py b/plugins/ledger/auth2fa.py
       t@@ -225,7 +225,7 @@ class LedgerAuthDialog(QDialog):
                try:
                    mode = self.dongle.exchange( bytearray(apdu) )
                    return mode
       -        except BTChipException, e:
       +        except BTChipException as e:
                    debug_msg('Device getMode Failed')
                return 0x11
            
       t@@ -274,7 +274,7 @@ class LedgerWebSocket(QThread):
                        challenge = self.dongle.exchange( bytearray(apdu) )
                        ws.send( '{"type":"challenge","data":"%s" }' % str(challenge).encode('hex') )
                        self.data = data
       -            except BTChipException, e:
       +            except BTChipException as e:
                        debug_msg('Identify Failed')
                        
                if data['type'] == 'challenge':
       t@@ -287,7 +287,7 @@ class LedgerWebSocket(QThread):
                        ws.send( '{"type":"pairing","is_successful":"true"}' )
                        self.data['pairid'] = self.pairID
                        self.pairing_done.emit(self.data)
       -            except BTChipException, e:
       +            except BTChipException as e:
                        debug_msg('Pairing Failed')
                        ws.send( '{"type":"pairing","is_successful":"false"}' ) 
                        self.pairing_done.emit(None)
   DIR diff --git a/plugins/ledger/ledger.py b/plugins/ledger/ledger.py
       t@@ -90,7 +90,7 @@ class Ledger_Client():
                try:
                    client.getVerifyPinRemainingAttempts()
                    return True
       -        except BTChipException, e:
       +        except BTChipException as e:
                    if e.sw == 0x6d00:
                        return False
                    raise e
       t@@ -99,7 +99,7 @@ class Ledger_Client():
                try:
                    # Invalid SET OPERATION MODE to verify the PIN status
                    client.dongle.exchange(bytearray([0xe0, 0x26, 0x00, 0x00, 0x01, 0xAB]))
       -        except BTChipException, e:
       +        except BTChipException as e:
                    if (e.sw == 0x6982):
                        return False
                    if (e.sw == 0x6A80):
       t@@ -118,16 +118,16 @@ class Ledger_Client():
                        raise Exception("HW1 firmware version too old. Please update at https://www.ledgerwallet.com")
                    try:
                        self.dongleObject.getOperationMode()
       -            except BTChipException, e:
       +            except BTChipException as e:
                        if (e.sw == 0x6985):
                            self.dongleObject.dongle.close()
                            self.handler.get_setup( )
                            # Acquire the new client on the next run
                        else:
                            raise e
       -            if self.has_detached_pin_support(self.dongleObject) and not self.is_pin_validated(self.dongleObject) and (self.handler <> None):
       +            if self.has_detached_pin_support(self.dongleObject) and not self.is_pin_validated(self.dongleObject) and (self.handler is not None):
                        remaining_attempts = self.dongleObject.getVerifyPinRemainingAttempts()
       -                if remaining_attempts <> 1:
       +                if remaining_attempts != 1:
                            msg = "Enter your Ledger PIN - remaining attempts : " + str(remaining_attempts)
                        else:
                            msg = "Enter your Ledger PIN - WARNING : LAST ATTEMPT. If the PIN is not correct, the dongle will be wiped."
       t@@ -136,7 +136,7 @@ class Ledger_Client():
                            raise Exception('Aborted by user - please unplug the dongle and plug it again before retrying')
                        pin = pin.encode()
                        self.dongleObject.verifyPin(pin)
       -        except BTChipException, e:
       +        except BTChipException as e:
                    if (e.sw == 0x6faa):
                        raise Exception("Dongle is temporarily locked - please unplug it and replug it again")
                    if ((e.sw & 0xFFF0) == 0x63c0):
       t@@ -225,7 +225,7 @@ class Ledger_KeyStore(Hardware_KeyStore):
                            raise UserWarning(_('Cancelled by user'))
                        pin = str(pin).encode()
                    signature = self.get_client().signMessageSign(pin)
       -        except BTChipException, e:
       +        except BTChipException as e:
                    if e.sw == 0x6a80:
                        self.give_error("Unfortunately, this message cannot be signed by the Ledger wallet. Only alphanumerical messages shorter than 140 characters are supported. Please remove any extra characters (tab, carriage return) and retry.")
                    else:
       t@@ -233,7 +233,7 @@ class Ledger_KeyStore(Hardware_KeyStore):
                except UserWarning:
                    self.handler.show_error(_('Cancelled by user'))
                    return ''
       -        except Exception, e:
       +        except Exception as e:
                    self.give_error(e, True)
                finally:
                    self.handler.clear_dialog()
       t@@ -469,7 +469,7 @@ class LedgerPlugin(HW_PluginBase):
                self.handler = handler
        
                client = self.get_btchip_device(device)
       -        if client <> None:
       +        if client is not None:
                    client = Ledger_Client(client)
                return client
        
       t@@ -501,6 +501,6 @@ class LedgerPlugin(HW_PluginBase):
                # returns the client for a given keystore. can use xpub
                #if client:
                #    client.used()
       -        if client <> None:
       +        if client is not None:
                    client.checkDevice()                    
                return client
   DIR diff --git a/plugins/ledger/qt.py b/plugins/ledger/qt.py
       t@@ -9,7 +9,7 @@ from .ledger import LedgerPlugin
        from ..hw_wallet.qt import QtHandlerBase, QtPluginBase
        from electrum_gui.qt.util import *
        
       -from btchip.btchipPersoWizard import StartBTChipPersoDialog
       +#from btchip.btchipPersoWizard import StartBTChipPersoDialog
        
        class Plugin(LedgerPlugin, QtPluginBase):
            icon_unpaired = ":icons/ledger_unpaired.png"
   DIR diff --git a/plugins/trezor/qt.py b/plugins/trezor/qt.py
       t@@ -1,5 +1,5 @@
        from ..trezor.qt_generic import QtPlugin
       -from trezor import TrezorPlugin
       +from .trezor import TrezorPlugin
        
        
        class Plugin(TrezorPlugin, QtPlugin):
   DIR diff --git a/plugins/trustedcoin/qt.py b/plugins/trustedcoin/qt.py
       t@@ -37,7 +37,7 @@ from electrum_gui.qt.amountedit import AmountEdit
        from electrum_gui.qt.main_window import StatusBarButton
        from electrum.i18n import _
        from electrum.plugins import hook
       -from trustedcoin import TrustedCoinPlugin, server
       +from .trustedcoin import TrustedCoinPlugin, server
        
        
        class Plugin(TrustedCoinPlugin):
   DIR diff --git a/plugins/trustedcoin/trustedcoin.py b/plugins/trustedcoin/trustedcoin.py
       t@@ -90,11 +90,10 @@ class TrustedCoinCosignerClient(object):
                    kwargs['headers']['content-type'] = 'application/json'
                url = urljoin(self.base_url, relative_url)
                if self.debug:
       -            print '%s %s %s' % (method, url, data)
       +            print('%s %s %s' % (method, url, data))
                response = requests.request(method, url, **kwargs)
                if self.debug:
       -            print response.text
       -            print
       +            print(response.text)
                if response.status_code != 200:
                    message = str(response.text)
                    if response.headers.get('content-type') == 'application/json':
   DIR diff --git a/setup.py b/setup.py
       t@@ -43,7 +43,7 @@ setup(
                'qrcode',
                'protobuf',
                'dnspython',
       -        'jsonrpclib',
       +        'jsonrpclib-pelix',
                'PySocks>=1.6.6',
            ],
            packages=[