Skip to content

Commit

Permalink
Added propagation node list sorting and manual delivery sync initiation
Browse files Browse the repository at this point in the history
  • Loading branch information
markqvist committed Oct 15, 2023
1 parent 8d72a83 commit a3bf538
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 18 deletions.
6 changes: 6 additions & 0 deletions nomadnet/Directory.py
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,12 @@ def trust_level(self, source_hash, announced_display_name=None):
else:
return DirectoryEntry.UNKNOWN

def pn_trust_level(self, source_hash):
recalled_identity = RNS.Identity.recall(source_hash)
if recalled_identity != None:
associated_node = RNS.Destination.hash_from_name_and_identity("nomadnetwork.node", recalled_identity)
return self.trust_level(associated_node)

def sort_rank(self, source_hash):
if source_hash in self.directory_entries:
return self.directory_entries[source_hash].sort_rank
Expand Down
29 changes: 18 additions & 11 deletions nomadnet/ui/textui/Guide.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,15 @@ def focus_reader(self):
- Ctrl-W Close conversation
>>`!Network Window`!
>>>Browser
- Ctrl-D Back
- Ctrl-F Forward
- Ctrl-R Reload page
- Ctrl-U Open URL entry dialog
- Ctrl-S Save connected node
- Ctrl-G Toggle fullscreen browser window
- Ctrl-W Disconnect from node
>>>Announce Stream
- Ctrl-L Switch to Known Nodes list
- Ctrl-X Delete selected announce
Expand All @@ -227,14 +236,10 @@ def focus_reader(self):
- Ctrl-X Delete selected node entry
- Ctrl-P Display peered LXMF Propagation Nodes
>>>Browser
- Ctrl-D Back
- Ctrl-F Forward
- Ctrl-R Reload page
- Ctrl-U Open URL entry dialog
- Ctrl-S Save connected node
- Ctrl-G Toggle fullscreen browser window
- Ctrl-W Disconnect from node
>>>Peered LXMF Propagation Nodes
- Ctrl-L Switch to Announce Stream or Known Nodes
- Ctrl-X Break peering with selected node entry
- Ctrl-R Request immediate delivery sync of unhandled LXMs
'''

TOPIC_CONCEPTS = '''>Concepts and Terminology
Expand Down Expand Up @@ -302,11 +307,13 @@ def focus_reader(self):
>>Distributed Message Store
All nodes on the network automatically form a distributed message store that allows users to exchange messages, even when they are not available at the same time.
All nodes on the network will automatically participate in a distributed message store that allows users to exchange messages, even when they are not connected to the network at the same time.
When Nomad Network is configured to host a node, by default it also configures itself as an LXMF Propagation Node, and automatically discovers and peers with other propagation nodes on the network. This process is completely automatic and requires no configuration from the node operator.
When Nomad Network is configured to host a node, it also configures itself as an LXMF Propagation Node, and automatically discovers and peers with other propagation nodes on the network. This process is completely automatic and requires no configuration from the node operator.
If there is already an abundance of Propagation Nodes on the network, or the operator simply wishes to host a pageserving-only node, Propagation Node hosting can be disabled in the configuration file.
To view LXMF Propagation nodes that are currently peered with your node, go to the `![ Network ]`! part of the program and press `!Ctrl-P`!.
To view LXMF Propagation nodes that are currently peered with your node, go to the `![ Network ]`! part of the program and press `!Ctrl-P`!. In the list of peered Propagation Nodes, it is possible to break peering with a node by pressing `!Ctrl-X`!. It is also possible to request an immediate delivery sync of all unhandled messages for a node, by pressing `!Ctrl-R`!.
The distributed message store is resilient to intermittency, and will remain functional as long as at least one node remains on the network. Nodes that were offline for a time will automatically be synced up to date when they regain connectivity.
Expand Down
57 changes: 50 additions & 7 deletions nomadnet/ui/textui/Network.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import urwid
import nomadnet
import time
import threading
from datetime import datetime
from nomadnet.Directory import DirectoryEntry
from nomadnet.vendor.additional_urwid_widgets import IndicativeListBox, MODIFIER_KEY
Expand Down Expand Up @@ -1626,6 +1627,8 @@ def keypress(self, size, key):
nomadnet.NomadNetworkApp.get_shared_instance().ui.main_display.frame.set_focus("header")
elif key == "ctrl x":
self.delete_selected_entry()
elif key == "ctrl r":
self.sync_selected_entry()

