Compare commits

..

6 Commits

Author SHA1 Message Date
Mark Qvist
dd33483cbd Versions 2026-01-06 17:48:17 +01:00
Mark Qvist
97709058b0 Cleanup 2026-01-06 17:18:40 +01:00
Mark Qvist
70baa59ac2 Updated versions 2026-01-04 01:05:29 +01:00
Mark Qvist
29b6255746 Avoid running stat updater multiple time. Run stat updates non-blocking. 2026-01-02 00:45:46 +01:00
Mark Qvist
f75d25f857 Updated version 2025-12-30 12:41:53 +01:00
Mark Qvist
237d56059d Markup handling improvements 2025-12-30 12:16:24 +01:00
6 changed files with 31 additions and 13 deletions

View File

@@ -173,7 +173,7 @@ class Node:
if isinstance(e, str) and (e.startswith("field_") or e.startswith("var_")): if isinstance(e, str) and (e.startswith("field_") or e.startswith("var_")):
env_map[e] = data[e] env_map[e] = data[e]
generated = subprocess.run([file_path], stdout=subprocess.PIPE, env=env_map) generated = subprocess.run([file_path], stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, env=env_map)
return generated.stdout return generated.stdout
else: else:
fh = open(file_path, "rb") fh = open(file_path, "rb")

View File

@@ -1 +1 @@
__version__ = "0.9.5" __version__ = "0.9.7"

View File

@@ -1040,7 +1040,8 @@ class Browser:
fg = self.markup[fgpos+5:endpos] fg = self.markup[fgpos+5:endpos]
self.page_foreground_color = fg self.page_foreground_color = fg
self.attr_maps = markup_to_attrmaps(strip_modifiers(self.markup), url_delegate=self, fg_color=self.page_foreground_color, bg_color=self.page_background_color) try: self.attr_maps = markup_to_attrmaps(strip_modifiers(self.markup), url_delegate=self, fg_color=self.page_foreground_color, bg_color=self.page_background_color)
except Exception as e: self.attr_maps = [urwid.AttrMap(urwid.Text(f"Could not render page: {e}"), "inactive_text")]
self.response_progress = 0 self.response_progress = 0
self.response_speed = None self.response_speed = None
@@ -1080,7 +1081,7 @@ class Browser:
if "PATH" in os.environ: if "PATH" in os.environ:
env_map["PATH"] = os.environ["PATH"] env_map["PATH"] = os.environ["PATH"]
generated = subprocess.run([page_path], stdout=subprocess.PIPE, env=env_map) generated = subprocess.run([page_path], stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, env=env_map)
page_data = generated.stdout page_data = generated.stdout
else: else:
file = open(page_path, "rb") file = open(page_path, "rb")
@@ -1107,7 +1108,8 @@ class Browser:
fg = self.markup[fgpos+5:endpos] fg = self.markup[fgpos+5:endpos]
self.page_foreground_color = fg self.page_foreground_color = fg
self.attr_maps = markup_to_attrmaps(strip_modifiers(self.markup), url_delegate=self, fg_color=self.page_foreground_color, bg_color=self.page_background_color) try: self.attr_maps = markup_to_attrmaps(strip_modifiers(self.markup), url_delegate=self, fg_color=self.page_foreground_color, bg_color=self.page_background_color)
except Exception as e: self.attr_maps = [urwid.AttrMap(urwid.Text(f"Could not render page: {e}"), "inactive_text")]
self.response_progress = 0 self.response_progress = 0
self.response_speed = None self.response_speed = None
@@ -1259,7 +1261,9 @@ class Browser:
fg = self.markup[fgpos+5:endpos] fg = self.markup[fgpos+5:endpos]
self.page_foreground_color = fg self.page_foreground_color = fg
self.attr_maps = markup_to_attrmaps(strip_modifiers(self.markup), url_delegate=self, fg_color=self.page_foreground_color, bg_color=self.page_background_color) try: self.attr_maps = markup_to_attrmaps(strip_modifiers(self.markup), url_delegate=self, fg_color=self.page_foreground_color, bg_color=self.page_background_color)
except Exception as e: self.attr_maps = [urwid.AttrMap(urwid.Text(f"Could not render page: {e}"), "inactive_text")]
self.response_progress = 0 self.response_progress = 0
self.response_speed = None self.response_speed = None
self.progress_updated_at = None self.progress_updated_at = None

View File

