mirror of
https://github.com/markqvist/NomadNet.git
synced 2025-02-22 08:00:00 -05:00
Implemented support for standalone LXMF propagation nodes
This commit is contained in:
parent
fe257a63c0
commit
4fcf37ac86
@ -5,6 +5,29 @@ import time
|
||||
import nomadnet
|
||||
import RNS.vendor.umsgpack as msgpack
|
||||
|
||||
class PNAnnounceHandler:
|
||||
def __init__(self, owner):
|
||||
self.aspect_filter = "lxmf.propagation"
|
||||
self.owner = owner
|
||||
|
||||
def received_announce(self, destination_hash, announced_identity, app_data):
|
||||
try:
|
||||
if type(app_data) == bytes:
|
||||
data = msgpack.unpackb(app_data)
|
||||
|
||||
if data[0] == True:
|
||||
RNS.log("Received active propagation node announce from "+RNS.prettyhexrep(destination_hash))
|
||||
|
||||
associated_peer = RNS.Destination.hash_from_name_and_identity("lxmf.delivery", announced_identity)
|
||||
associated_node = RNS.Destination.hash_from_name_and_identity("nomadnetwork.node", announced_identity)
|
||||
|
||||
self.owner.app.directory.pn_announce_received(destination_hash, app_data, associated_peer, associated_node)
|
||||
self.owner.app.autoselect_propagation_node()
|
||||
|
||||
except Exception as e:
|
||||
RNS.log("Error while evaluating propagation node announce, ignoring announce.", RNS.LOG_DEBUG)
|
||||
RNS.log("The contained exception was: "+str(e), RNS.LOG_DEBUG)
|
||||
|
||||
class Directory:
|
||||
ANNOUNCE_STREAM_MAXLENGTH = 64
|
||||
|
||||
@ -14,8 +37,6 @@ class Directory:
|
||||
app = nomadnet.NomadNetworkApp.get_shared_instance()
|
||||
|
||||
if not destination_hash in app.ignored_list:
|
||||
destination_hash_text = RNS.hexrep(destination_hash, delimit=False)
|
||||
|
||||
associated_peer = RNS.Destination.hash_from_name_and_identity("lxmf.delivery", announced_identity)
|
||||
|
||||
app.directory.node_announce_received(destination_hash, app_data, associated_peer)
|
||||
@ -31,6 +52,9 @@ class Directory:
|
||||
self.app = app
|
||||
self.load_from_disk()
|
||||
|
||||
self.pn_announce_handler = PNAnnounceHandler(self)
|
||||
RNS.Transport.register_announce_handler(self.pn_announce_handler)
|
||||
|
||||
|
||||
def save_to_disk(self):
|
||||
try:
|
||||
@ -90,7 +114,7 @@ class Directory:
|
||||
def lxmf_announce_received(self, source_hash, app_data):
|
||||
if app_data != None:
|
||||
timestamp = time.time()
|
||||
self.announce_stream.insert(0, (timestamp, source_hash, app_data, False))
|
||||
self.announce_stream.insert(0, (timestamp, source_hash, app_data, "peer"))
|
||||
while len(self.announce_stream) > Directory.ANNOUNCE_STREAM_MAXLENGTH:
|
||||
self.announce_stream.pop()
|
||||
|
||||
@ -100,7 +124,7 @@ class Directory:
|
||||
def node_announce_received(self, source_hash, app_data, associated_peer):
|
||||
if app_data != None:
|
||||
timestamp = time.time()
|
||||
self.announce_stream.insert(0, (timestamp, source_hash, app_data, True))
|
||||
self.announce_stream.insert(0, (timestamp, source_hash, app_data, "node"))
|
||||
while len(self.announce_stream) > Directory.ANNOUNCE_STREAM_MAXLENGTH:
|
||||
self.announce_stream.pop()
|
||||
|
||||
@ -113,6 +137,27 @@ class Directory:
|
||||
if hasattr(self.app.ui, "main_display"):
|
||||
self.app.ui.main_display.sub_displays.network_display.directory_change_callback()
|
||||
|
||||
def pn_announce_received(self, source_hash, app_data, associated_peer, associated_node):
|
||||
found_node = None
|
||||
for sh in self.directory_entries:
|
||||
if sh == associated_node:
|
||||
found_node = True
|
||||
break
|
||||
|
||||
for e in self.announce_stream:
|
||||
if e[1] == associated_node:
|
||||
found_node = True
|
||||
break
|
||||
|
||||
if not found_node:
|
||||
timestamp = time.time()
|
||||
self.announce_stream.insert(0, (timestamp, source_hash, app_data, "pn"))
|
||||
while len(self.announce_stream) > Directory.ANNOUNCE_STREAM_MAXLENGTH:
|
||||
self.announce_stream.pop()
|
||||
|
||||
if hasattr(self.app.ui, "main_display"):
|
||||
self.app.ui.main_display.sub_displays.network_display.directory_change_callback()
|
||||
|
||||
def remove_announce_with_timestamp(self, timestamp):
|
||||
selected_announce = None
|
||||
for announce in self.announce_stream:
|
||||
@ -250,11 +295,6 @@ class DirectoryEntry:
|
||||
def __init__(self, source_hash, display_name=None, trust_level=UNKNOWN, hosts_node=False, preferred_delivery=None, identify_on_connect=False):
|
||||
if len(source_hash) == RNS.Identity.TRUNCATED_HASHLENGTH//8:
|
||||
self.source_hash = source_hash
|
||||
|
||||
# TODO: Clean
|
||||
# if display_name == None:
|
||||
# display_name = source_hash
|
||||
|
||||
self.display_name = display_name
|
||||
|
||||
if preferred_delivery == None:
|
||||
|
@ -436,8 +436,9 @@ class NomadNetworkApp:
|
||||
def autoselect_propagation_node(self):
|
||||
selected_node = None
|
||||
|
||||
if "propagation_node" in self.peer_settings and self.directory.find(self.peer_settings["propagation_node"]):
|
||||
selected_node = self.directory.find(self.peer_settings["propagation_node"])
|
||||
if "propagation_node" in self.peer_settings:
|
||||
selected_node = self.peer_settings["propagation_node"]
|
||||
|
||||
else:
|
||||
nodes = self.directory.known_nodes()
|
||||
trusted_nodes = []
|
||||
@ -450,19 +451,14 @@ class NomadNetworkApp:
|
||||
|
||||
if hops < best_hops:
|
||||
best_hops = hops
|
||||
selected_node = node
|
||||
selected_node = node.source_hash
|
||||
|
||||
if selected_node == None:
|
||||
RNS.log("Could not autoselect a propagation node! LXMF propagation will not be available until a trusted node announces on the network.", RNS.LOG_WARNING)
|
||||
RNS.log("Could not autoselect a propagation node! LXMF propagation will not be available until a trusted node announces on the network, or a propagation node is manually selected.", RNS.LOG_WARNING)
|
||||
else:
|
||||
node_identity = RNS.Identity.recall(selected_node.source_hash)
|
||||
if node_identity != None:
|
||||
propagation_hash = RNS.Destination.hash_from_name_and_identity("lxmf.propagation", node_identity)
|
||||
RNS.log("Selecting "+selected_node.display_name+" "+RNS.prettyhexrep(propagation_hash)+" as default LXMF propagation node", RNS.LOG_INFO)
|
||||
self.message_router.set_outbound_propagation_node(propagation_hash)
|
||||
else:
|
||||
RNS.log("Could not recall identity for autoselected LXMF propagation node "+RNS.prettyhexrep(selected_node.source_hash), RNS.LOG_WARNING)
|
||||
RNS.log("LXMF propagation will not be available until a trusted node announces on the network.", RNS.LOG_WARNING)
|
||||
pn_name_str = ""
|
||||
RNS.log("Selecting "+RNS.prettyhexrep(selected_node)+pn_name_str+" as default LXMF propagation node", RNS.LOG_INFO)
|
||||
self.message_router.set_outbound_propagation_node(selected_node)
|
||||
|
||||
def get_user_selected_propagation_node(self):
|
||||
if "propagation_node" in self.peer_settings:
|
||||
|
@ -1 +1 @@
|
||||
__version__ = "0.2.5"
|
||||
__version__ = "0.2.6"
|
||||
|
@ -398,10 +398,15 @@ class ConversationsDisplay():
|
||||
if pn_ident != None:
|
||||
node_hash = RNS.Destination.hash_from_name_and_identity("nomadnetwork.node", pn_ident)
|
||||
pn_entry = self.app.directory.find(node_hash)
|
||||
pn_display_str = " "
|
||||
if pn_entry != None:
|
||||
pn_display_str += " "+str(pn_entry.display_name)
|
||||
else:
|
||||
pn_display_str += " "+RNS.prettyhexrep(pn_hash)
|
||||
|
||||
dialog = DialogLineBox(
|
||||
urwid.Pile([
|
||||
urwid.Text(""+g["node"]+" "+str(pn_entry.display_name), align="center"),
|
||||
urwid.Text(""+g["node"]+pn_display_str, align="center"),
|
||||
urwid.Divider(g["divider1"]),
|
||||
sync_progress,
|
||||
urwid.Divider(g["divider1"]),
|
||||
@ -417,7 +422,7 @@ class ConversationsDisplay():
|
||||
urwid.Pile([
|
||||
urwid.Text(""),
|
||||
urwid.Text("No trusted nodes found, cannot sync!\n", align="center"),
|
||||
urwid.Text("To syncronise messages from the network, one or more nodes must be marked as trusted in the Known Nodes list. Nomad Network will then automatically sync from the nearest trusted node.", align="left"),
|
||||
urwid.Text("To syncronise messages from the network, one or more nodes must be marked as trusted in the Known Nodes list, or a node must manually be selected as the default propagation node. Nomad Network will then automatically sync from the nearest trusted node, or the manually selected one.", align="left"),
|
||||
urwid.Text(""),
|
||||
button_columns
|
||||
]), title="Message Sync"
|
||||
|
@ -71,11 +71,17 @@ class AnnounceInfo(urwid.WidgetWrap):
|
||||
trust_str = ""
|
||||
display_str = self.app.directory.simplest_display_str(source_hash)
|
||||
addr_str = "<"+RNS.hexrep(source_hash, delimit=False)+">"
|
||||
is_node = announce[3]
|
||||
info_type = announce[3]
|
||||
|
||||
if is_node:
|
||||
type_string = "Node " + g["node"]
|
||||
else:
|
||||
is_node = False
|
||||
is_pn = False
|
||||
if info_type == "node" or info_type == True:
|
||||
type_string = "Nomad Network Node " + g["node"]
|
||||
is_node = True
|
||||
elif info_type == "pn":
|
||||
type_string = "LXMF Propagation Node " + g["sent"]
|
||||
is_pn = True
|
||||
elif info_type == "peer" or info_type == False:
|
||||
type_string = "Peer " + g["peer"]
|
||||
|
||||
try:
|
||||
@ -174,10 +180,20 @@ class AnnounceInfo(urwid.WidgetWrap):
|
||||
except Exception as e:
|
||||
RNS.log("Error while starting conversation from announce. The contained exception was: "+str(e), RNS.LOG_ERROR)
|
||||
|
||||
def use_pn(sender):
|
||||
show_announce_stream(None)
|
||||
try:
|
||||
self.app.set_user_selected_propagation_node(source_hash)
|
||||
except Exception as e:
|
||||
RNS.log("Error while setting active propagation node from announce. The contained exception was: "+str(e), RNS.LOG_ERROR)
|
||||
|
||||
if is_node:
|
||||
type_button = ("weight", 0.45, urwid.Button("Connect", on_press=connect))
|
||||
msg_button = ("weight", 0.45, urwid.Button("Msg Op", on_press=msg_op))
|
||||
save_button = ("weight", 0.45, urwid.Button("Save", on_press=save_node))
|
||||
elif is_pn:
|
||||
type_button = ("weight", 0.45, urwid.Button("Use as default", on_press=use_pn))
|
||||
save_button = None
|
||||
else:
|
||||
type_button = ("weight", 0.45, urwid.Button("Converse", on_press=converse))
|
||||
save_button = None
|
||||
@ -187,21 +203,33 @@ class AnnounceInfo(urwid.WidgetWrap):
|
||||
else:
|
||||
button_columns = urwid.Columns([("weight", 0.45, urwid.Button("Back", on_press=show_announce_stream)), ("weight", 0.1, urwid.Text("")), type_button])
|
||||
|
||||
pile_widgets = [
|
||||
urwid.Text("Time : "+ts_string, align="left"),
|
||||
urwid.Text("Addr : "+addr_str, align="left"),
|
||||
urwid.Text("Type : "+type_string, align="left"),
|
||||
urwid.Text("Name : "+display_str, align="left"),
|
||||
urwid.Text(["Trust : ", (style, trust_str)], align="left"),
|
||||
urwid.Divider(g["divider1"]),
|
||||
urwid.Text(["Announce Data: \n", (data_style, data_str)], align="left"),
|
||||
urwid.Divider(g["divider1"]),
|
||||
button_columns
|
||||
]
|
||||
pile_widgets = []
|
||||
|
||||
if is_node:
|
||||
operator_entry = urwid.Text("Oprtr : "+op_str, align="left")
|
||||
pile_widgets.insert(4, operator_entry)
|
||||
if is_pn:
|
||||
pile_widgets = [
|
||||
urwid.Text("Time : "+ts_string, align="left"),
|
||||
urwid.Text("Addr : "+addr_str, align="left"),
|
||||
urwid.Text("Type : "+type_string, align="left"),
|
||||
urwid.Divider(g["divider1"]),
|
||||
button_columns
|
||||
]
|
||||
|
||||
else:
|
||||
pile_widgets = [
|
||||
urwid.Text("Time : "+ts_string, align="left"),
|
||||
urwid.Text("Addr : "+addr_str, align="left"),
|
||||
urwid.Text("Type : "+type_string, align="left"),
|
||||
urwid.Text("Name : "+display_str, align="left"),
|
||||
urwid.Text(["Trust : ", (style, trust_str)], align="left"),
|
||||
urwid.Divider(g["divider1"]),
|
||||
urwid.Text(["Announce Data: \n", (data_style, data_str)], align="left"),
|
||||
urwid.Divider(g["divider1"]),
|
||||
button_columns
|
||||
]
|
||||
|
||||
if is_node:
|
||||
operator_entry = urwid.Text("Oprtr : "+op_str, align="left")
|
||||
pile_widgets.insert(4, operator_entry)
|
||||
|
||||
pile = urwid.Pile(pile_widgets)
|
||||
|
||||
@ -220,7 +248,7 @@ class AnnounceStreamEntry(urwid.WidgetWrap):
|
||||
|
||||
timestamp = announce[0]
|
||||
source_hash = announce[1]
|
||||
is_node = announce[3]
|
||||
announce_type = announce[3]
|
||||
self.app = app
|
||||
self.timestamp = timestamp
|
||||
time_format = app.time_format
|
||||
@ -257,10 +285,12 @@ class AnnounceStreamEntry(urwid.WidgetWrap):
|
||||
style = "list_untrusted"
|
||||
focus_style = "list_focus_untrusted"
|
||||
|
||||
if is_node:
|
||||
if announce_type == "node" or announce_type == True:
|
||||
type_symbol = g["node"]
|
||||
else:
|
||||
elif announce_type == "peer" or announce_type == False:
|
||||
type_symbol = g["peer"]
|
||||
elif announce_type == "pn":
|
||||
type_symbol = g["sent"]
|
||||
|
||||
widget = ListEntry(ts_string+" "+type_symbol+" "+display_str)
|
||||
urwid.connect_signal(widget, "click", self.display_announce, announce)
|
||||
@ -425,13 +455,15 @@ class KnownNodeInfo(urwid.WidgetWrap):
|
||||
if display_str == None:
|
||||
display_str = addr_str
|
||||
|
||||
pn_hash = RNS.Destination.hash_from_name_and_identity("lxmf.propagation", node_ident)
|
||||
|
||||
if node_ident != None:
|
||||
lxmf_addr_str = g["sent"]+" LXMF Propagation Node Address is "+RNS.prettyhexrep(RNS.Destination.hash_from_name_and_identity("lxmf.propagation", node_ident))
|
||||
lxmf_addr_str = g["sent"]+" LXMF Propagation Node Address is "+RNS.prettyhexrep(pn_hash)
|
||||
else:
|
||||
lxmf_addr_str = "No associated Propagation Node known"
|
||||
|
||||
|
||||
type_string = "Node " + g["node"]
|
||||
type_string = "Nomad Network Node " + g["node"]
|
||||
|
||||
if trust_level == DirectoryEntry.UNTRUSTED:
|
||||
trust_str = "Untrusted"
|
||||
@ -525,7 +557,7 @@ class KnownNodeInfo(urwid.WidgetWrap):
|
||||
def save_node(sender):
|
||||
if self.pn_changed:
|
||||
if propagation_node_checkbox.get_state():
|
||||
self.app.set_user_selected_propagation_node(source_hash)
|
||||
self.app.set_user_selected_propagation_node(pn_hash)
|
||||
else:
|
||||
self.app.set_user_selected_propagation_node(None)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user