Compare commits

...

18 Commits

Author SHA1 Message Date
markqvist
eafe77718f Merge pull request #85 from RFnexus/master
Strip whitespace from LXMF address and URL dialog
2025-12-13 13:56:50 +01:00
Zenith
6d2bf21f0d Strip whitespace from LXMF address and URL dialog 2025-12-12 19:21:03 -05:00
Mark Qvist
eac9021c75 Updated required LXMF to 0.9.1 2025-11-03 22:31:34 +01:00
Mark Qvist
e6688b157e Ensure static_peers is initialized regardless of config 2025-11-03 12:38:07 +01:00
Mark Qvist
ad2cefa329 Allow configuring propagation node stamp cost 2025-11-01 18:27:47 +01:00
Mark Qvist
373315423e Updated config file descriptions. Ensure propagation node is disabled by default. 2025-11-01 17:49:39 +01:00
Mark Qvist
025cae6ebf Updated version and dependencies 2025-10-30 14:12:46 +01:00
Mark Qvist
0baebe5a3c Propagation node stamp cost handling 2025-10-30 14:09:12 +01:00
Mark Qvist
3fedd0af30 Added separate LXMF PN message size and sync transfer size limits 2025-10-29 23:19:33 +01:00
Mark Qvist
34e0bde0b4 Updated versions 2025-07-13 15:15:03 +02:00
markqvist
334559a4b6 Merge pull request #77 from tothedaring/patch-1
Update NomadNetworkApp.py
2025-07-13 15:03:50 +02:00
markqvist
cbca0d67b7 Merge pull request #78 from LinuxinaBit/patch-1
Fix Guide description on authenticating users
2025-07-13 15:03:17 +02:00
markqvist
5b0146325e Merge pull request #80 from Erethon/micronparsing-crash
micronparser: Fix a parsing bug
2025-07-13 12:19:46 +02:00
Dionysis Grigoropoulos
b2f48d5853 micronparser: Fix a parsing bug 2025-06-25 23:51:18 +03:00
Linux in a Bit
f0c3b898ae Update Guide.py - Authenticating Users section 2025-05-29 16:50:53 -05:00
tothedaring
bf4b9e55ae added explanation of CUPS variables and added example for reciept printer 2025-05-25 16:01:23 -04:00
tothedaring
2d87214cd0 Update NomadNetworkApp.py
Update line 1271 (line 253 in config file) to reflect current CUPS options and removing deprecated options per issue 4010 (https://github.com/apple/cups/issues/4010)
2025-05-23 14:35:41 -04:00
Mark Qvist
a20b4c9bc3 Added funding 2025-05-17 10:26:59 +02:00
10 changed files with 151 additions and 34 deletions

3
FUNDING.yml Normal file
View File

@@ -0,0 +1,3 @@
liberapay: Reticulum
ko_fi: markqvist
custom: "https://unsigned.io/donate"

View File

@@ -6,6 +6,8 @@ import nomadnet
import threading
import RNS.vendor.umsgpack as msgpack
from LXMF import pn_announce_data_is_valid
class PNAnnounceHandler:
def __init__(self, owner):
self.aspect_filter = "lxmf.propagation"
@@ -13,10 +15,10 @@ class PNAnnounceHandler:
def received_announce(self, destination_hash, announced_identity, app_data):
try:
if type(app_data) == bytes:
if pn_announce_data_is_valid(app_data):
data = msgpack.unpackb(app_data)
if data[0] == True:
if data[2] == 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)
@@ -193,7 +195,8 @@ class Directory:
found_node = True
break
if not found_node:
# TODO: Remove debug and rethink this (needs way to set PN when node is saved)
if True or not found_node:
if self.app.compact_stream:
try:
remove_announces = []

View File

