ruff fixes and formatting

This commit is contained in:
2025-11-16 00:46:42 -06:00
parent 3cddaeb2b9
commit 5ec677437e
13 changed files with 244 additions and 122 deletions

View File

@@ -93,40 +93,41 @@ async def main(page: Page):
def reload_reticulum(page: Page, on_complete=None):
"""Hot reload Reticulum with updated configuration.
Args:
page: Flet page instance
on_complete: Optional callback to run when reload is complete
"""
def reload_thread():
import time
try:
global RNS_INSTANCE
if RNS_INSTANCE:
try:
RNS_INSTANCE.exit_handler()
print("RNS exit handler completed")
except Exception as e:
print(f"Warning during RNS shutdown: {e}")
RNS.Reticulum._Reticulum__instance = None
RNS.Transport.destinations = []
RNS_INSTANCE = None
print("RNS instance cleared")
time.sleep(0.5)
# Initialize storage system
storage = initialize_storage(page)
# Get Reticulum config directory from storage manager
config_dir = storage.get_reticulum_config_path()
# Ensure any saved config is written to filesystem before RNS init
try:
saved_config = storage.load_config()
@@ -136,27 +137,28 @@ def reload_reticulum(page: Page, on_complete=None):
config_file_path.write_text(saved_config, encoding="utf-8")
except Exception as e:
print(f"Warning: Failed to write config file: {e}")
try:
# Re-initialize Reticulum
import ren_browser.logs
ren_browser.logs.setup_rns_logging()
RNS_INSTANCE = RNS.Reticulum(str(config_dir))
# Success
if on_complete:
on_complete(True, None)
except Exception as e:
print(f"Error reinitializing Reticulum: {e}")
if on_complete:
on_complete(False, str(e))
except Exception as e:
print(f"Error during reload: {e}")
if on_complete:
on_complete(False, str(e))
page.run_thread(reload_thread)
@@ -172,10 +174,17 @@ def run():
help="Select renderer (plaintext or micron)",
)
parser.add_argument(
"-w", "--web", action="store_true", help="Launch in web browser mode",
"-w",
"--web",
action="store_true",
help="Launch in web browser mode",
)
parser.add_argument(
"-p", "--port", type=int, default=None, help="Port for web server",
"-p",
"--port",
type=int,
default=None,
help="Port for web server",
)
parser.add_argument(
"-c",

View File

@@ -22,7 +22,7 @@ def hex_to_rgb(hex_color: str) -> str:
def parse_micron_line(line: str) -> list:
"""Parse a single line of micron markup into styled text spans.
Returns list of dicts with 'text', 'bold', 'italic', 'underline', 'color', 'bgcolor'.
"""
spans = []
@@ -37,14 +37,16 @@ def parse_micron_line(line: str) -> list:
while i < len(line):
if line[i] == "`" and i + 1 < len(line):
if current_text:
spans.append({
"text": current_text,
"bold": bold,
"italic": italic,
"underline": underline,
"color": color,
"bgcolor": bgcolor,
})
spans.append(
{
"text": current_text,
"bold": bold,
"italic": italic,
"underline": underline,
"color": color,
"bgcolor": bgcolor,
}
)
current_text = ""
tag = line[i + 1]
@@ -59,13 +61,13 @@ def parse_micron_line(line: str) -> list:
underline = not underline
i += 2
elif tag == "F" and i + 5 <= len(line):
color = hex_to_rgb(line[i+2:i+5])
color = hex_to_rgb(line[i + 2 : i + 5])
i += 5
elif tag == "f":
color = None
i += 2
elif tag == "B" and i + 5 <= len(line):
bgcolor = hex_to_rgb(line[i+2:i+5])
bgcolor = hex_to_rgb(line[i + 2 : i + 5])
i += 5
elif tag == "b":
bgcolor = None
@@ -85,21 +87,23 @@ def parse_micron_line(line: str) -> list:
i += 1
if current_text:
spans.append({
"text": current_text,
"bold": bold,
"italic": italic,
"underline": underline,
"color": color,
"bgcolor": bgcolor,
})
spans.append(
{
"text": current_text,
"bold": bold,
"italic": italic,
"underline": underline,
"color": color,
"bgcolor": bgcolor,
}
)
return spans
def render_micron(content: str, on_link_click=None) -> ft.Control:
"""Render micron markup content to a Flet control.
Falls back to plaintext renderer if parsing fails.
Args:
@@ -119,7 +123,7 @@ def render_micron(content: str, on_link_click=None) -> ft.Control:
def _render_micron_internal(content: str, on_link_click=None) -> ft.Control:
"""Internal micron rendering implementation.
Args:
content: Micron markup content to render.
on_link_click: Optional callback function(url) called when a link is clicked.
@@ -186,23 +190,23 @@ def _render_micron_internal(content: str, on_link_click=None) -> ft.Control:
if "`[" in line:
row_controls = []
remaining = line
last_end = 0
for link_match in re.finditer(r"`\[([^`]*)`([^\]]*)\]", line):
before = line[last_end:link_match.start()]
before = line[last_end : link_match.start()]
if before:
before_spans = parse_micron_line(before)
for span in before_spans:
row_controls.append(create_text_span(span))
label = link_match.group(1)
url = link_match.group(2)
def make_link_handler(link_url):
def handler(e):
if on_link_click:
on_link_click(link_url)
return handler
row_controls.append(
@@ -215,9 +219,9 @@ def _render_micron_internal(content: str, on_link_click=None) -> ft.Control:
on_click=make_link_handler(url),
),
)
last_end = link_match.end()
after = line[last_end:]
if after:
after_spans = parse_micron_line(after)

