electrum

Electrum Bitcoin wallet
git clone https://git.parazyd.org/electrum
Log | Files | Refs | Submodules

commit 86fd728a47f8b5fcb2deed66c8c769851d9979ba
parent 7d1075d85d355c30b224caede4416a8173ca97e4
Author: ecdsa <ecdsa@github>
Date:   Sun, 28 Apr 2013 13:47:19 +0200

move network dialog in a new class; simplify interface.get_servers

Diffstat:
Melectrum | 2+-
Mgui/gui_android.py | 16++++++++--------
Mgui/gui_classic.py | 220++++++-------------------------------------------------------------------------
Mgui/gui_gtk.py | 8++++----
Agui/network_dialog.py | 231+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Agui/qt_util.py | 30++++++++++++++++++++++++++++++
Mlib/interface.py | 113++++++++++++++++++++++++++++++++++++-------------------------------------------
Msetup.py | 2++
8 files changed, 344 insertions(+), 278 deletions(-)

diff --git a/electrum b/electrum @@ -219,7 +219,7 @@ if __name__ == '__main__': w_host, w_port, w_protocol = server.split(':') host = raw_input("server (default:%s):"%w_host) port = raw_input("port (default:%s):"%w_port) - protocol = raw_input("protocol [t=tcp;h=http;n=native] (default:%s):"%w_protocol) + protocol = raw_input("protocol [t=tcp;h=http] (default:%s):"%w_protocol) fee = raw_input("fee (default:%s):"%( str(Decimal(wallet.fee)/100000000)) ) gap = raw_input("gap limit (default 5):") if host: w_host = host diff --git a/gui/gui_android.py b/gui/gui_android.py @@ -688,9 +688,9 @@ def contacts_loop(): return out -def server_dialog(plist): +def server_dialog(servers): droid.dialogCreateAlert("Public servers") - droid.dialogSetItems( plist.keys() ) + droid.dialogSetItems( servers.keys() ) droid.dialogSetPositiveButtonText('Private server') droid.dialogShow() response = droid.dialogGetResponse().result @@ -702,7 +702,7 @@ def server_dialog(plist): i = response.get('item') if i is not None: - response = plist.keys()[i] + response = servers.keys()[i] return response @@ -774,7 +774,7 @@ def settings_loop(): if event == 'OK': continue if not event: continue - plist, servers_list = interface.get_servers_list() + servers = interface.get_servers() name = event.get("name") if not name: continue @@ -783,9 +783,9 @@ def settings_loop(): host, port, protocol = interface.server.split(':') if pos == "0": #server - host = server_dialog(plist) + host = server_dialog(servers) if host: - p = plist[host] + p = servers[host] port = p['t'] srv = host + ':' + port + ':t' wallet.config.set_key("server", srv, True) @@ -796,8 +796,8 @@ def settings_loop(): set_listview() elif pos == "1": #protocol - if host in plist: - srv = protocol_dialog(host, protocol, plist[host]) + if host in servers: + srv = protocol_dialog(host, protocol, servers[host]) if srv: wallet.config.set_key("server", srv, True) try: diff --git a/gui/gui_classic.py b/gui/gui_classic.py @@ -20,7 +20,7 @@ import sys, time, datetime, re, threading from i18n import _, set_language from electrum.util import print_error, print_msg import os.path, json, ast, traceback -from qrcodewidget import QRCodeWidget + try: import PyQt4 @@ -30,8 +30,7 @@ except: from PyQt4.QtGui import * from PyQt4.QtCore import * import PyQt4.QtCore as QtCore -import PyQt4.QtGui as QtGui -from electrum.interface import DEFAULT_SERVERS, DEFAULT_PORTS + from electrum.bitcoin import MIN_RELAY_TX_FEE try: @@ -48,6 +47,8 @@ import bmp, pyqrnative import exchange_rate from amountedit import AmountEdit +from network_dialog import NetworkDialog +from qrcodewidget import QRCodeWidget from decimal import Decimal @@ -67,9 +68,11 @@ else: from electrum import ELECTRUM_VERSION import re -class UpdateLabel(QtGui.QLabel): +from qt_util import * + +class UpdateLabel(QLabel): def __init__(self, config, parent=None): - QtGui.QLabel.__init__(self, parent) + QLabel.__init__(self, parent) self.new_version = False try: @@ -225,32 +228,7 @@ def waiting_dialog(f): w.destroy() -def ok_cancel_buttons(dialog, ok_label=_("OK") ): - hbox = QHBoxLayout() - hbox.addStretch(1) - b = QPushButton(_("Cancel")) - hbox.addWidget(b) - b.clicked.connect(dialog.reject) - b = QPushButton(ok_label) - hbox.addWidget(b) - b.clicked.connect(dialog.accept) - b.setDefault(True) - return hbox - -def text_dialog(parent, title, label, ok_label): - dialog = QDialog(parent) - dialog.setMinimumWidth(500) - dialog.setWindowTitle(title) - dialog.setModal(1) - l = QVBoxLayout() - dialog.setLayout(l) - l.addWidget(QLabel(label)) - txt = QTextEdit() - l.addWidget(txt) - l.addLayout(ok_cancel_buttons(dialog, ok_label)) - if dialog.exec_(): - return unicode(txt.toPlainText()) @@ -1234,7 +1212,7 @@ class ElectrumWindow(QMainWindow): sb.addPermanentWidget( StatusBarButton( QIcon(":icons/preferences.png"), _("Preferences"), self.settings_dialog ) ) if self.wallet.seed: sb.addPermanentWidget( StatusBarButton( QIcon(":icons/seed.png"), _("Seed"), self.show_seed_dialog ) ) - self.status_button = StatusBarButton( QIcon(":icons/status_disconnected.png"), _("Network"), lambda: self.network_dialog(self.wallet, self) ) + self.status_button = StatusBarButton( QIcon(":icons/status_disconnected.png"), _("Network"), self.run_network_dialog ) sb.addPermanentWidget( self.status_button ) self.run_hook('create_status_bar', (sb,)) @@ -2008,7 +1986,7 @@ class ElectrumWindow(QMainWindow): grid_plugins = QGridLayout() grid_plugins.setColumnStretch(0,1) - w = QtGui.QWidget() + w = QWidget() w.setLayout(grid_plugins) tab5.setWidget(w) tab5.setMaximumSize(tab3.size()) # optional @@ -2112,177 +2090,8 @@ class ElectrumWindow(QMainWindow): self.receive_tab_set_mode(expert_cb.isChecked()) - - @staticmethod - def network_dialog(wallet, parent=None): - interface = wallet.interface - if parent: - if interface.is_connected: - status = _("Connected to")+" %s\n%d "%(interface.host, wallet.verifier.height)+_("blocks") - else: - status = _("Not connected") - server = interface.server - else: - import random - status = _("Please choose a server.") + "\n" + _("Select 'Cancel' if you are offline.") - server = interface.server - - plist, servers_list = interface.get_servers_list() - - d = QDialog(parent) - d.setModal(1) - d.setWindowTitle(_('Server')) - d.setMinimumSize(375, 20) - - vbox = QVBoxLayout() - vbox.setSpacing(30) - - hbox = QHBoxLayout() - l = QLabel() - l.setPixmap(QPixmap(":icons/network.png")) - hbox.addStretch(10) - hbox.addWidget(l) - hbox.addWidget(QLabel(status)) - hbox.addStretch(50) - vbox.addLayout(hbox) - - - # grid layout - grid = QGridLayout() - grid.setSpacing(8) - vbox.addLayout(grid) - - # server - server_protocol = QComboBox() - server_host = QLineEdit() - server_host.setFixedWidth(200) - server_port = QLineEdit() - server_port.setFixedWidth(60) - - protocol_names = ['TCP', 'HTTP', 'SSL', 'HTTPS'] - protocol_letters = 'thsg' - server_protocol.addItems(protocol_names) - - grid.addWidget(QLabel(_('Server') + ':'), 0, 0) - grid.addWidget(server_protocol, 0, 1) - grid.addWidget(server_host, 0, 2) - grid.addWidget(server_port, 0, 3) - - def change_protocol(p): - protocol = protocol_letters[p] - host = unicode(server_host.text()) - pp = plist.get(host,DEFAULT_PORTS) - if protocol not in pp.keys(): - protocol = pp.keys()[0] - port = pp[protocol] - server_host.setText( host ) - server_port.setText( port ) - - server_protocol.connect(server_protocol, SIGNAL('currentIndexChanged(int)'), change_protocol) - - label = _('Active Servers') if wallet.interface.servers else _('Default Servers') - servers_list_widget = QTreeWidget(parent) - servers_list_widget.setHeaderLabels( [ label, _('Limit') ] ) - servers_list_widget.setMaximumHeight(150) - servers_list_widget.setColumnWidth(0, 240) - for _host in servers_list.keys(): - pruning_level = servers_list[_host].get('pruning','') - servers_list_widget.addTopLevelItem(QTreeWidgetItem( [ _host, pruning_level ] )) - servers_list_widget.setColumnHidden(1, not parent.expert_mode if parent else True) - - def change_server(host, protocol=None): - pp = plist.get(host,DEFAULT_PORTS) - if protocol: - port = pp.get(protocol) - if not port: protocol = None - - if not protocol: - if 's' in pp.keys(): - protocol = 's' - port = pp.get(protocol) - else: - protocol = pp.keys()[0] - port = pp.get(protocol) - - server_host.setText( host ) - server_port.setText( port ) - server_protocol.setCurrentIndex(protocol_letters.index(protocol)) - - if not plist: return - for p in protocol_letters: - i = protocol_letters.index(p) - j = server_protocol.model().index(i,0) - if p not in pp.keys() and interface.is_connected: - server_protocol.model().setData(j, QtCore.QVariant(0), QtCore.Qt.UserRole-1) - else: - server_protocol.model().setData(j, QtCore.QVariant(33), QtCore.Qt.UserRole-1) - - if server: - host, port, protocol = server.split(':') - change_server(host,protocol) - - servers_list_widget.connect(servers_list_widget, SIGNAL('currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)'), - lambda x,y: change_server(unicode(x.text(0)))) - grid.addWidget(servers_list_widget, 1, 1, 1, 3) - - if not wallet.config.is_modifiable('server'): - for w in [server_host, server_port, server_protocol, servers_list_widget]: w.setEnabled(False) - - # auto cycle - autocycle_cb = QCheckBox(_('Try random servers if disconnected')) - autocycle_cb.setChecked(wallet.config.get('auto_cycle', True)) - grid.addWidget(autocycle_cb, 3, 1, 3, 2) - if not wallet.config.is_modifiable('auto_cycle'): autocycle_cb.setEnabled(False) - - # proxy setting - proxy_mode = QComboBox() - proxy_host = QLineEdit() - proxy_host.setFixedWidth(200) - proxy_port = QLineEdit() - proxy_port.setFixedWidth(60) - proxy_mode.addItems(['NONE', 'SOCKS4', 'SOCKS5', 'HTTP']) - - def check_for_disable(index = False): - if proxy_mode.currentText() != 'NONE': - proxy_host.setEnabled(True) - proxy_port.setEnabled(True) - else: - proxy_host.setEnabled(False) - proxy_port.setEnabled(False) - - check_for_disable() - proxy_mode.connect(proxy_mode, SIGNAL('currentIndexChanged(int)'), check_for_disable) - - if not wallet.config.is_modifiable('proxy'): - for w in [proxy_host, proxy_port, proxy_mode]: w.setEnabled(False) - - proxy_config = interface.proxy if interface.proxy else { "mode":"none", "host":"localhost", "port":"8080"} - proxy_mode.setCurrentIndex(proxy_mode.findText(str(proxy_config.get("mode").upper()))) - proxy_host.setText(proxy_config.get("host")) - proxy_port.setText(proxy_config.get("port")) - - grid.addWidget(QLabel(_('Proxy') + ':'), 2, 0) - grid.addWidget(proxy_mode, 2, 1) - grid.addWidget(proxy_host, 2, 2) - grid.addWidget(proxy_port, 2, 3) - - # buttons - vbox.addLayout(ok_cancel_buttons(d)) - d.setLayout(vbox) - - if not d.exec_(): return - - server = unicode( server_host.text() ) + ':' + unicode( server_port.text() ) + ':' + (protocol_letters[server_protocol.currentIndex()]) - if proxy_mode.currentText() != 'NONE': - proxy = { u'mode':unicode(proxy_mode.currentText()).lower(), u'host':unicode(proxy_host.text()), u'port':unicode(proxy_port.text()) } - else: - proxy = None - - wallet.config.set_key("proxy", proxy, True) - wallet.config.set_key("server", server, True) - interface.set_server(server, proxy) - wallet.config.set_key('auto_cycle', autocycle_cb.isChecked(), True) - return True + def run_network_dialog(self): + NetworkDialog(self.wallet.interface, self.config, self).do_exec() def closeEvent(self, event): g = self.geometry() @@ -2292,6 +2101,9 @@ class ElectrumWindow(QMainWindow): event.accept() + + + class ElectrumGui: def __init__(self, wallet, config, app=None): @@ -2379,7 +2191,7 @@ class ElectrumGui: def network_dialog(self): - return ElectrumWindow.network_dialog( self.wallet, parent=None ) + return NetworkDialog(self.wallet.interface, self.config, None).do_exec() def show_seed(self): diff --git a/gui/gui_gtk.py b/gui/gui_gtk.py @@ -282,7 +282,7 @@ def run_network_dialog( wallet, parent ): status = "Please choose a server.\nSelect cancel if you are offline." server = interface.server - plist, servers_list = interface.get_servers_list() + servers = interface.get_servers() dialog = gtk.MessageDialog( parent, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_QUESTION, gtk.BUTTONS_OK_CANCEL, status) @@ -331,7 +331,7 @@ def run_network_dialog( wallet, parent ): def set_protocol(protocol): host = current_line()[0] - pp = plist[host] + pp = servers[host] if protocol not in pp.keys(): protocol = pp.keys()[0] set_button(protocol) @@ -342,7 +342,7 @@ def run_network_dialog( wallet, parent ): radio2.connect("toggled", lambda x,y:set_protocol('h'), "radio button 1") server_list = gtk.ListStore(str) - for host in plist.keys(): + for host in servers.keys(): server_list.append([host]) treeview = gtk.TreeView(model=server_list) @@ -372,7 +372,7 @@ def run_network_dialog( wallet, parent ): path, view_column = treeview.get_cursor() host = server_list.get_value( server_list.get_iter(path), 0) - pp = plist[host] + pp = servers[host] if 't' in pp.keys(): protocol = 't' else: diff --git a/gui/network_dialog.py b/gui/network_dialog.py @@ -0,0 +1,231 @@ +#!/usr/bin/env python +# +# Electrum - lightweight Bitcoin client +# Copyright (C) 2012 thomasv@gitorious +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +import sys, time, datetime, re, threading +from i18n import _ +from electrum.util import print_error, print_msg +import os.path, json, ast, traceback + +from PyQt4.QtGui import * +from PyQt4.QtCore import * +from electrum.interface import DEFAULT_SERVERS, DEFAULT_PORTS + +from qt_util import * + +protocol_names = ['TCP', 'HTTP', 'SSL', 'HTTPS'] +protocol_letters = 'thsg' + +class NetworkDialog(QDialog): + def __init__(self, interface, config, parent): + + QDialog.__init__(self,parent) + self.setModal(1) + self.setWindowTitle(_('Server')) + self.setMinimumSize(375, 20) + + self.interface = interface + self.config = config + self.protocol = None + + if parent: + if interface.is_connected: + status = _("Connected to")+" %s"%(interface.host) #, wallet.verifier.height)+_("blocks") + else: + status = _("Not connected") + server = interface.server + else: + import random + status = _("Please choose a server.") + "\n" + _("Select 'Cancel' if you are offline.") + server = interface.server + + self.servers = interface.get_servers() + + vbox = QVBoxLayout() + vbox.setSpacing(30) + + hbox = QHBoxLayout() + l = QLabel() + l.setPixmap(QPixmap(":icons/network.png")) + hbox.addStretch(10) + hbox.addWidget(l) + hbox.addWidget(QLabel(status)) + hbox.addStretch(50) + vbox.addLayout(hbox) + + # grid layout + grid = QGridLayout() + grid.setSpacing(8) + vbox.addLayout(grid) + + # server + self.server_protocol = QComboBox() + self.server_host = QLineEdit() + self.server_host.setFixedWidth(200) + self.server_port = QLineEdit() + self.server_port.setFixedWidth(60) + + self.server_protocol.addItems(protocol_names) + + grid.addWidget(QLabel(_('Server') + ':'), 0, 0) + grid.addWidget(self.server_protocol, 0, 1) + grid.addWidget(self.server_host, 0, 2) + grid.addWidget(self.server_port, 0, 3) + + self.server_protocol.connect(self.server_protocol, SIGNAL('currentIndexChanged(int)'), self.change_protocol) + + label = _('Active Servers') if interface.servers else _('Default Servers') + self.servers_list_widget = QTreeWidget(parent) + self.servers_list_widget.setHeaderLabels( [ label, _('Limit') ] ) + self.servers_list_widget.setMaximumHeight(150) + self.servers_list_widget.setColumnWidth(0, 240) + + if server: + host, port, protocol = server.split(':') + self.set_protocol(protocol) + self.change_server(host, protocol) + else: + self.set_protocol('s') + + self.servers_list_widget.connect(self.servers_list_widget, + SIGNAL('currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)'), + lambda x,y: self.server_changed(x)) + grid.addWidget(self.servers_list_widget, 1, 1, 1, 3) + + if not config.is_modifiable('server'): + for w in [self.server_host, self.server_port, self.server_protocol, self.servers_list_widget]: w.setEnabled(False) + + # auto cycle + self.autocycle_cb = QCheckBox(_('Try random servers if disconnected')) + self.autocycle_cb.setChecked(self.config.get('auto_cycle', True)) + grid.addWidget(self.autocycle_cb, 3, 1, 3, 2) + if not self.config.is_modifiable('auto_cycle'): self.autocycle_cb.setEnabled(False) + + # proxy setting + self.proxy_mode = QComboBox() + self.proxy_host = QLineEdit() + self.proxy_host.setFixedWidth(200) + self.proxy_port = QLineEdit() + self.proxy_port.setFixedWidth(60) + self.proxy_mode.addItems(['NONE', 'SOCKS4', 'SOCKS5', 'HTTP']) + + def check_for_disable(index = False): + if self.proxy_mode.currentText() != 'NONE': + self.proxy_host.setEnabled(True) + self.proxy_port.setEnabled(True) + else: + self.proxy_host.setEnabled(False) + self.proxy_port.setEnabled(False) + + check_for_disable() + self.proxy_mode.connect(self.proxy_mode, SIGNAL('currentIndexChanged(int)'), check_for_disable) + + if not self.config.is_modifiable('proxy'): + for w in [self.proxy_host, self.proxy_port, self.proxy_mode]: w.setEnabled(False) + + proxy_config = interface.proxy if interface.proxy else { "mode":"none", "host":"localhost", "port":"8080"} + self.proxy_mode.setCurrentIndex(self.proxy_mode.findText(str(proxy_config.get("mode").upper()))) + self.proxy_host.setText(proxy_config.get("host")) + self.proxy_port.setText(proxy_config.get("port")) + + grid.addWidget(QLabel(_('Proxy') + ':'), 2, 0) + grid.addWidget(self.proxy_mode, 2, 1) + grid.addWidget(self.proxy_host, 2, 2) + grid.addWidget(self.proxy_port, 2, 3) + + # buttons + vbox.addLayout(ok_cancel_buttons(self)) + self.setLayout(vbox) + + + def init_servers_list(self): + self.servers_list_widget.clear() + for _host, d in self.servers.items(): + if d.get(self.protocol): + pruning_level = d.get('pruning','') + self.servers_list_widget.addTopLevelItem(QTreeWidgetItem( [ _host, pruning_level ] )) + + + def set_protocol(self, protocol): + if protocol != self.protocol: + self.protocol = protocol + self.init_servers_list() + + def change_protocol(self, index): + p = protocol_letters[index] + host = unicode(self.server_host.text()) + pp = self.servers.get(host) + if p not in pp.keys(): + p = pp.keys()[0] + port = pp[p] + self.server_host.setText( host ) + self.server_port.setText( port ) + self.set_protocol(p) + + def server_changed(self, x): + if x: + self.change_server(str(x.text(0)), self.protocol) + + def change_server(self, host, protocol): + + pp = self.servers.get(host, DEFAULT_PORTS) + if protocol: + port = pp.get(protocol) + if not port: protocol = None + + if not protocol: + if 's' in pp.keys(): + protocol = 's' + port = pp.get(protocol) + else: + protocol = pp.keys()[0] + port = pp.get(protocol) + + self.server_host.setText( host ) + self.server_port.setText( port ) + self.server_protocol.setCurrentIndex(protocol_letters.index(protocol)) + + if not self.servers: return + for p in protocol_letters: + i = protocol_letters.index(p) + j = self.server_protocol.model().index(i,0) + #if p not in pp.keys(): # and self.interface.is_connected: + # self.server_protocol.model().setData(j, QVariant(0), Qt.UserRole-1) + #else: + # self.server_protocol.model().setData(j, QVariant(33), Qt.UserRole-1) + + + def do_exec(self): + + if not self.exec_(): return + + server = ':'.join([str( self.server_host.text() ), + str( self.server_port.text() ), + (protocol_letters[self.server_protocol.currentIndex()]) ]) + + if self.proxy_mode.currentText() != 'NONE': + proxy = { 'mode':str(self.proxy_mode.currentText()).lower(), + 'host':str(self.proxy_host.text()), + 'port':str(self.proxy_port.text()) } + else: + proxy = None + + self.config.set_key("proxy", proxy, True) + self.config.set_key("server", server, True) + self.interface.set_server(server, proxy) + self.config.set_key('auto_cycle', self.autocycle_cb.isChecked(), True) + return True diff --git a/gui/qt_util.py b/gui/qt_util.py @@ -0,0 +1,30 @@ +from i18n import _ +from PyQt4.QtGui import * +from PyQt4.QtCore import * + +def ok_cancel_buttons(dialog, ok_label=_("OK") ): + hbox = QHBoxLayout() + hbox.addStretch(1) + b = QPushButton(_("Cancel")) + hbox.addWidget(b) + b.clicked.connect(dialog.reject) + b = QPushButton(ok_label) + hbox.addWidget(b) + b.clicked.connect(dialog.accept) + b.setDefault(True) + return hbox + +def text_dialog(parent, title, label, ok_label): + dialog = QDialog(parent) + dialog.setMinimumWidth(500) + dialog.setWindowTitle(title) + dialog.setModal(1) + l = QVBoxLayout() + dialog.setLayout(l) + l.addWidget(QLabel(label)) + txt = QTextEdit() + l.addWidget(txt) + l.addLayout(ok_cancel_buttons(dialog, ok_label)) + if dialog.exec_(): + return unicode(txt.toPlainText()) + diff --git a/lib/interface.py b/lib/interface.py @@ -26,34 +26,39 @@ from util import print_error, print_msg DEFAULT_TIMEOUT = 5 DEFAULT_PORTS = {'t':'50001', 's':'50002', 'h':'8081', 'g':'8082'} -DEFAULT_SERVERS = [ - 'electrum.bitcoin.cz:50002:s', - 'electrum.novit.ro:50002:s', - 'electrum.be:50002:s', - 'electrum.bysh.me:50002:s', - 'electrum.pdmc.net:50002:s', - 'electrum.no-ip.org:50002:s', - 'ecdsa.org:50002:s', - 'electra.datemas.de:50002:s', - 'electrum.datemas.de:50002:s', - 'electrum.mooo.com:50002:s', - 'btcback.com:50002:s', - 'electrum.bitcoins.sk:50002:s', - 'btc.stytt.com:50002:s', - 'electrum.stepkrav.pw:50002:s', - 'btc.it-zone.org:110:s' - ] - -# add only port 80 servers here -DEFAULT_HTTP_SERVERS = [ - 'electrum.no-ip.org:80:h' -] + +DEFAULT_SERVERS = { + 'electrum.thecoinwillprevail.com': {'h': '8081', 's': '50002', 't': '50001'}, + 'the9ull.homelinux.org': {'h': '8082', 't': '50001'}, + 'electra.datemas.de': {'h': '8081', 's': '50002', 't': '50001', 'g': '808'}, + 'electrum.datemas.de': {'h': '8081', 's': '50002', 't': '50001', 'g': '8082'}, + 'ecdsa.org': {'h': '8081', 's': '50002', 't': '50001', 'g': '8082'}, + 'electrum.mooo.com': {'h': '8081', 't': '50001'}, + 'btcback.com': {'h': '8081', 's': '50002', 't': '50001', 'g': '8082'}, + 'electrum.bitcoins.sk': {'h': '8081', 's': '50002', 't': '50001', 'g': '8'}, + 'electrum.no-ip.org': {'h': '80', 's': '50002', 't': '50001', 'g': '443'}, + 'electrum.drollette.com': {'h': '8081', 's': '50002', 't': '50001', 'g': '8082'}, + 'btc.it-zone.org': {'h': '80', 's': '110', 't': '50001', 'g': '443'}, + 'electrum.yacoin.com': {'h': '8081', 's': '50002', 't': '50001', 'g': '8082'}, + 'electrum.be': {'h': '8081', 's': '50002', 't': '50001', 'g': '8082'} +} + + + +def filter_protocol(servers, p): + l = [] + for k, protocols in servers.items(): + if p in protocols: + l.append( ':'.join([k, protocols[p], p]) ) + return l + + proxy_modes = ['socks4', 'socks5', 'http'] def pick_random_server(): - return random.choice( DEFAULT_SERVERS ) + return random.choice( filter_protocol(DEFAULT_SERVERS,'s') ) @@ -119,9 +124,10 @@ class Interface(threading.Thread): elif method == 'server.peers.subscribe': servers = {} for item in result: - s = [] + host = item[1] - ports = [] + out = {} + version = None pruning_level = '-' if len(item) > 2: @@ -129,7 +135,7 @@ class Interface(threading.Thread): if re.match("[stgh]\d*", v): protocol, port = v[0], v[1:] if port == '': port = DEFAULT_PORTS[protocol] - ports.append((protocol, port)) + out[protocol] = port elif re.match("v(.?)+", v): version = v[1:] elif re.match("p\d*", v): @@ -139,8 +145,11 @@ class Interface(threading.Thread): is_recent = float(version)>=float(PROTOCOL_VERSION) except: is_recent = False - if ports and is_recent: - servers[host] = {'ports':ports, 'pruning':pruning_level} + + if out and is_recent: + out['pruning'] = pruning_level + servers[host] = out + self.servers = servers self.trigger_callback('peers') @@ -309,26 +318,28 @@ class Interface(threading.Thread): s.setproxy(proxy_modes.index(self.proxy["mode"]) + 1, self.proxy["host"], int(self.proxy["port"]) ) if self.use_ssl: - s = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_SSLv23) + s = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_SSLv23, do_handshake_on_connect=True) s.settimeout(2) s.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) try: s.connect(( self.host.encode('ascii'), int(self.port))) - s.settimeout(60) - self.s = s - self.is_connected = True except: + traceback.print_exc(file=sys.stdout) self.is_connected = False self.s = None + return + s.settimeout(60) + self.s = s + self.is_connected = True def run_tcp(self): try: + #if self.use_ssl: self.s.do_handshake() out = '' while self.is_connected: - try: timeout = False msg = self.s.recv(1024) @@ -395,7 +406,7 @@ class Interface(threading.Thread): def __init__(self, config=None, loop=False): - self.server = random.choice(DEFAULT_SERVERS[:]) + self.server = random.choice(filter_protocol(DEFAULT_SERVERS, 's')) self.proxy = None if config is None: @@ -431,16 +442,10 @@ class Interface(threading.Thread): if not self.is_connected and self.config.get('auto_cycle'): print_msg("Using random server...") - servers_tcp = DEFAULT_SERVERS[:] - servers_http = DEFAULT_HTTP_SERVERS[:] - while servers_tcp or servers_http: - if servers_tcp: - server = random.choice( servers_tcp ) - servers_tcp.remove(server) - else: - # try HTTP if we can't get a TCP connection - server = random.choice( servers_http ) - servers_http.remove(server) + servers = filter_protocol(DEFAULT_SERVERS, 's') + while servers: + server = random.choice( servers ) + servers.remove(server) print server self.config.set_key('server', server, False) self.init_with_server(self.config) @@ -559,25 +564,11 @@ class Interface(threading.Thread): self.s.close() - def get_servers_list(self): - plist = {} + def get_servers(self): if not self.servers: - servers_list = {} - for x in DEFAULT_SERVERS: - h,port,protocol = x.split(':') - servers_list[h] = {'ports':[(protocol,port)]} + return DEFAULT_SERVERS else: - servers_list = self.servers - - for _host, v in servers_list.items(): - pp = v['ports'] - z = {} - for item2 in pp: - _protocol, _port = item2 - z[_protocol] = _port - plist[_host] = z - - return plist, servers_list + return self.servers def is_empty(self, channel): diff --git a/setup.py b/setup.py @@ -73,6 +73,8 @@ setup(name = "Electrum", 'electrum_gui.qrcodewidget', 'electrum_gui.history_widget', 'electrum_gui.receiving_widget', + 'electrum_gui.qt_util', + 'electrum_gui.network_dialog', 'electrum_gui.bmp', 'electrum_gui.i18n', 'electrum_gui.plugins',