@@ -1,6 +1,7 @@
import RNS import RNS
import time import time
import nomadnet import nomadnet
import threading
from math import log10, pow from math import log10, pow
from nomadnet.vendor.additional_urwid_widgets.FormWidgets import * from nomadnet.vendor.additional_urwid_widgets.FormWidgets import *
@@ -2226,7 +2227,7 @@ class ShowInterface(urwid.WidgetWrap):
self.history_length = screen_cols-(margin+2) self.history_length = screen_cols-(margin+2)
# get interface stats # get interface stats
interface_stats = self.parent.app.rns.get_interface_stats() interface_stats = self.parent.app.interface_stats
stats_lookup = {iface['short_name']: iface for iface in interface_stats['interfaces']} stats_lookup = {iface['short_name']: iface for iface in interface_stats['interfaces']}
self.stats = stats_lookup.get(iface_name, {}) self.stats = stats_lookup.get(iface_name, {})
@@ -2758,7 +2759,7 @@ class ShowInterface(urwid.WidgetWrap):
return return
try: try:
interface_stats = self.parent.app.rns.get_interface_stats() interface_stats = self.parent.app.interface_stats
stats_lookup = {iface['short_name']: iface for iface in interface_stats['interfaces']} stats_lookup = {iface['short_name']: iface for iface in interface_stats['interfaces']}
stats = stats_lookup.get(self.iface_name, {}) stats = stats_lookup.get(self.iface_name, {})
@@ -2825,6 +2826,8 @@ class InterfaceDisplay:
def __init__(self, app): def __init__(self, app):
self.app = app self.app = app
self.started = False self.started = False
self.poll_scheduler = False
self.size_scheduler = False
self.interface_items = [] self.interface_items = []
self.glyphset = self.app.config["textui"]["glyphs"] self.glyphset = self.app.config["textui"]["glyphs"]
self.g = self.app.ui.glyphs self.g = self.app.ui.glyphs
@@ -2857,7 +2860,8 @@ class InterfaceDisplay:
processed_interfaces[interface_name] = interface_data processed_interfaces[interface_name] = interface_data
interface_stats = app.rns.get_interface_stats() app.interface_stats = app.rns.get_interface_stats()
interface_stats = app.interface_stats
stats_lookup = {interface['short_name']: interface for interface in interface_stats['interfaces']} stats_lookup = {interface['short_name']: interface for interface in interface_stats['interfaces']}
# print(stats_lookup) # print(stats_lookup)
for interface_name, interface_data in processed_interfaces.items(): for interface_name, interface_data in processed_interfaces.items():
@@ -2916,8 +2920,8 @@ class InterfaceDisplay:
def start(self): def start(self):
# started from Main.py # started from Main.py
self.started = True self.started = True
self.app.ui.loop.set_alarm_in(1, self.poll_stats) if not self.poll_scheduler: self.app.ui.loop.set_alarm_in(1, self.poll_stats)
self.app.ui.loop.set_alarm_in(5, self.check_terminal_size) if not self.size_scheduler: self.app.ui.loop.set_alarm_in(5, self.check_terminal_size)
def switch_to_edit_interface(self, iface_name): def switch_to_edit_interface(self, iface_name):
self.edit_interface_view = EditInterfaceView(self, iface_name) self.edit_interface_view = EditInterfaceView(self, iface_name)
@@ -2936,6 +2940,7 @@ class InterfaceDisplay:
self.switch_to_edit_interface(interface_name) self.switch_to_edit_interface(interface_name)
def check_terminal_size(self, loop, user_data): def check_terminal_size(self, loop, user_data):
self.size_scheduler = True
new_cols, new_rows = _get_cols_rows() new_cols, new_rows = _get_cols_rows()
if new_rows != self.terminal_rows or new_cols != self.terminal_cols: if new_rows != self.terminal_rows or new_cols != self.terminal_cols:
@@ -2950,12 +2955,15 @@ class InterfaceDisplay:
loop.set_alarm_in(5, self.check_terminal_size) loop.set_alarm_in(5, self.check_terminal_size)
def poll_stats(self, loop, user_data): def poll_stats(self, loop, user_data):
self.poll_scheduler = True
try: try:
if hasattr(self, 'disconnect_overlay') and self.widget is self.disconnect_overlay: if hasattr(self, 'disconnect_overlay') and self.widget is self.disconnect_overlay:
self.widget = self.interfaces_display self.widget = self.interfaces_display
self.app.ui.main_display.update_active_sub_display() self.app.ui.main_display.update_active_sub_display()
interface_stats = self.app.rns.get_interface_stats() def job(): self.app.interface_stats = self.app.rns.get_interface_stats()
threading.Thread(target=job, daemon=True).start()
interface_stats = self.app.interface_stats
stats_lookup = {iface['short_name']: iface for iface in interface_stats['interfaces']} stats_lookup = {iface['short_name']: iface for iface in interface_stats['interfaces']}
for item in self.interface_items: for item in self.interface_items:
# use interface name as the key # use interface name as the key

View File

@@ -146,6 +146,12 @@ def parse_line(line, state, url_delegate):
# Only parse content if not in literal state # Only parse content if not in literal state
if not state["literal"]: if not state["literal"]:
# Apply markup sanitization
if first_char == ">" and "`<" in line:
# Remove heading status from lines containing fields
line = line.lstrip(">")
first_char = line[0]
# Check if the command is an escape # Check if the command is an escape
if first_char == "\\": if first_char == "\\":
line = line[1:] line = line[1:]

View File

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