return super(LXMFPeers, self).keypress(size, key)

Expand All @@ -1641,6 +1644,43 @@ def delete_selected_entry(self):
self.delegate.reinit_lxmf_peers()
self.delegate.show_peers()

def sync_selected_entry(self):
sync_grace = 10
si = self.ilb.get_selected_item()
if si != None:
destination_hash = si.original_widget.destination_hash
if destination_hash in self.app.message_router.peers:
peer = self.app.message_router.peers[destination_hash]
if time.time() > peer.last_sync_attempt+sync_grace:
peer.next_sync_attempt = time.time()-1

def job():
peer.sync()
threading.Thread(target=job, daemon=True).start()

time.sleep(0.25)

def dismiss_dialog(sender):
self.close_list_dialogs()

dialog = ListDialogLineBox(
urwid.Pile([
urwid.Text("A delivery sync of all unhandled LXMs was manually requested for the selected node\n", align="center"),
urwid.Columns([("weight", 0.1, urwid.Text("")), ("weight", 0.45, urwid.Button("OK", on_press=dismiss_dialog))])
]), title="!"
)
dialog.delegate = self.delegate
bottom = self

overlay = urwid.Overlay(dialog, bottom, align="center", width=("relative", 100), valign="middle", height="pack", left=2, right=2)

options = self.delegate.left_pile.options("weight", 1)
self.delegate.left_pile.contents[0] = (overlay, options)


def close_list_dialogs(self):
self.delegate.reinit_lxmf_peers()
self.delegate.show_peers()

def rebuild_widget_list(self):
self.peer_list = self.app.message_router.peers
Expand All @@ -1654,17 +1694,18 @@ def rebuild_widget_list(self):

def make_peer_widgets(self):
widget_list = []
sorted_peers = sorted(self.peer_list, key=lambda pid: self.peer_list[pid].link_establishment_rate, reverse=True)
sorted_peers = sorted(self.peer_list, key=lambda pid: (self.app.directory.pn_trust_level(pid), self.peer_list[pid].link_establishment_rate), reverse=True)
for peer_id in sorted_peers:
peer = self.peer_list[peer_id]
pe = LXMFPeerEntry(self.app, peer, self)
trust_level = self.app.directory.pn_trust_level(peer_id)
pe = LXMFPeerEntry(self.app, peer, self, trust_level)
pe.destination_hash = peer.destination_hash
widget_list.append(pe)

return widget_list

class LXMFPeerEntry(urwid.WidgetWrap):
def __init__(self, app, peer, delegate):
def __init__(self, app, peer, delegate, trust_level):
destination_hash = peer.destination_hash

self.app = app
Expand All @@ -1686,16 +1727,18 @@ def __init__(self, app, peer, delegate):
if hasattr(peer, "alive"):
if peer.alive:
alive_string = "Available"
style = "list_normal"
focus_style = "list_focus"
if trust_level == DirectoryEntry.TRUSTED:
style = "list_trusted"
focus_style = "list_focus_trusted"
else:
style = "list_normal"
focus_style = "list_focus"
else:
alive_string = "Unresponsive"
style = "list_unresponsive"
focus_style = "list_focus_unresponsive"

widget = ListEntry(sym+" "+display_str+"\n "+alive_string+", last heard "+pretty_date(int(peer.last_heard))+"\n "+str(len(peer.unhandled_messages))+" unhandled LXMs, "+RNS.prettysize(peer.link_establishment_rate/8, "b")+"/s LER")
# urwid.connect_signal(widget, "click", delegate.connect_node, node)

self.display_widget = urwid.AttrMap(widget, style, focus_style)
self.display_widget.destination_hash = destination_hash
urwid.WidgetWrap.__init__(self, self.display_widget)
Expand Down

0 comments on commit a3bf538

Please sign in to comment.