commit 9e57ae630ba96e6d2c40288d2633aeca8d20764d
parent b2cfaddff25b93189e8fb26f04fe9667958fe2d6
Author: SomberNight <somber.night@protonmail.com>
Date: Thu, 16 Apr 2020 21:12:23 +0200
network/gui: unify host/port input fields to single server str
This allows optionally specifying the protocol for the main server.
fixes #6095
fixes #5278
Diffstat:
5 files changed, 42 insertions(+), 68 deletions(-)
diff --git a/electrum/gui/kivy/main_window.py b/electrum/gui/kivy/main_window.py
@@ -145,13 +145,11 @@ class ElectrumWindow(App):
servers = self.network.get_servers()
ChoiceDialog(_('Choose a server'), sorted(servers), popup.ids.host.text, cb2).open()
- def maybe_switch_to_server(self, *, host: str, port: str):
+ def maybe_switch_to_server(self, server_str: str):
from electrum.interface import ServerAddr
net_params = self.network.get_parameters()
try:
- server = ServerAddr(host=host,
- port=port,
- protocol=net_params.server.protocol)
+ server = ServerAddr.from_str_with_inference(server_str)
except Exception as e:
self.show_error(_("Invalid server details: {}").format(repr(e)))
return
diff --git a/electrum/gui/kivy/uix/ui_screens/server.kv b/electrum/gui/kivy/uix/ui_screens/server.kv
@@ -1,5 +1,3 @@
-#:import ServerAddr electrum.interface.ServerAddr
-
Popup:
id: nd
title: _('Server')
@@ -18,27 +16,14 @@ Popup:
height: '36dp'
size_hint_x: 1
size_hint_y: None
- text: _('Host') + ':'
+ text: _('Server') + ':'
TextInput:
- id: host
+ id: server_str
multiline: False
height: '36dp'
size_hint_x: 3
size_hint_y: None
- text: app.network.get_parameters().server.host
- Label:
- height: '36dp'
- size_hint_x: 1
- size_hint_y: None
- text: _('Port') + ':'
- TextInput:
- id: port
- multiline: False
- input_type: 'number'
- height: '36dp'
- size_hint_x: 3
- size_hint_y: None
- text: str(app.network.get_parameters().server.port)
+ text: app.network.get_parameters().server.net_addr_str()
Widget
Button:
id: chooser
@@ -58,5 +43,5 @@ Popup:
height: '48dp'
text: _('OK')
on_release:
- app.maybe_switch_to_server(host=str(root.ids.host.text), port=str(root.ids.port.text))
+ app.maybe_switch_to_server(str(root.ids.server_str.text))
nd.dismiss()
diff --git a/electrum/gui/qt/network_dialog.py b/electrum/gui/qt/network_dialog.py
@@ -36,8 +36,8 @@ from PyQt5.QtGui import QFontMetrics
from electrum.i18n import _
from electrum import constants, blockchain, util
-from electrum.interface import ServerAddr
-from electrum.network import Network, PREFERRED_NETWORK_PROTOCOL
+from electrum.interface import ServerAddr, PREFERRED_NETWORK_PROTOCOL
+from electrum.network import Network
from electrum.logging import get_logger
from .util import (Buttons, CloseButton, HelpButton, read_QIcon, char_width_in_lineedit,
@@ -171,8 +171,7 @@ class ServerListWidget(QTreeWidget):
menu.exec_(self.viewport().mapToGlobal(position))
def set_server(self, server: ServerAddr):
- self.parent.server_host.setText(server.host)
- self.parent.server_port.setText(str(server.port))
+ self.parent.server_e.setText(server.net_addr_str())
self.parent.set_server()
def keyPressEvent(self, event):
@@ -230,15 +229,12 @@ class NetworkChoiceLayout(object):
grid = QGridLayout(server_tab)
grid.setSpacing(8)
- self.server_host = QLineEdit()
- self.server_host.setFixedWidth(fixed_width_hostname)
- self.server_port = QLineEdit()
- self.server_port.setFixedWidth(fixed_width_port)
+ self.server_e = QLineEdit()
+ self.server_e.setFixedWidth(fixed_width_hostname + fixed_width_port)
self.autoconnect_cb = QCheckBox(_('Select server automatically'))
self.autoconnect_cb.setEnabled(self.config.is_modifiable('auto_connect'))
- self.server_host.editingFinished.connect(self.set_server)
- self.server_port.editingFinished.connect(self.set_server)
+ self.server_e.editingFinished.connect(self.set_server)
self.autoconnect_cb.clicked.connect(self.set_server)
self.autoconnect_cb.clicked.connect(self.update)
@@ -250,8 +246,7 @@ class NetworkChoiceLayout(object):
grid.addWidget(HelpButton(msg), 0, 4)
grid.addWidget(QLabel(_('Server') + ':'), 1, 0)
- grid.addWidget(self.server_host, 1, 1, 1, 2)
- grid.addWidget(self.server_port, 1, 3)
+ grid.addWidget(self.server_e, 1, 1, 1, 3)
label = _('Server peers') if network.is_connected() else _('Default Servers')
grid.addWidget(QLabel(label), 2, 0, 1, 5)
@@ -355,20 +350,18 @@ class NetworkChoiceLayout(object):
def enable_set_server(self):
if self.config.is_modifiable('server'):
enabled = not self.autoconnect_cb.isChecked()
- self.server_host.setEnabled(enabled)
- self.server_port.setEnabled(enabled)
+ self.server_e.setEnabled(enabled)
self.servers_list.setEnabled(enabled)
else:
- for w in [self.autoconnect_cb, self.server_host, self.server_port, self.servers_list]:
+ for w in [self.autoconnect_cb, self.server_e, self.servers_list]:
w.setEnabled(False)
def update(self):
net_params = self.network.get_parameters()
server = net_params.server
proxy_config, auto_connect = net_params.proxy, net_params.auto_connect
- if not self.server_host.hasFocus() and not self.server_port.hasFocus():
- self.server_host.setText(server.host)
- self.server_port.setText(str(server.port))
+ if not self.server_e.hasFocus():
+ self.server_e.setText(server.net_addr_str())
self.autoconnect_cb.setChecked(auto_connect)
interface = self.network.interface
@@ -425,33 +418,13 @@ class NetworkChoiceLayout(object):
self.network.run_from_another_thread(self.network.follow_chain_given_server(server))
self.update()
- def change_server(self, host, protocol):
- pp = self.servers.get(host, constants.net.DEFAULT_PORTS)
- if protocol and protocol not in protocol_letters:
- protocol = None
- if protocol:
- port = pp.get(protocol)
- if port is None:
- protocol = None
- if not protocol:
- if 's' in pp.keys():
- protocol = 's'
- port = pp.get(protocol)
- else:
- protocol = list(pp.keys())[0]
- port = pp.get(protocol)
- self.server_host.setText(host)
- self.server_port.setText(port)
-
def accept(self):
pass
def set_server(self):
net_params = self.network.get_parameters()
try:
- server = ServerAddr(host=str(self.server_host.text()),
- port=str(self.server_port.text()),
- protocol=net_params.server.protocol)
+ server = ServerAddr.from_str_with_inference(str(self.server_e.text()))
except Exception:
return
net_params = net_params._replace(server=server,
diff --git a/electrum/interface.py b/electrum/interface.py
@@ -65,6 +65,10 @@ BUCKET_NAME_OF_ONION_SERVERS = 'onion'
MAX_INCOMING_MSG_SIZE = 1_000_000 # in bytes
+_KNOWN_NETWORK_PROTOCOLS = {'t', 's'}
+PREFERRED_NETWORK_PROTOCOL = 's'
+assert PREFERRED_NETWORK_PROTOCOL in _KNOWN_NETWORK_PROTOCOLS
+
class NetworkTimeout:
# seconds
@@ -212,7 +216,7 @@ class ServerAddr:
net_addr = NetAddress(host, port) # this validates host and port
except Exception as e:
raise ValueError(f"cannot construct ServerAddr: invalid host or port (host={host}, port={port})") from e
- if protocol not in ('s', 't'):
+ if protocol not in _KNOWN_NETWORK_PROTOCOLS:
raise ValueError(f"invalid network protocol: {protocol}")
self.host = str(net_addr.host) # canonical form (if e.g. IPv6 address)
self.port = int(net_addr.port)
@@ -225,6 +229,24 @@ class ServerAddr:
host, port, protocol = str(s).rsplit(':', 2)
return ServerAddr(host=host, port=port, protocol=protocol)
+ @classmethod
+ def from_str_with_inference(cls, s: str) -> Optional['ServerAddr']:
+ """Construct ServerAddr from str, guessing missing details.
+ Ongoing compatibility not guaranteed.
+ """
+ if not s:
+ return None
+ items = str(s).rsplit(':', 2)
+ if len(items) < 2:
+ return None # although maybe we could guess the port too?
+ host = items[0]
+ port = items[1]
+ if len(items) >= 3:
+ protocol = items[2]
+ else:
+ protocol = PREFERRED_NETWORK_PROTOCOL
+ return ServerAddr(host=host, port=port, protocol=protocol)
+
def __str__(self):
return '{}:{}'.format(self.net_addr_str(), self.protocol)
diff --git a/electrum/network.py b/electrum/network.py
@@ -53,7 +53,7 @@ from . import bitcoin
from . import dns_hacks
from .transaction import Transaction
from .blockchain import Blockchain, HEADER_SIZE
-from .interface import (Interface,
+from .interface import (Interface, PREFERRED_NETWORK_PROTOCOL,
RequestTimedOut, NetworkTimeout, BUCKET_NAME_OF_ONION_SERVERS,
NetworkException, RequestCorrupted, ServerAddr)
from .version import PROTOCOL_VERSION
@@ -75,10 +75,6 @@ NUM_TARGET_CONNECTED_SERVERS = 10
NUM_STICKY_SERVERS = 4
NUM_RECENT_SERVERS = 20
-_KNOWN_NETWORK_PROTOCOLS = {'t', 's'}
-PREFERRED_NETWORK_PROTOCOL = 's'
-assert PREFERRED_NETWORK_PROTOCOL in _KNOWN_NETWORK_PROTOCOLS
-
def parse_servers(result: Sequence[Tuple[str, str, List[str]]]) -> Dict[str, dict]:
""" parse servers list into dict format"""