Browse Source

Merge pull request #8865 from SomberNight/202402_server_bookmarks

network: implement basic "add server as bookmark" functionality
master
ghost43 2 years ago committed by GitHub
parent
commit
e11d7b37f2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. BIN
      electrum/gui/icons/bookmark.png
  2. 11
      electrum/gui/icons/bookmark.svg
  3. BIN
      electrum/gui/icons/bookmark_add.png
  4. 23
      electrum/gui/icons/bookmark_add.svg
  5. BIN
      electrum/gui/icons/bookmark_remove.png
  6. 23
      electrum/gui/icons/bookmark_remove.svg
  7. 26
      electrum/gui/qt/network_dialog.py
  8. 28
      electrum/network.py
  9. 1
      electrum/simple_config.py

BIN
electrum/gui/icons/bookmark.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 455 B

11
electrum/gui/icons/bookmark.svg

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 19.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 40 40" style="enable-background:new 0 0 40 40;" xml:space="preserve">
<g>
<polygon style="fill:#F78F8F;" points="20,31.441 8.5,37.191 8.5,2.5 31.5,2.5 31.5,37.191 "/>
<g>
<path style="fill:#C74343;" d="M31,3v33.382l-10.553-5.276L20,30.882l-0.447,0.224L9,36.382V3H31 M32,2H8v36l12-6l12,6V2L32,2z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 588 B

BIN
electrum/gui/icons/bookmark_add.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

23
electrum/gui/icons/bookmark_add.svg

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 25.2.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" baseProfile="basic" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
y="0px" viewBox="0 0 40 40" xml:space="preserve">
<g id="Layer_10">
</g>
<g id="fluent_1_">
</g>
<g id="color">
</g>
<g id="office">
<path style="fill:#F78F8F;" d="M20,31.441l-11.5,5.75V2.5h23v34.691L20,31.441z"/>
<path style="fill:#C74343;" d="M31,3v33.382l-10.553-5.276L20,30.882l-0.447,0.224L9,36.382V3H31 M32,2H8v36l12-6l12,6V2L32,2z"/>
<path style="fill:#BAE0BD;" d="M31,26.5c-4.687,0-8.5-3.813-8.5-8.5s3.813-8.5,8.5-8.5s8.5,3.813,8.5,8.5S35.687,26.5,31,26.5z"/>
<path style="fill:#5E9C76;" d="M31,10c4.411,0,8,3.589,8,8s-3.589,8-8,8s-8-3.589-8-8S26.589,10,31,10 M31,9c-4.971,0-9,4.029-9,9
s4.029,9,9,9s9-4.029,9-9S35.971,9,31,9L31,9z"/>
<polygon style="fill:#FFFFFF;" points="32,23 30,23 30,19 26,19 26,17 30,17 30,13 32,13 32,17 36,17 36,19 32,19 "/>
</g>
<g id="ios">
</g>
<g id="fluent">
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
electrum/gui/icons/bookmark_remove.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

23
electrum/gui/icons/bookmark_remove.svg

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 25.2.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" baseProfile="basic" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
y="0px" viewBox="0 0 40 40" xml:space="preserve">
<g id="Layer_10">
</g>
<g id="fluent_1_">
</g>
<g id="color">
</g>
<g id="office">
<path style="fill:#F78F8F;" d="M20,31.441l-11.5,5.75V2.5h23v34.691L20,31.441z"/>
<path style="fill:#C74343;" d="M31,3v33.382l-10.553-5.276L20,30.882l-0.447,0.224L9,36.382V3H31 M32,2H8v36l12-6l12,6V2L32,2z"/>
<path style="fill:#FFC49C;" d="M31,26.5c-4.687,0-8.5-3.813-8.5-8.5s3.813-8.5,8.5-8.5s8.5,3.813,8.5,8.5S35.687,26.5,31,26.5z"/>
<path style="fill:#A16A4A;" d="M31,10c4.411,0,8,3.589,8,8s-3.589,8-8,8s-8-3.589-8-8S26.589,10,31,10 M31,9c-4.971,0-9,4.029-9,9
s4.029,9,9,9s9-4.029,9-9S35.971,9,31,9L31,9z"/>
<rect x="26" y="17" style="fill:#FFFFFF;" width="10" height="2"/>
</g>
<g id="ios">
</g>
<g id="fluent">
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

26
electrum/gui/qt/network_dialog.py

