diff --git a/pages/chat.mu b/pages/chat.mu index 311bf5c..69ff8a6 100755 --- a/pages/chat.mu +++ b/pages/chat.mu @@ -50,6 +50,6 @@ for msg in reversed(r.lrange(CHAT_NAME, 0, -1)): delbtn = "" if hswro.is_admin(): delbtn = f"`B400`FAAA`!`[DEL`:/page/chat.mu`delete={m['id']}]`!" - print(f"{delbtn}`BCCC`F333{m['when']}`BAAA`F444{'<'+m['who']+'>':>16}`B333`FCCC{m['msg']}") + print(f"{delbtn}`BCCC`F333{m['when']}`BAAA`F444{'<'+m['who']+'>':>16}`B888`F000{m['msg']}") hswro.reset_colors() hswro.footer() diff --git a/pages/hswro.py b/pages/hswro.py index 683e719..f57fcbd 100755 --- a/pages/hswro.py +++ b/pages/hswro.py @@ -19,11 +19,18 @@ FORBIDDEN_INPUT = [ "\n" ] +MENU_ITEMS = [ + ("Home", "/page/index.mu]"), + ("Status", "/page/status.mu"), + ("Shoutbox", "/page/chat.mu]") +] + ADMIN_IDENTITIES = [ "e6c72573bb91d48338dbcc57d0223b81", "70c9608c9a0f4ae895f7fab406554e1c" ] BGCOLOR = "`F333`BDDD" +MENUBGCOLOR = "`FEEE`B333" def is_admin() -> bool: remote_identity = environ.get("remote_identity", None) @@ -80,37 +87,52 @@ def login_button() -> str: return "[`[Identify`:/page/login.mu`]]" else: return f"Welcome, {l[0]} | [`[Forget`:/page/logout.mu`]]" + +def render_menu_item(active_title: Optional[str]) -> str: + def f(current: Tuple[str, str]) -> str: + current_title = current[0] + href = current[1] + retval = " " + if current_title == active_title: + retval += "`!" + retval += f"`[{current_title}`:{href}`]" + if current_title == active_title: + retval += "`!" + return retval + " " + return f + +def render_menu(title: Optional[str] = None) -> str: + LEFT_MARGIN = 2 + retval = "\n`l" + " "*LEFT_MARGIN + retval += "│".join(map(render_menu_item(title), MENU_ITEMS)) + retval += "\n" + return retval + def header(title: Optional[str] = None): - if title is None: - title = "" - else: - title = ": `i" + title + ftitle = "" + if title is not None: + ftitle = ": `i" + title print(f"""`F000`BFB1 `c --*abc -`r {login_button()} -`l `!Hackerspace`!Wrocław{title} + +`r {login_button()} +`l `!Hackerspace`!Wrocław{ftitle} `a --_ + `a `` -`FEEE`B333 +{MENUBGCOLOR} `c - -`l `[Home`:/page/index.mu]` | `[Status`:/page/status.mu]` | `[Shoutbox`:/page/chat.mu]` - -`a -`` -{BGCOLOR} -""") +{render_menu(title)} +{BGCOLOR}""") def reset_colors() -> str: print(BGCOLOR) def footer(): - print(f"{BGCOLOR}`r Rendered in: {(datetime.now()-s).total_seconds()}s") + print(f"\n{BGCOLOR}`r Rendered in: {(datetime.now()-s).total_seconds()}s") print(f"{datetime.now()}") if __name__ == "__main__": diff --git a/pages/index.mu b/pages/index.mu index 2e378fa..e99b087 100755 --- a/pages/index.mu +++ b/pages/index.mu @@ -2,6 +2,6 @@ import hswro -hswro.header() +hswro.header("Home") print("Nothing to see here... yet") hswro.footer() diff --git a/pages/library.mu b/pages/library.mu new file mode 100755 index 0000000..27dc975 --- /dev/null +++ b/pages/library.mu @@ -0,0 +1,49 @@ +#!/usr/bin/env python3 + +import hswro +import os +from pathlib import PurePosixPath +from typing import List +from os import environ + +LIBRARY_DIR = "/home/reticulum/library" + +library_contents = [""] + + +def get_from_list(l: List[str], i: int) -> str: + try: + return l[i] + except IndexError: + return "" + + +with os.scandir(LIBRARY_DIR) as it: + for entry in it: + if not entry.name.startswith('.') and entry.is_file(): + library_contents.append(PurePosixPath(entry.path).stem) + +content_lines = ["", "Select a file to begin reading."] + +if "var_view" in environ: + document_name = environ["var_view"] + if len(document_name) > 20: + raise ValueError("Document name is too long, rejecting") + if not all(map(lambda c: c.isalnum(), document_name)): + raise ValueError("Document name contains not allowed characters, rejecting") + content_lines = [] + with open(f"{LIBRARY_DIR}/{document_name}.txt") as file: + content_lines = [line.rstrip() for line in file] + +page_len = max(len(library_contents), len(content_lines)) + 2 + +hswro.header("Library") +for i in range(page_len): + menuitem = " "*23 + item_name = get_from_list(library_contents, i) + if item_name != "": + menuitem = f" `[{item_name:<20}`:/page/library.mu`view={item_name}] " + content = get_from_list(content_lines, i) + print(f"{hswro.MENUBGCOLOR}{menuitem}{hswro.BGCOLOR} {content}") +print("-.") +hswro.footer() diff --git a/pages/login.mu b/pages/login.mu index a271c92..7b00f9e 100755 --- a/pages/login.mu +++ b/pages/login.mu @@ -4,10 +4,10 @@ import hswro from os import environ def login_form(): - print("`c `!Login:`") - print("Username: `<16|username`>") - print("Password: `") - print("[`[Submit`:/page/login.mu`*]]") + print(" `!Login:`") + print(f" Username: `BFFF`F000`<16|username`>{hswro.BGCOLOR}") + print(f" Password: `BFFF`F000`{hswro.BGCOLOR}") + print(" [`[Submit`:/page/login.mu`*]]") l = hswro.get_login_info() form_login = environ.get('field_username', None) @@ -26,6 +26,5 @@ if l[0] is None: login_form() else: print(f"Welcome, {l[0]}.") -#print("`l\n\n\n\n\n") -#print(environ) + hswro.footer() diff --git a/pages/status.mu b/pages/status.mu index fa7f654..423055c 100755 --- a/pages/status.mu +++ b/pages/status.mu @@ -6,6 +6,8 @@ import subprocess import json import hswro +UNIT_STATUS_ALLOWED_LINES = ["Active:", "Tasks:", "Memory:", "CPU:"] + def sizeof_fmt(num, suffix="B"): for unit in ("", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi"): if abs(num) < 1024.0: @@ -13,16 +15,38 @@ def sizeof_fmt(num, suffix="B"): num /= 1024.0 return f"{num:.1f}Yi{suffix}" +def systemd_unit_status(unit_name: str): + unit_status_raw = subprocess.run(["systemctl", "status", unit_name], capture_output=True) + for allowed in UNIT_STATUS_ALLOWED_LINES: + for line in unit_status_raw.stdout.splitlines(): + line = line.decode('utf-8') + if allowed in line: + print(line) + +def get_temp(): + with open("/sys/class/thermal/thermal_zone0/temp", "r") as f: + t = f.read() + t = float(t) / 1000 + print(f" CPU Temp: {t:.1f}°C") status_raw = subprocess.run(["/home/reticulum/venv/bin/rnstatus", "-j"], capture_output=True) status = json.loads(status_raw.stdout) -hswro.header("Node Status") +hswro.header("Status") + +get_temp() +print(subprocess.run(["uptime"], capture_output=True).stdout.decode('utf-8')) +print("> Service status") +print(">> rnst status") +systemd_unit_status("rnsd") +print(">> nomadnet status") +systemd_unit_status("nomadnet") + print("> Interfaces") for i in status['interfaces']: print(">> ", i['short_name']) - print("`!Clients:`! ", i['clients']) + print("`!Clients:`! ", i['clients']) print("`!Current RX:`! ", i['rxs']) print("`!Current TX:`! ", i['txs']) print("`!Total RX:`! ", sizeof_fmt(i['rxb']))