2013-04-28 04:47:19 -07:00
#!/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
2013-09-11 04:43:37 -07:00
from electrum . i18n import _
2013-04-28 04:47:19 -07:00
from electrum . util import print_error , print_msg
import os . path , json , ast , traceback
from PyQt4 . QtGui import *
from PyQt4 . QtCore import *
2013-09-11 23:41:27 -07:00
from electrum import DEFAULT_SERVERS , DEFAULT_PORTS
2013-04-28 04:47:19 -07:00
2013-09-24 01:06:03 -07:00
from util import *
2013-04-28 04:47:19 -07:00
protocol_names = [ ' TCP ' , ' HTTP ' , ' SSL ' , ' HTTPS ' ]
protocol_letters = ' thsg '
class NetworkDialog ( QDialog ) :
2013-09-10 09:27:32 -07:00
def __init__ ( self , network , config , parent ) :
2013-04-28 04:47:19 -07:00
QDialog . __init__ ( self , parent )
self . setModal ( 1 )
self . setWindowTitle ( _ ( ' Server ' ) )
self . setMinimumSize ( 375 , 20 )
2013-09-10 09:27:32 -07:00
self . network = network
self . interface = interface = network . interface
2013-04-28 04:47:19 -07:00
self . config = config
self . protocol = None
if parent :
2013-09-10 10:59:58 -07:00
n = len ( network . interfaces )
if n :
status = _ ( " Connected to %d servers " ) % n + " , %d " % ( network . blockchain . height ) + _ ( " blocks " )
2013-04-28 04:47:19 -07:00
else :
status = _ ( " Not connected " )
2013-09-10 10:59:58 -07:00
2013-10-04 10:27:50 -07:00
if network . is_connected ( ) :
2013-09-11 07:32:18 -07:00
status + = " \n " + _ ( " Main server: " ) + " %s " % ( interface . host )
2013-09-10 10:59:58 -07:00
else :
2013-09-11 07:32:18 -07:00
status + = " \n " + _ ( " Disconnected from main server " )
2013-09-10 10:59:58 -07:00
2013-04-28 04:47:19 -07:00
else :
import random
status = _ ( " Please choose a server. " ) + " \n " + _ ( " Select ' Cancel ' if you are offline. " )
2013-10-04 10:27:50 -07:00
server = network . default_server
2013-09-11 23:41:27 -07:00
self . servers = network . get_servers ( )
2013-04-28 04:47:19 -07:00
2013-09-10 09:27:32 -07:00
2013-04-28 04:47:19 -07:00
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 )
2013-09-11 09:45:34 -07:00
hbox . addWidget ( HelpButton ( _ ( " As of version 1.9, Electrum connects to several servers in order to download block headers and find out the longest blockchain. However, your wallet addresses are sent to a single server, in order to receive your transaction history. " ) ) )
2013-04-28 04:47:19 -07:00
vbox . addLayout ( hbox )
# grid layout
grid = QGridLayout ( )
grid . setSpacing ( 8 )
vbox . addLayout ( grid )
2013-10-05 01:14:33 -07:00
# auto cycle
self . autocycle_cb = QCheckBox ( _ ( ' Auto-connect ' ) )
self . autocycle_cb . setChecked ( self . config . get ( ' auto_cycle ' , True ) )
grid . addWidget ( self . autocycle_cb , 0 , 1 , 1 , 2 )
if not self . config . is_modifiable ( ' auto_cycle ' ) : self . autocycle_cb . setEnabled ( False )
2013-04-28 04:47:19 -07:00
# 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 )
2013-10-05 01:14:33 -07:00
grid . addWidget ( QLabel ( _ ( ' Server ' ) + ' : ' ) , 1 , 0 )
grid . addWidget ( self . server_protocol , 1 , 1 )
grid . addWidget ( self . server_host , 1 , 2 )
grid . addWidget ( self . server_port , 1 , 3 )
2013-04-28 04:47:19 -07:00
self . server_protocol . connect ( self . server_protocol , SIGNAL ( ' currentIndexChanged(int) ' ) , self . change_protocol )
2013-10-04 10:08:09 -07:00
label = _ ( ' Active Servers ' ) if network . irc_servers else _ ( ' Default Servers ' )
2013-04-28 04:47:19 -07:00
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 ) )
2013-10-05 01:14:33 -07:00
grid . addWidget ( self . servers_list_widget , 2 , 1 , 1 , 3 )
2013-04-28 04:47:19 -07:00
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 )
2013-10-05 01:14:33 -07:00
def enable_set_server ( ) :
enabled = not self . autocycle_cb . isChecked ( )
self . server_host . setEnabled ( enabled )
self . server_port . setEnabled ( enabled )
self . servers_list_widget . setEnabled ( enabled )
self . autocycle_cb . clicked . connect ( enable_set_server )
enable_set_server ( )
2013-04-28 04:47:19 -07:00
# 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 )
2013-10-04 10:27:50 -07:00
proxy_config = network . proxy if network . proxy else { " mode " : " none " , " host " : " localhost " , " port " : " 8080 " }
2013-04-28 04:47:19 -07:00
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 " ) )
2013-10-05 01:14:33 -07:00
grid . addWidget ( QLabel ( _ ( ' Proxy ' ) + ' : ' ) , 3 , 0 )
grid . addWidget ( self . proxy_mode , 3 , 1 )
grid . addWidget ( self . proxy_host , 3 , 2 )
grid . addWidget ( self . proxy_port , 3 , 3 )
2013-04-28 04:47:19 -07:00
# 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 ( ) )
2013-10-04 23:51:53 -07:00
pp = self . servers . get ( host , DEFAULT_PORTS )
2013-04-28 04:47:19 -07:00
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 ) :
2013-08-01 02:31:33 -07:00
if not self . exec_ ( ) :
return
2013-04-28 04:47:19 -07:00
2013-10-05 02:16:09 -07:00
host = str ( self . server_host . text ( ) )
port = str ( self . server_port . text ( ) )
protocol = protocol_letters [ self . server_protocol . currentIndex ( ) ]
2013-04-28 04:47:19 -07:00
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
2013-10-05 01:01:33 -07:00
auto_connect = self . autocycle_cb . isChecked ( )
2013-09-12 05:58:42 -07:00
2013-10-05 02:16:09 -07:00
self . network . set_parameters ( host , port , protocol , proxy , auto_connect )
2013-04-28 04:47:19 -07:00
return True