View File

@@ -51,9 +51,7 @@ class StorageManager:
elif "APPDATA" in os.environ: # Windows
storage_dir = pathlib.Path(os.environ["APPDATA"]) / "ren_browser"
elif "XDG_CONFIG_HOME" in os.environ: # Linux XDG standard
storage_dir = (
pathlib.Path(os.environ["XDG_CONFIG_HOME"]) / "ren_browser"
)
storage_dir = pathlib.Path(os.environ["XDG_CONFIG_HOME"]) / "ren_browser"
else:
storage_dir = pathlib.Path.home() / ".ren_browser"
@@ -126,7 +124,8 @@ class StorageManager:
if self.page and hasattr(self.page, "client_storage"):
self.page.client_storage.set("ren_browser_config", config_content)
self.page.client_storage.set(
"ren_browser_config_error", f"File save failed: {error}",
"ren_browser_config_error",
f"File save failed: {error}",
)
return True
@@ -193,7 +192,8 @@ class StorageManager:
if self.page and hasattr(self.page, "client_storage"):
self.page.client_storage.set(
"ren_browser_bookmarks", json.dumps(bookmarks),
"ren_browser_bookmarks",
json.dumps(bookmarks),
)
return True
@@ -258,7 +258,9 @@ class StorageManager:
json.dump(settings, f, indent=2)
if self.page and hasattr(self.page, "client_storage"):
self.page.client_storage.set("ren_browser_settings", json.dumps(settings))
self.page.client_storage.set(
"ren_browser_settings", json.dumps(settings)
)
return True
except Exception:
@@ -270,7 +272,7 @@ class StorageManager:
"horizontal_scroll": False,
"page_bgcolor": "#000000",
}
try:
settings_path = self._storage_dir / "settings.json"
if settings_path.exists():

View File

