mirror of
https://github.com/markqvist/Reticulum.git
synced 2026-06-08 22:21:54 -07:00
Improved rngit page rendering
This commit is contained in:
@@ -38,18 +38,9 @@ from RNS.Utilities.rngit.util import MarkdownToMicron
|
||||
from RNS.vendor.configobj import ConfigObj
|
||||
from RNS._version import __version__
|
||||
|
||||
DEFAULT_TEMPLATE = """#!c=0
|
||||
>{NODE_NAME}
|
||||
|
||||
{PAGE_CONTENT}
|
||||
<
|
||||
-
|
||||
`a`F666`[Served by rngit {VERSION}`:/page/index.mu] - {GEN_TIME}`f"""
|
||||
|
||||
class NomadNetworkNode():
|
||||
APP_NAME = "nomadnetwork"
|
||||
JOBS_INTERVAL = 5
|
||||
BASE_TEMPLATE = DEFAULT_TEMPLATE
|
||||
|
||||
PATH_INDEX = "/page/index.mu"
|
||||
PATH_GROUP = "/page/group.mu"
|
||||
@@ -78,7 +69,12 @@ class NomadNetworkNode():
|
||||
self.announce_interval = owner.announce_interval
|
||||
self.last_announce = 0
|
||||
self.null_ident = RNS.Identity.from_bytes(bytes(64))
|
||||
self.md_converter = MarkdownToMicron(max_width=self.MAX_RENDER_WIDTH)
|
||||
self.mdc = MarkdownToMicron(max_width=self.MAX_RENDER_WIDTH)
|
||||
self.templates = {}
|
||||
|
||||
self.templates["base"] = DEFAULT_BASE_TEMPLATE
|
||||
self.templates["front"] = DEFAULT_FRONT_TEMPLATE
|
||||
self.templates["group"] = DEFAULT_GROUP_TEMPLATE
|
||||
|
||||
self.destination = RNS.Destination(self.identity, RNS.Destination.IN, RNS.Destination.SINGLE, self.APP_NAME, "node")
|
||||
self.destination.set_link_established_callback(self.remote_connected)
|
||||
@@ -121,14 +117,22 @@ class NomadNetworkNode():
|
||||
self.destination.register_request_handler(self.PATH_COMMIT, response_generator=self.serve_commit_page, allow=RNS.Destination.ALLOW_ALL)
|
||||
self.destination.register_request_handler(self.PATH_REFS, response_generator=self.serve_refs_page, allow=RNS.Destination.ALLOW_ALL)
|
||||
|
||||
def render_template(self, page_content, st=None):
|
||||
template = self.BASE_TEMPLATE
|
||||
template = template.replace("{PAGE_CONTENT}", page_content)
|
||||
template = template.replace("{NODE_NAME}", self.node_name)
|
||||
template = template.replace("{VERSION}", __version__)
|
||||
def render_template(self, page_content, nav_content=None, template=None, st=None):
|
||||
if template and template in self.templates:
|
||||
template = self.templates[template]
|
||||
page_content = template.replace("{PAGE_CONTENT}", page_content)
|
||||
|
||||
base_template = self.templates["base"]
|
||||
base_template = base_template.replace("{PAGE_CONTENT}", page_content)
|
||||
base_template = base_template.replace("{NODE_NAME}", self.node_name)
|
||||
base_template = base_template.replace("{VERSION}", __version__)
|
||||
|
||||
if nav_content: base_template = base_template.replace("{NAVIGATION}", nav_content)
|
||||
else: base_template = base_template.replace("{NAVIGATION}", "")
|
||||
|
||||
gt = f"Generated in {RNS.prettytime(time.time()-st)}" if st else "Unknown generation time"
|
||||
template = template.replace("{GEN_TIME}", gt)
|
||||
return template.encode("utf-8")
|
||||
base_template = base_template.replace("{GEN_TIME}", gt)
|
||||
return base_template.encode("utf-8")
|
||||
|
||||
#############################
|
||||
# Micron Generation Helpers #
|
||||
@@ -166,28 +170,26 @@ class NomadNetworkNode():
|
||||
RNS.log(f"Front page request from {remote_identity}", RNS.LOG_DEBUG)
|
||||
|
||||
content_parts = []
|
||||
content_parts.append(self.m_heading("Git Repositories", 1))
|
||||
content_parts.append(f"\n")
|
||||
nav_parts = []
|
||||
|
||||
accessible_groups = self.get_accessible_groups(remote_identity)
|
||||
|
||||
breadcrumb = f"{self.m_link("Node", self.PATH_INDEX)} /"
|
||||
nav_parts.append(self.m_align(breadcrumb, "left") + "\n")
|
||||
|
||||
if not accessible_groups: content_parts.append("No repository groups available.\n")
|
||||
else:
|
||||
content_parts.append(self.m_heading("Available Groups", 2))
|
||||
content_parts.append("\n")
|
||||
|
||||
for group_name in sorted(accessible_groups.keys()):
|
||||
group = accessible_groups[group_name]
|
||||
repo_count = len(group.get("repositories", {}))
|
||||
repo_word = "repository" if repo_count == 1 else "repositories"
|
||||
|
||||
link = self.m_link(f"{group_name}", self.PATH_GROUP, g=group_name)
|
||||
content_parts.append(f" {link} - {repo_count} {repo_word}\n")
|
||||
|
||||
# content_parts.append("\n")
|
||||
link = self.m_link(f" {self.mdc.BULLET} {group_name}", self.PATH_GROUP, g=group_name)
|
||||
content_parts.append(f"{link} ({repo_count} {repo_word})\n")
|
||||
|
||||
page_content = "".join(content_parts)
|
||||
return self.render_template(page_content, st)
|
||||
nav_content = "".join(nav_parts)
|
||||
return self.render_template(page_content, nav_content=nav_content, template="front", st=st)
|
||||
|
||||
def serve_group_page(self, path, data, request_id, link_id, remote_identity, requested_at):
|
||||
st = time.time()
|
||||
@@ -198,18 +200,17 @@ class NomadNetworkNode():
|
||||
|
||||
if not group_name or group_name not in self.owner.groups or not accessible_repos:
|
||||
content = self.m_heading("Group Not Found", 1) + "\n\nThe requested group does not exist or you do not have access to any repositories in it.\n"
|
||||
return self.render_template(content, st)
|
||||
return self.render_template(content, st=st)
|
||||
|
||||
content_parts = []
|
||||
nav_parts = []
|
||||
|
||||
breadcrumb = f"{self.m_link("Node", self.PATH_INDEX)} / {group_name}"
|
||||
content_parts.append(self.m_align(breadcrumb, "left") + "\n\n")
|
||||
content_parts.append(self.m_heading(group_name, 1))
|
||||
content_parts.append("\n")
|
||||
nav_parts.append(self.m_align(breadcrumb, "left") + "\n")
|
||||
|
||||
if not accessible_repos: content_parts.append("No repositories available in this group.\n")
|
||||
if not accessible_repos: content_parts.append("No repositories available.\n")
|
||||
else:
|
||||
content_parts.append(self.m_heading("Repositories", 2))
|
||||
content_parts.append(self.m_heading("Repositories", 1))
|
||||
content_parts.append("\n")
|
||||
|
||||
for repo_name in sorted(accessible_repos.keys()):
|
||||
@@ -217,15 +218,14 @@ class NomadNetworkNode():
|
||||
|
||||
description = self.get_repository_description(repo["path"])
|
||||
|
||||
link = self.m_link(repo_name, self.PATH_REPO, g=group_name, r=repo_name)
|
||||
content_parts.append(f" {link}\n")
|
||||
if description: content_parts.append(f" {self.m_escape(description)}\n")
|
||||
content_parts.append("\n")
|
||||
|
||||
content_parts.append("\n")
|
||||
link = self.m_link(f" {self.mdc.BULLET} {repo_name}", self.PATH_REPO, g=group_name, r=repo_name)
|
||||
content_parts.append(f"{link}")
|
||||
if description: content_parts.append(f" - {description}\n")
|
||||
else: content_parts.append("\n")
|
||||
|
||||
page_content = "".join(content_parts)
|
||||
return self.render_template(page_content, st)
|
||||
nav_content = "".join(nav_parts)
|
||||
return self.render_template(page_content, nav_content=nav_content, template="group", st=st)
|
||||
|
||||
def serve_repo_page(self, path, data, request_id, link_id, remote_identity, requested_at):
|
||||
st = time.time()
|
||||
@@ -237,7 +237,7 @@ class NomadNetworkNode():
|
||||
|
||||
if not repo:
|
||||
content = self.m_heading("Not Found", 1) + "\n\nThe requested repository does not exist or you do not have access to it.\n"
|
||||
return self.render_template(content, st)
|
||||
return self.render_template(content, st=st)
|
||||
|
||||
content_parts = []
|
||||
|
||||
@@ -289,7 +289,7 @@ class NomadNetworkNode():
|
||||
content_parts.append("\n")
|
||||
|
||||
if readme_is_markdown:
|
||||
converted = self.md_converter.format_block(readme_content)
|
||||
converted = self.mdc.format_block(readme_content)
|
||||
content_parts.append(converted)
|
||||
|
||||
else: content_parts.append(f"`=\n{readme_content}\n`=")
|
||||
@@ -304,7 +304,7 @@ class NomadNetworkNode():
|
||||
content_parts.append("\n")
|
||||
|
||||
page_content = "".join(content_parts)
|
||||
return self.render_template(page_content, st)
|
||||
return self.render_template(page_content, st=st)
|
||||
|
||||
def serve_tree_page(self, path, data, request_id, link_id, remote_identity, requested_at):
|
||||
st = time.time()
|
||||
@@ -326,7 +326,7 @@ class NomadNetworkNode():
|
||||
repo = self.get_accessible_repository(remote_identity, group_name, repo_name)
|
||||
if not repo:
|
||||
content = self.m_heading("Not Found", 1) + "\n\nThe requested repository does not exist or you do not have access to it.\n"
|
||||
return self.render_template(content, st)
|
||||
return self.render_template(content, st=st)
|
||||
|
||||
repo_path = repo["path"]
|
||||
|
||||
@@ -335,7 +335,7 @@ class NomadNetworkNode():
|
||||
if not resolved_ref:
|
||||
content = self.m_heading("Ref Not Found", 1) + f"\n\nThe ref '{ref}' does not exist in this repository.\n"
|
||||
content += f"\n" + self.m_link("View All Refs", self.PATH_REFS, g=group_name, r=repo_name) + "\n"
|
||||
return self.render_template(content, st)
|
||||
return self.render_template(content, st=st)
|
||||
|
||||
content_parts = []
|
||||
|
||||
@@ -441,7 +441,7 @@ class NomadNetworkNode():
|
||||
if content_parts[-1] == "\n": content_parts[-1] = ""
|
||||
|
||||
page_content = "".join(content_parts)
|
||||
return self.render_template(page_content, st)
|
||||
return self.render_template(page_content, st=st)
|
||||
|
||||
def serve_blob_page(self, path, data, request_id, link_id, remote_identity, requested_at):
|
||||
st = time.time()
|
||||
@@ -456,7 +456,7 @@ class NomadNetworkNode():
|
||||
repo = self.get_accessible_repository(remote_identity, group_name, repo_name)
|
||||
if not repo:
|
||||
content = self.m_heading("Not Found", 1) + "\n\nThe requested repository does not exist or you do not have access to it.\n"
|
||||
return self.render_template(content, st)
|
||||
return self.render_template(content, st=st)
|
||||
|
||||
repo_path = repo["path"]
|
||||
|
||||
@@ -464,12 +464,12 @@ class NomadNetworkNode():
|
||||
resolved_ref = self.resolve_ref(repo_path, ref)
|
||||
if not resolved_ref:
|
||||
content = self.m_heading("Ref Not Found", 1) + f"\n\nThe ref '{ref}' does not exist in this repository.\n"
|
||||
return self.render_template(content, st)
|
||||
return self.render_template(content, st=st)
|
||||
|
||||
# Validate file path
|
||||
if not file_path:
|
||||
content = self.m_heading("Invalid Path", 1) + "\n\nNo file path specified.\n"
|
||||
return self.render_template(content, st)
|
||||
return self.render_template(content, st=st)
|
||||
|
||||
content_parts = []
|
||||
|
||||
@@ -538,7 +538,7 @@ class NomadNetworkNode():
|
||||
content_parts.append("Error reading file content.\n")
|
||||
|
||||
page_content = "".join(content_parts)
|
||||
return self.render_template(page_content, st)
|
||||
return self.render_template(page_content, st=st)
|
||||
|
||||
def serve_commits_page(self, path, data, request_id, link_id, remote_identity, requested_at):
|
||||
st = time.time()
|
||||
@@ -560,7 +560,7 @@ class NomadNetworkNode():
|
||||
repo = self.get_accessible_repository(remote_identity, group_name, repo_name)
|
||||
if not repo:
|
||||
content = self.m_heading("Not Found", 1) + "\n\nThe requested repository does not exist or you do not have access to it.\n"
|
||||
return self.render_template(content, st)
|
||||
return self.render_template(content, st=st)
|
||||
|
||||
repo_path = repo["path"]
|
||||
|
||||
@@ -568,7 +568,7 @@ class NomadNetworkNode():
|
||||
resolved_ref = self.resolve_ref(repo_path, ref)
|
||||
if not resolved_ref:
|
||||
content = self.m_heading("Ref Not Found", 1) + f"\n\nThe ref '{ref}' does not exist in this repository.\n"
|
||||
return self.render_template(content, st)
|
||||
return self.render_template(content, st=st)
|
||||
|
||||
content_parts = []
|
||||
|
||||
@@ -622,7 +622,7 @@ class NomadNetworkNode():
|
||||
content_parts.append(" " + " | ".join(nav_links) + "\n")
|
||||
|
||||
page_content = "".join(content_parts)
|
||||
return self.render_template(page_content, st)
|
||||
return self.render_template(page_content, st=st)
|
||||
|
||||
def serve_commit_page(self, path, data, request_id, link_id, remote_identity, requested_at):
|
||||
st = time.time()
|
||||
@@ -635,20 +635,20 @@ class NomadNetworkNode():
|
||||
repo = self.get_accessible_repository(remote_identity, group_name, repo_name)
|
||||
if not repo:
|
||||
content = self.m_heading("Not Found", 1) + "\n\nThe requested repository does not exist or you do not have access to it.\n"
|
||||
return self.render_template(content, st)
|
||||
return self.render_template(content, st=st)
|
||||
|
||||
repo_path = repo["path"]
|
||||
|
||||
# Validate commit hash
|
||||
if not commit_hash or len(commit_hash) < 7:
|
||||
content = self.m_heading("Invalid Commit", 1) + "\n\nNo valid commit hash specified.\n"
|
||||
return self.render_template(content, st)
|
||||
return self.render_template(content, st=st)
|
||||
|
||||
# Resolve and validate the commit hash
|
||||
resolved_hash = self.resolve_ref(repo_path, commit_hash)
|
||||
if not resolved_hash:
|
||||
content = self.m_heading("Commit Not Found", 1) + f"\n\nThe commit '{commit_hash}' does not exist in this repository.\n"
|
||||
return self.render_template(content, st)
|
||||
return self.render_template(content, st=st)
|
||||
|
||||
# Verify it's actually a commit object
|
||||
try:
|
||||
@@ -658,11 +658,11 @@ class NomadNetworkNode():
|
||||
|
||||
if type_result.returncode != 0 or type_result.stdout.strip() != "commit":
|
||||
content = self.m_heading("Invalid Object", 1) + f"\n\nThe hash '{commit_hash}' does not refer to a commit.\n"
|
||||
return self.render_template(content, st)
|
||||
return self.render_template(content, st=st)
|
||||
|
||||
except Exception:
|
||||
content = self.m_heading("Error", 1) + "\n\nCould not verify commit object.\n"
|
||||
return self.render_template(content, st)
|
||||
return self.render_template(content, st=st)
|
||||
|
||||
content_parts = []
|
||||
|
||||
@@ -674,7 +674,7 @@ class NomadNetworkNode():
|
||||
if not commit_info:
|
||||
content_parts.append(self.m_heading("Error", 1) + "\n\nCould not retrieve commit information.\n")
|
||||
page_content = "".join(content_parts)
|
||||
return self.render_template(page_content, st)
|
||||
return self.render_template(page_content, st=st)
|
||||
|
||||
content_parts.append(self.m_heading(f"Commit {resolved_hash[:7]}", 1))
|
||||
content_parts.append("\n")
|
||||
@@ -756,7 +756,7 @@ class NomadNetworkNode():
|
||||
content_parts.append(f" {self.m_link('📁 Browse files at this commit', self.PATH_TREE, g=group_name, r=repo_name, ref=resolved_hash)}\n")
|
||||
|
||||
page_content = "".join(content_parts)
|
||||
return self.render_template(page_content, st)
|
||||
return self.render_template(page_content, st=st)
|
||||
|
||||
def serve_refs_page(self, path, data, request_id, link_id, remote_identity, requested_at):
|
||||
st = time.time()
|
||||
@@ -769,7 +769,7 @@ class NomadNetworkNode():
|
||||
repo = self.get_accessible_repository(remote_identity, group_name, repo_name)
|
||||
if not repo:
|
||||
content = self.m_heading("Not Found", 1) + "\n\nThe requested repository does not exist or you do not have access to it.\n"
|
||||
return self.render_template(content, st)
|
||||
return self.render_template(content, st=st)
|
||||
|
||||
repo_path = repo["path"]
|
||||
|
||||
@@ -859,7 +859,7 @@ class NomadNetworkNode():
|
||||
content_parts.append(" " + " | ".join(filter_links) + "\n")
|
||||
|
||||
page_content = "".join(content_parts)
|
||||
return self.render_template(page_content, st)
|
||||
return self.render_template(page_content, st=st)
|
||||
|
||||
#######################
|
||||
# Git Data Extraction #
|
||||
@@ -874,12 +874,11 @@ class NomadNetworkNode():
|
||||
if result.returncode == 0 and result.stdout.strip(): return result.stdout.strip()
|
||||
|
||||
# Fall back to description file
|
||||
desc_path = os.path.join(repo_path, "description")
|
||||
desc_path = f"{repo_path}.description"
|
||||
if os.path.isfile(desc_path):
|
||||
with open(desc_path, "r") as f:
|
||||
desc = f.read().strip()
|
||||
# Skip default template descriptions
|
||||
if desc and not desc.startswith("Unnamed repository"): return desc
|
||||
if desc: return desc
|
||||
|
||||
except Exception as e: RNS.log(f"Error getting repository description: {e}", RNS.LOG_DEBUG)
|
||||
|
||||
@@ -1396,3 +1395,21 @@ class NomadNetworkNode():
|
||||
return all_repos[repo_name]
|
||||
|
||||
return None
|
||||
|
||||
# Global base template
|
||||
DEFAULT_BASE_TEMPLATE = """#!c=0
|
||||
>{NODE_NAME}
|
||||
|
||||
{NAVIGATION}
|
||||
{PAGE_CONTENT}
|
||||
<
|
||||
-
|
||||
`a`F666`[Served by rngit {VERSION}`:/page/index.mu] - {GEN_TIME}`f"""
|
||||
|
||||
# Front page template
|
||||
DEFAULT_FRONT_TEMPLATE = """>Groups
|
||||
|
||||
{PAGE_CONTENT}"""
|
||||
|
||||
# Repositories page template
|
||||
DEFAULT_GROUP_TEMPLATE = """{PAGE_CONTENT}"""
|
||||
Reference in New Issue
Block a user