@ -123,6 +123,13 @@ class NodesListWidget(QTreeWidget):
def do_set_server(): def do_set_server():
self.setServer.emit(str(server)) self.setServer.emit(str(server))
menu.addAction(read_QIcon("chevron-right.png"), _("Use as server"), do_set_server) menu.addAction(read_QIcon("chevron-right.png"), _("Use as server"), do_set_server)
def set_bookmark(*, add: bool):
self.network.set_server_bookmark(server, add=add)
self.update()
if self.network.is_server_bookmarked(server):
menu.addAction(read_QIcon("bookmark_remove.png"), _("Remove from bookmarks"), lambda: set_bookmark(add=False))
else:
menu.addAction(read_QIcon("bookmark_add.png"), _("Bookmark this server"), lambda: set_bookmark(add=True))
elif item_type == self.ItemType.CHAIN: elif item_type == self.ItemType.CHAIN:
chain_id = item.data(0, self.CHAIN_ID_ROLE) chain_id = item.data(0, self.CHAIN_ID_ROLE)
def do_follow_chain(): def do_follow_chain():
@ -174,6 +181,8 @@ class NodesListWidget(QTreeWidget):
item.setToolTip(0, str(i.server)) item.setToolTip(0, str(i.server))
if i == network.interface: if i == network.interface:
item.setIcon(0, read_QIcon("chevron-right.png")) item.setIcon(0, read_QIcon("chevron-right.png"))
elif network.is_server_bookmarked(i.server):
item.setIcon(0, read_QIcon("bookmark.png"))
x.addChild(item) x.addChild(item)
if n_chains > 1: if n_chains > 1:
connected_servers_item.addChild(x) connected_servers_item.addChild(x)
@ -183,18 +192,21 @@ class NodesListWidget(QTreeWidget):
disconnected_servers_item.setData(0, self.ITEMTYPE_ROLE, self.ItemType.TOPLEVEL) disconnected_servers_item.setData(0, self.ITEMTYPE_ROLE, self.ItemType.TOPLEVEL)
connected_hosts = set([iface.host for ifaces in chains.values() for iface in ifaces]) connected_hosts = set([iface.host for ifaces in chains.values() for iface in ifaces])
protocol = PREFERRED_NETWORK_PROTOCOL protocol = PREFERRED_NETWORK_PROTOCOL
for _host, d in sorted(servers.items()): server_addrs = [
if _host in connected_hosts: ServerAddr(_host, port, protocol=protocol)
continue for _host, d in servers.items()
if _host.endswith('.onion') and not use_tor: if (port := d.get(protocol))]
server_addrs.sort(key=lambda x: (-network.is_server_bookmarked(x), str(x)))
for server in server_addrs:
if server.host in connected_hosts:
continue continue
port = d.get(protocol) if server.host.endswith('.onion') and not use_tor:
if not port:
continue continue
server = ServerAddr(_host, port, protocol=protocol)
item = QTreeWidgetItem([server.net_addr_str(), ""]) item = QTreeWidgetItem([server.net_addr_str(), ""])
item.setData(0, self.ITEMTYPE_ROLE, self.ItemType.DISCONNECTED_SERVER) item.setData(0, self.ITEMTYPE_ROLE, self.ItemType.DISCONNECTED_SERVER)
item.setData(0, self.SERVER_ADDR_ROLE, server) item.setData(0, self.SERVER_ADDR_ROLE, server)
if network.is_server_bookmarked(server):
item.setIcon(0, read_QIcon("bookmark.png"))
disconnected_servers_item.addChild(item) disconnected_servers_item.addChild(item)
self.addTopLevelItem(connected_servers_item) self.addTopLevelItem(connected_servers_item)

28
electrum/network.py

@ -581,6 +581,18 @@ class Network(Logger, NetworkRetryManager[ServerAddr]):
out[server.host].update({server.protocol: port}) out[server.host].update({server.protocol: port})
else: else:
out[server.host] = {server.protocol: port} out[server.host] = {server.protocol: port}
# add bookmarks
bookmarks = self.config.NETWORK_BOOKMARKED_SERVERS or []
for server_str in bookmarks:
try:
server = ServerAddr.from_str(server_str)
except ValueError:
continue
port = str(server.port)
if server.host in out:
out[server.host].update({server.protocol: port})
else:
out[server.host] = {server.protocol: port}
# potentially filter out some # potentially filter out some
if self.config.NETWORK_NOONION: if self.config.NETWORK_NOONION:
out = filter_noonion(out) out = filter_noonion(out)
@ -706,6 +718,22 @@ class Network(Logger, NetworkRetryManager[ServerAddr]):
self.oneserver = oneserver self.oneserver = oneserver
self.num_server = NUM_TARGET_CONNECTED_SERVERS if not oneserver else 0 self.num_server = NUM_TARGET_CONNECTED_SERVERS if not oneserver else 0
def is_server_bookmarked(self, server: ServerAddr) -> bool:
bookmarks = self.config.NETWORK_BOOKMARKED_SERVERS or []
return str(server) in bookmarks
def set_server_bookmark(self, server: ServerAddr, *, add: bool) -> None:
server_str = str(server)
with self.config.lock:
bookmarks = self.config.NETWORK_BOOKMARKED_SERVERS or []
if add:
if server_str not in bookmarks:
bookmarks.append(server_str)
else: # remove
if server_str in bookmarks:
bookmarks.remove(server_str)
self.config.NETWORK_BOOKMARKED_SERVERS = bookmarks
async def _switch_to_random_interface(self): async def _switch_to_random_interface(self):
'''Switch to a random connected server other than the current one''' '''Switch to a random connected server other than the current one'''
servers = self.get_interfaces() # Those in connected state servers = self.get_interfaces() # Those in connected state

1
electrum/simple_config.py

@ -940,6 +940,7 @@ class SimpleConfig(Logger):
NETWORK_SERVERFINGERPRINT = ConfigVar('serverfingerprint', default=None, type_=str) NETWORK_SERVERFINGERPRINT = ConfigVar('serverfingerprint', default=None, type_=str)
NETWORK_MAX_INCOMING_MSG_SIZE = ConfigVar('network_max_incoming_msg_size', default=1_000_000, type_=int) # in bytes NETWORK_MAX_INCOMING_MSG_SIZE = ConfigVar('network_max_incoming_msg_size', default=1_000_000, type_=int) # in bytes
NETWORK_TIMEOUT = ConfigVar('network_timeout', default=None, type_=int) NETWORK_TIMEOUT = ConfigVar('network_timeout', default=None, type_=int)
NETWORK_BOOKMARKED_SERVERS = ConfigVar('network_bookmarked_servers', default=None)
WALLET_BATCH_RBF = ConfigVar( WALLET_BATCH_RBF = ConfigVar(
'batch_rbf', default=False, type_=bool, 'batch_rbf', default=False, type_=bool,

Loading…
Cancel
Save