@@ -32,10 +32,10 @@ class TabsManager:
self.page = page
self.page.on_resize = self._on_resize
self.manager = SimpleNamespace(tabs=[], index=0)
storage = get_storage_manager(page)
self.settings = storage.load_app_settings()
self.tab_bar = ft.Container(
content=ft.Row(
spacing=6,
@@ -60,7 +60,9 @@ class TabsManager:
self._on_tab_go(None, 0)
default_content = (
render_micron("Welcome to Ren Browser", on_link_click=handle_link_click_home)
render_micron(
"Welcome to Ren Browser", on_link_click=handle_link_click_home
)
if app_module.RENDERER == "micron"
else render_plaintext("Welcome to Ren Browser")
)
@@ -96,16 +98,16 @@ class TabsManager:
self.settings = settings
bgcolor = settings.get("page_bgcolor", "#000000")
self.content_container.bgcolor = bgcolor
horizontal_scroll = settings.get("horizontal_scroll", False)
scroll_mode = ft.ScrollMode.ALWAYS if horizontal_scroll else ft.ScrollMode.AUTO
for tab in self.manager.tabs:
if "content" in tab and hasattr(tab["content"], "scroll"):
tab["content"].scroll = scroll_mode
if "content_control" in tab and hasattr(tab["content_control"], "scroll"):
tab["content_control"].scroll = scroll_mode
if self.content_container.content:
self.content_container.content.update()
self.page.update()
@@ -127,7 +129,9 @@ class TabsManager:
cumulative_width = 0
visible_tabs_count = 0
tab_containers = [c for c in self.tab_bar.content.controls if isinstance(c, ft.Container)]
tab_containers = [
c for c in self.tab_bar.content.controls if isinstance(c, ft.Container)
]
for i, tab in enumerate(self.manager.tabs):
estimated_width = len(tab["title"]) * 10 + 32 + self.tab_bar.content.spacing
@@ -183,7 +187,7 @@ class TabsManager:
content_control = content
horizontal_scroll = self.settings.get("horizontal_scroll", False)
scroll_mode = ft.ScrollMode.ALWAYS if horizontal_scroll else ft.ScrollMode.AUTO
tab_content = ft.Column(
expand=True,
scroll=scroll_mode,
@@ -254,13 +258,17 @@ class TabsManager:
return
idx = self.manager.index
tab_containers = [c for c in self.tab_bar.content.controls if isinstance(c, ft.Container)]
tab_containers = [
c for c in self.tab_bar.content.controls if isinstance(c, ft.Container)
]
control_to_remove = tab_containers[idx]
self.manager.tabs.pop(idx)
self.tab_bar.content.controls.remove(control_to_remove)
updated_tab_containers = [c for c in self.tab_bar.content.controls if isinstance(c, ft.Container)]
updated_tab_containers = [
c for c in self.tab_bar.content.controls if isinstance(c, ft.Container)
]
for i, control in enumerate(updated_tab_containers):
control.on_click = lambda e, i=i: self.select_tab(i) # type: ignore
@@ -278,7 +286,9 @@ class TabsManager:
"""
self.manager.index = idx
tab_containers = [c for c in self.tab_bar.content.controls if isinstance(c, ft.Container)]
tab_containers = [
c for c in self.tab_bar.content.controls if isinstance(c, ft.Container)
]
for i, control in enumerate(tab_containers):
if i == idx:
control.bgcolor = ft.Colors.BLUE_900
@@ -296,7 +306,7 @@ class TabsManager:
url = tab["url_field"].value.strip()
if not url:
return
placeholder_text = f"Loading content for {url}..."
import ren_browser.app as app_module
@@ -330,12 +340,12 @@ class TabsManager:
def fetch_and_update():
parts = url.split(":", 1)
if len(parts) != 2:
result = f"Error: Invalid URL format. Expected format: hash:/page/path"
result = "Error: Invalid URL format. Expected format: hash:/page/path"
page_path = ""
else:
dest_hash = parts[0]
page_path = parts[1] if parts[1].startswith("/") else f"/{parts[1]}"
req = PageRequest(destination_hash=dest_hash, page_path=page_path)
page_fetcher = PageFetcher()
try:
@@ -343,7 +353,7 @@ class TabsManager:
except Exception as ex:
app_module.log_error(str(ex))
result = f"Error: {ex}"
try:
tab = self.manager.tabs[idx]
except IndexError:
@@ -353,7 +363,7 @@ class TabsManager:
new_control = render_micron(result, on_link_click=handle_link_click)
else:
new_control = render_plaintext(result)
tab["content_control"] = new_control
tab["content"].controls[0] = new_control
if self.manager.index == idx:

View File

@@ -77,8 +77,15 @@ def open_settings_tab(page: ft.Page, tab_manager):
snack = ft.SnackBar(
content=ft.Row(
controls=[
ft.Icon(ft.Icons.CHECK_CIRCLE, color=ft.Colors.GREEN_400, size=20),
ft.Text("Configuration saved! Restart app to apply changes.", color=ft.Colors.WHITE),
ft.Icon(
ft.Icons.CHECK_CIRCLE,
color=ft.Colors.GREEN_400,
size=20,
),
ft.Text(
"Configuration saved! Restart app to apply changes.",
color=ft.Colors.WHITE,
),
],
tight=True,
),
@@ -93,7 +100,9 @@ def open_settings_tab(page: ft.Page, tab_manager):
content=ft.Row(
controls=[
ft.Icon(ft.Icons.ERROR, color=ft.Colors.RED_400, size=20),
ft.Text("Failed to save configuration", color=ft.Colors.WHITE),
ft.Text(
"Failed to save configuration", color=ft.Colors.WHITE
),
],
tight=True,
),
@@ -127,7 +136,9 @@ def open_settings_tab(page: ft.Page, tab_manager):
content=ft.Row(
controls=[
ft.Icon(ft.Icons.ERROR, color=ft.Colors.RED_400, size=20),
ft.Text("Failed to save configuration", color=ft.Colors.WHITE),
ft.Text(
"Failed to save configuration", color=ft.Colors.WHITE
),
],
tight=True,
),
@@ -138,11 +149,16 @@ def open_settings_tab(page: ft.Page, tab_manager):
snack.open = True
page.update()
return
loading_snack = ft.SnackBar(
content=ft.Row(
controls=[
ft.ProgressRing(width=16, height=16, stroke_width=2, color=ft.Colors.BLUE_400),
ft.ProgressRing(
width=16,
height=16,
stroke_width=2,
color=ft.Colors.BLUE_400,
),
ft.Text("Reloading Reticulum...", color=ft.Colors.WHITE),
],
tight=True,
@@ -153,17 +169,24 @@ def open_settings_tab(page: ft.Page, tab_manager):
page.overlay.append(loading_snack)
loading_snack.open = True
page.update()
def on_reload_complete(success, error):
loading_snack.open = False
page.update()
if success:
snack = ft.SnackBar(
content=ft.Row(
controls=[
ft.Icon(ft.Icons.CHECK_CIRCLE, color=ft.Colors.GREEN_400, size=20),
ft.Text("Reticulum reloaded successfully!", color=ft.Colors.WHITE),
ft.Icon(
ft.Icons.CHECK_CIRCLE,
color=ft.Colors.GREEN_400,
size=20,
),
ft.Text(
"Reticulum reloaded successfully!",
color=ft.Colors.WHITE,
),
],
tight=True,
),
@@ -174,8 +197,12 @@ def open_settings_tab(page: ft.Page, tab_manager):
snack = ft.SnackBar(
content=ft.Row(
controls=[
ft.Icon(ft.Icons.ERROR, color=ft.Colors.RED_400, size=20),
ft.Text(f"Reload failed: {error}", color=ft.Colors.WHITE),
ft.Icon(
ft.Icons.ERROR, color=ft.Colors.RED_400, size=20
),
ft.Text(
f"Reload failed: {error}", color=ft.Colors.WHITE
),
],
tight=True,
),
@@ -185,10 +212,11 @@ def open_settings_tab(page: ft.Page, tab_manager):
page.overlay.append(snack)
snack.open = True
page.update()
import ren_browser.app as app_module
app_module.reload_reticulum(page, on_reload_complete)
except Exception as ex:
snack = ft.SnackBar(
content=ft.Row(
@@ -217,8 +245,15 @@ def open_settings_tab(page: ft.Page, tab_manager):
snack = ft.SnackBar(
content=ft.Row(
controls=[
ft.Icon(ft.Icons.CHECK_CIRCLE, color=ft.Colors.GREEN_400, size=20),
ft.Text("Appearance settings saved and applied!", color=ft.Colors.WHITE),
ft.Icon(
ft.Icons.CHECK_CIRCLE,
color=ft.Colors.GREEN_400,
size=20,
),
ft.Text(
"Appearance settings saved and applied!",
color=ft.Colors.WHITE,
),
],
tight=True,
),
@@ -233,7 +268,10 @@ def open_settings_tab(page: ft.Page, tab_manager):
content=ft.Row(
controls=[
ft.Icon(ft.Icons.ERROR, color=ft.Colors.RED_400, size=20),
ft.Text("Failed to save appearance settings", color=ft.Colors.WHITE),
ft.Text(
"Failed to save appearance settings",
color=ft.Colors.WHITE,
),
],
tight=True,
),
@@ -410,7 +448,14 @@ def open_settings_tab(page: ft.Page, tab_manager):
nav_card = ft.Container(
content=ft.Row(
controls=[btn_config, btn_appearance, btn_errors, btn_ret, btn_storage, btn_refresh],
controls=[
btn_config,
btn_appearance,
btn_errors,
btn_ret,
btn_storage,
btn_refresh,
],
spacing=8,
wrap=True,
),

View File

@@ -84,7 +84,9 @@ def build_ui(page: Page):
tab_manager._on_tab_go(None, idx)
if req.page_path.endswith(".mu"):
new_control = render_micron(result, on_link_click=handle_link_click)
new_control = render_micron(
result, on_link_click=handle_link_click
)
else:
new_control = render_plaintext(result)
tab["content_control"] = new_control