@@ -122,13 +122,16 @@ class NomadNetworkApp:
self.page_refresh_interval = 0
self.file_refresh_interval = 0
self.static_peers = []
self.peer_announce_at_start = True
self.try_propagation_on_fail = True
self.disable_propagation = False
self.disable_propagation = True
self.notify_on_new_message = True
self.lxmf_max_propagation_size = None
self.lxmf_max_sync_size = None
self.lxmf_max_incoming_size = None
self.node_propagation_cost = LXMF.LXMRouter.PROPAGATION_COST
self.periodic_lxmf_sync = True
self.lxmf_sync_interval = 360*60
@@ -302,8 +305,8 @@ class NomadNetworkApp:
self.message_router = LXMF.LXMRouter(
identity = self.identity, storagepath = self.storagepath, autopeer = True,
propagation_limit = self.lxmf_max_propagation_size, delivery_limit = self.lxmf_max_incoming_size,
max_peers = self.max_peers, static_peers = static_peers,
propagation_limit = self.lxmf_max_propagation_size, sync_limit = self.lxmf_max_sync_size, delivery_limit = self.lxmf_max_incoming_size,
max_peers = self.max_peers, static_peers = static_peers, propagation_cost=self.node_propagation_cost
)
self.message_router.register_delivery_callback(self.lxmf_delivery)
@@ -876,7 +879,7 @@ class NomadNetworkApp:
self.node_name = self.config["node"]["node_name"]
if not "disable_propagation" in self.config["node"]:
self.disable_propagation = False
self.disable_propagation = True
else:
self.disable_propagation = self.config["node"].as_bool("disable_propagation")
@@ -888,6 +891,14 @@ class NomadNetworkApp:
value = 1
self.lxmf_max_propagation_size = value
if not "max_sync_size" in self.config["node"]:
self.lxmf_max_sync_size = 256*40
else:
value = self.config["node"].as_float("max_sync_size")
if value < self.lxmf_max_propagation_size:
value = self.lxmf_max_propagation_size
self.lxmf_max_sync_size = value
if not "announce_at_start" in self.config["node"]:
self.node_announce_at_start = False
else:
@@ -901,6 +912,13 @@ class NomadNetworkApp:
if value < 1:
value = 1
self.node_announce_interval = value
if not "propagation_cost" in self.config["node"]:
self.node_propagation_cost = 16
else:
value = self.config["node"].as_int("propagation_cost")
if value < 13: value = 13
self.node_propagation_cost = value
if "pages_path" in self.config["node"]:
self.pagespath = self.config["node"]["pages_path"]
@@ -1162,14 +1180,55 @@ announce_at_start = Yes
# When Nomad Network is hosting a page-serving
# node, it can also act as an LXMF propagation
# node. If there is already a large amount of
# node. This is a convenient feature that lets
# you easily set up and run a propagation node
# on the network, but it is not as fully
# featured as using the lxmd program to host a
# propagation node. For complete control and
# flexibility, use lxmd to run a PN. For a
# small local system or network, the built-in
# PN functionality will suffice for most cases.
#
# If there is already a large amount of
# propagation nodes on the network, or you
# simply want to run a pageserving-only node,
# you can disable running a propagation node.
# you should disable running a propagation node.
# Due to lots of propagation nodes being
# available, this is currently the default.
disable_propagation = Yes
# For clients and other propagation nodes
# delivering messages via this node, you can
# configure the minimum required propagation
# stamp costs. All messages delivered to the
# propagation node network must have a valid
# propagation stamp, or they will be rejected.
# Clients automatically detect the stamp cost
# for the node they are delivering to, and
# compute a corresponding stamp before trying
# to deliver the message to the propagation
# node.
#
# Propagation stamps are easier to verify in
# large batches, and therefore also somewhat
# easier to compute for the senders. As such,
# a reasonable propagation stamp cost should
# be a bit higher than the normal peer-to-peer
# stamp costs.
#
# Propagation stamps does not incur any extra
# load for propagation nodes processing them,
# since they are only required to verify that
# they are correct, and only the generation
# is computationally costly. Setting a sensible
# propagation stamp cost (and periodically
# checking the average network consensus) helps
# keep spam and misuse out of the propagation
# node network.
propagation_cost = 16
# The maximum amount of storage to use for
# the LXMF Propagation Node message store,
# specified in megabytes. When this limit
@@ -1179,19 +1238,26 @@ disable_propagation = Yes
# new and small. Large and old messages will
# be removed first. This setting is optional
# and defaults to 2 gigabytes.
# message_storage_limit = 2000
# The maximum accepted transfer size per in-
# coming propagation transfer, in kilobytes.
# This also sets the upper limit for the size
# of single messages accepted onto this node.
# coming propagation message, in kilobytes.
# This sets the upper limit for the size of
# single messages accepted onto this node.
max_transfer_size = 256
# The maximum accepted transfer size per in-
# coming propagation node sync.
#
# If a node wants to propagate a larger number
# of messages to this node, than what can fit
# within this limit, it will prioritise sending
# the smallest, newest messages first, and try
# the smallest messages first, and try again
# with any remaining messages at a later point.
max_transfer_size = 256
max_sync_size = 10240
# You can tell the LXMF message router to
# prioritise storage for one or more
@@ -1200,29 +1266,34 @@ max_transfer_size = 256
# keeping messages for destinations specified
# with this option. This setting is optional,
# and generally you do not need to use it.
# prioritise_destinations = 41d20c727598a3fbbdf9106133a3a0ed, d924b81822ca24e68e2effea99bcb8cf
# You can configure the maximum number of other
# propagation nodes that this node will peer
# with automatically. The default is 50.
# max_peers = 25
# with automatically. The default is 20.
# max_peers = 20
# You can configure a list of static propagation
# node peers, that this node will always be
# peered with, by specifying a list of
# destination hashes.
# static_peers = e17f833c4ddf8890dd3a79a6fea8161d, 5a2d0029b6e5ec87020abaea0d746da4
# You can specify the interval in minutes for
# rescanning the hosted pages path. By default,
# this option is disabled, and the pages path
# will only be scanned on startup.
# page_refresh_interval = 0
# You can specify the interval in minutes for
# rescanning the hosted files path. By default,
# this option is disabled, and the files path
# will only be scanned on startup.
# file_refresh_interval = 0
[printing]
@@ -1231,6 +1302,7 @@ max_transfer_size = 256
# various kinds of information and messages.
# Printing messages is disabled by default
print_messages = No
# You can configure a custom template for
@@ -1238,37 +1310,64 @@ print_messages = No
# option, set a path to the template and
# restart Nomad Network, a default template
# will be created that you can edit.
# message_template = ~/.nomadnetwork/print_template_msg.txt
# You can configure Nomad Network to only
# print messages from trusted destinations.
# print_from = trusted
# Or specify the source LXMF addresses that
# will automatically have messages printed
# on arrival.
# print_from = 76fe5751a56067d1e84eef3e88eab85b, 0e70b5848eb57c13154154feaeeb89b7
# Or allow printing from anywhere, if you
# are feeling brave and adventurous.
# print_from = everywhere
# You can configure the printing command.
# This will use the default CUPS printer on
# your system.
print_command = lp
# You can specify what printer to use
# print_command = lp -d PRINTER_NAME
# print_command = lp -d [PRINTER_NAME]
# Or specify more advanced options. This
# example works well for small thermal-
# roll printers.
# print_command = lp -d PRINTER_NAME -o cpi=16 -o lpi=8
# roll printers:
# print_command = lp -d [PRINTER_NAME] -o cpi=16 -o lpi=8
# This one is more suitable for full-sheet
# printers.
# print_command = lp -d PRINTER_NAME -o page-left=36 -o page-top=36 -o page-right=36 -o page-bottom=36
# printers. It will print a QR code at the center of any media
# your printer will accept, print in portrait mode, and move the message to
# the top of the print queue:
# print_command = lp -d [PRINTER_NAME] -o job-priority=100 -o media=Custom.75x75mm -o orientation-requested=3
# But you can modify the size to fit your needs.
# The custom media option accepts millimeters, centimeters, and
# inches in a width by length format like so:
# -o media=Custom.[WIDTH]x[LENGTH][mm,cm,in]
#
# The job priority option accepts 1-100, though you can remove it
# entirely if you aren't concerned with a print queue:
# -o job-priority=[1-100]
#
# Finally, the orientation option allows for 90 degree rotations beginning with 3, so:
# -o orientation-requested=4 (landscape, 90 degrees)
# -o orientation-requested=5 (reverse portrait, 180 degrees)
#
# Here is the full command with the recommended customizable variables:
# print_command = lp -d [PRINTER_NAME] -o job-priority=[N] -o media=[MEDIA_SIZE] -o orientation-requested=[N] -o sides=one-sided
# For example, here's a configuration for USB thermal printer that uses the POS-58 PPD driver
# with rolls 47.98x209.9mm in size:
# print_command = lp -d [PRINTER_NAME] -o job-priority=100 -o media=custom_47.98x209.9mm_47.98x209.9mm -o sides=one-sided
'''.splitlines()

View File

@@ -1 +1 @@
__version__ = "0.7.0"
__version__ = "0.9.1"

View File

@@ -697,7 +697,7 @@ class Browser:
def confirmed(sender):
try:
self.retrieve_url(e_url.get_edit_text())
self.retrieve_url(e_url.get_edit_text().strip())
except Exception as e:
self.browser_footer = urwid.Text("Could not open link: "+str(e))
self.frame.contents["footer"] = (self.browser_footer, self.frame.options())

View File

@@ -331,7 +331,7 @@ class ConversationsDisplay():
existing_conversations = nomadnet.Conversation.conversation_list(self.app)
display_name = e_name.get_edit_text()
source_hash_text = e_id.get_edit_text()
source_hash_text = e_id.get_edit_text().strip()
source_hash = bytes.fromhex(source_hash_text)
trust_level = DirectoryEntry.UNTRUSTED
if r_unknown.state == True:
@@ -412,7 +412,7 @@ class ConversationsDisplay():
try:
local_delivery_signal = "local_delivery_occurred"
duplicate_signal = "duplicate_lxm"
lxm_uri = e_uri.get_edit_text()
lxm_uri = e_uri.get_edit_text().strip()
ingest_result = self.app.message_router.ingest_lxm_uri(
lxm_uri,

View File

@@ -345,7 +345,7 @@ By default, you can find the examples in `!~/.nomadnetwork/examples`!. If you bu
Sometimes, you don't want everyone to be able to view certain pages or execute certain scripts. In such cases, you can use `*authentication`* to control who gets to run certain requests.
To enable authentication for any page, simply add a new file to your pages directory with ".allowed" added to the file-name of the page. If your page is named "secret_page.mu", just add a file named "secret_page.allowed".
To enable authentication for any page, simply add a new file to your pages directory with ".allowed" added to the file-name of the page. If your page is named "secret_page.mu", just add a file named "secret_page.mu.allowed".
For each user allowed to access the page, add a line to this file, containing the hash of that users primary identity. Users can find their own identity hash in the `![ Network ]`! part of the program, under `!Local Peer Info`!. If you want to allow access for three different users, your file would look like this:

View File

@@ -148,6 +148,9 @@ def parse_line(line, state, url_delegate):
elif first_char == "-":
if len(line) == 2:
divider_char = line[1]
# Control characters don't make sense here and otherwise crash nomadnet
if ord(divider_char) < 32:
divider_char = "\u2500"
else:
divider_char = "\u2500"
if state["depth"] == 0:

View File

@@ -1843,15 +1843,24 @@ class LXMFPeerEntry(urwid.WidgetWrap):
style = "list_unresponsive"
focus_style = "list_focus_unresponsive"
if peer.propagation_transfer_limit:
txfer_limit = RNS.prettysize(peer.propagation_transfer_limit*1000)
else:
txfer_limit = "No"
if peer.propagation_transfer_limit: txfer_limit = RNS.prettysize(peer.propagation_transfer_limit*1000)
else: txfer_limit = "No"
if peer.propagation_sync_limit: sync_limit = RNS.prettysize(peer.propagation_sync_limit*1000)
else: sync_limit = "Unknown"
if peer.propagation_stamp_cost: sct = peer.propagation_stamp_cost
else: sct = "Unknown"
if peer.propagation_stamp_cost_flexibility: scf = f" (flex {peer.propagation_stamp_cost_flexibility})"
else: scf = ""
ar = round(peer.acceptance_rate*100, 2)
peer_info_str = sym+" "+display_str+"\n "+alive_string+", last heard "+pretty_date(int(peer.last_heard))
peer_info_str += "\n "+str(peer.unhandled_message_count)+f" unhandled LXMs, {txfer_limit} sync limit\n"
peer_info_str += f" {RNS.prettyspeed(peer.sync_transfer_rate)} STR, "
peer_info_str += f"{RNS.prettyspeed(peer.link_establishment_rate)} LER, {ar}% AR\n"
peer_info_str += f"\n {sync_limit} sync limit, {txfer_limit} msg limit"
peer_info_str += f"\n {RNS.prettyspeed(peer.sync_transfer_rate)} STR, {RNS.prettyspeed(peer.link_establishment_rate)} LER"
peer_info_str += f"\n Propagation cost {sct}{scf}"
peer_info_str += "\n "+str(peer.unhandled_message_count)+f" unhandled LXMs, {ar}% AR"
widget = ListEntry(peer_info_str)
self.display_widget = urwid.AttrMap(widget, style, focus_style)
self.display_widget.destination_hash = destination_hash

View File

@@ -30,6 +30,6 @@ setuptools.setup(
entry_points= {
'console_scripts': ['nomadnet=nomadnet.nomadnet:main']
},
install_requires=["rns>=0.9.6", "lxmf>=0.7.1", "urwid>=2.6.16", "qrcode"],
install_requires=["rns>=1.0.1", "lxmf>=0.9.1", "urwid>=2.6.16", "qrcode"],
python_requires=">=3.7",
)