diff --git a/RNS/Utilities/rngit/pages.py b/RNS/Utilities/rngit/pages.py index 13bcca5b..4dcccf09 100644 --- a/RNS/Utilities/rngit/pages.py +++ b/RNS/Utilities/rngit/pages.py @@ -99,14 +99,26 @@ class NomadNetworkNode(): self.last_announce = 0 self.null_ident = RNS.Identity.from_bytes(bytes(64)) - self.templates = {} - self.templates["base"] = DEFAULT_BASE_TEMPLATE - self.templates["front"] = DEFAULT_FRONT_TEMPLATE - self.templates["group"] = DEFAULT_GROUP_TEMPLATE - self.use_nerdfonts = self.USE_NERDFONTS - self.highlight_syntax = True - self.highlighter = SyntaxHighlighter() - self.mdc = MarkdownToMicron(max_width=self.MAX_RENDER_WIDTH, syntax_highlighter=self.highlighter) + self.templates = {} + self.templates["base"] = DEFAULT_BASE_TEMPLATE + self.templates["front"] = DEFAULT_FRONT_TEMPLATE + self.templates["group"] = DEFAULT_GROUP_TEMPLATE + self.templates["repo"] = DEFAULT_REPO_TEMPLATE + self.templates["tree"] = DEFAULT_TREE_TEMPLATE + self.templates["blob"] = DEFAULT_BLOB_TEMPLATE + self.templates["commits"] = DEFAULT_COMMITS_TEMPLATE + self.templates["commit"] = DEFAULT_COMMIT_TEMPLATE + self.templates["refs"] = DEFAULT_REFS_TEMPLATE + self.templates["stats"] = DEFAULT_STATS_TEMPLATE + self.templatesdir = self.owner.configdir+"/templates" + self.use_nerdfonts = self.USE_NERDFONTS + self.highlight_syntax = True + self.highlighter = SyntaxHighlighter() + self.mdc = MarkdownToMicron(max_width=self.MAX_RENDER_WIDTH, syntax_highlighter=self.highlighter) + + if not os.path.isdir(self.templatesdir): + try: os.makedirs(self.templatesdir) + except Exception as e: RNS.log(f"Could not create templates directory {self.templatesdir}: {e}", RNS.LOG_ERROR) 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) @@ -173,12 +185,40 @@ class NomadNetworkNode(): self.destination.register_request_handler(self.PATH_REFS, response_generator=self.serve_refs_page, allow=RNS.Destination.ALLOW_ALL) self.destination.register_request_handler(self.PATH_STATS, response_generator=self.serve_stats_page, allow=RNS.Destination.ALLOW_ALL) + def get_template(self, template): + filename = f"{template}.mu" + path = os.path.join(self.templatesdir, filename) + if not os.path.isfile(path): return None + else: + if os.access(path, os.X_OK): + try: + result = subprocess.run([path], stdout=subprocess.PIPE) + template = result.stdout.decode("utf-8") + return template + + except Exception as e: + RNS.log(f"Could not get dynamic template content from {path}: {e}", RNS.LOG_ERROR) + return None + + else: + try: + with open(path, "rb") as fh: return fh.read().decode("utf-8") + + except Exception as e: + RNS.log(f"Could not get static template content from {path}: {e}", RNS.LOG_ERROR) + return None + def render_template(self, page_content, nav_content=None, template=None, st=None): - if template and template in self.templates: + custom_template = self.get_template(template) if template else None + if custom_template: + template = custom_template + page_content = template.replace("{PAGE_CONTENT}", page_content) + + elif 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 = self.get_template("base") or 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__) @@ -240,8 +280,8 @@ class NomadNetworkNode(): 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") + breadcrumb = f">>\n{self.m_link("Node", self.PATH_INDEX)} /" + nav_parts.append(breadcrumb + "\n") if not accessible_groups: content_parts.append("No repository groups available.\n") else: @@ -250,7 +290,7 @@ class NomadNetworkNode(): repo_count = len(group.get("repositories", {})) repo_word = "repository" if repo_count == 1 else "repositories" - link = self.m_link(f" {self.mdc.BULLET} {group_name}", self.PATH_GROUP, g=group_name) + 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") self.owner.view_succeeded(None, None, remote_identity) @@ -277,8 +317,8 @@ class NomadNetworkNode(): content_parts = [] nav_parts = [] - breadcrumb = f"{self.m_link("Node", self.PATH_INDEX)} / {group_name}" - nav_parts.append(self.m_align(breadcrumb, "left") + "\n") + breadcrumb = f">>\n{self.m_link("Node", self.PATH_INDEX)} / {group_name}" + nav_parts.append(breadcrumb + "\n") if not accessible_repos: content_parts.append("No repositories available.\n") else: @@ -290,7 +330,7 @@ class NomadNetworkNode(): description = self.get_repository_description(repo["path"]) - link = self.m_link(f" {self.mdc.BULLET} {repo_name}", self.PATH_REPO, g=group_name, r=repo_name) + 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") @@ -372,7 +412,7 @@ class NomadNetworkNode(): self.owner.view_succeeded(group_name, repo_name, remote_identity) page_content = "".join(content_parts) nav_content = "".join(nav_parts) - return self.render_template(page_content, nav_content=nav_content, st=st) + return self.render_template(page_content, nav_content=nav_content, template="repo", st=st) def serve_tree_page(self, path, data, request_id, link_id, remote_identity, requested_at): st = time.time() @@ -426,7 +466,7 @@ class NomadNetworkNode(): else: breadcrumb_parts.append("") # Could be "root" or something, but a bit confusing breadcrumb = " / ".join(breadcrumb_parts) - nav_parts.append(breadcrumb + "\n") + nav_parts.append(">>\n" + breadcrumb + "\n") # Get tree entries entries = self.get_tree_entries(repo_path, resolved_ref, tree_path) @@ -512,7 +552,7 @@ class NomadNetworkNode(): self.owner.view_succeeded(group_name, repo_name, remote_identity) page_content = "".join(content_parts) nav_content = "".join(nav_parts) - return self.render_template(page_content, nav_content=nav_content, st=st) + return self.render_template(page_content, nav_content=nav_content, template="tree", st=st) def serve_blob_page(self, path, data, request_id, link_id, remote_identity, requested_at): st = time.time() @@ -571,7 +611,7 @@ class NomadNetworkNode(): else: breadcrumb_parts.append(self.m_link(component, self.PATH_TREE, g=group_name, r=repo_name, ref=ref, path=current_path)) breadcrumb = " / ".join(breadcrumb_parts) - nav_parts.append(breadcrumb + "\n") + nav_parts.append(">>\n" + breadcrumb + "\n") if renderable: sep = self.icon("sep") @@ -627,7 +667,7 @@ class NomadNetworkNode(): self.owner.view_succeeded(group_name, repo_name, remote_identity) page_content = "".join(content_parts) nav_content = "".join(nav_parts) - return self.render_template(page_content, nav_content=nav_content, st=st) + return self.render_template(page_content, nav_content=nav_content, template="blob", st=st) def serve_commits_page(self, path, data, request_id, link_id, remote_identity, requested_at): st = time.time() @@ -671,7 +711,7 @@ class NomadNetworkNode(): if file_path: breadcrumb_parts.insert(3, f"{self.m_escape(file_path)}") breadcrumb = " / ".join(breadcrumb_parts) - nav_parts.append(self.m_align(breadcrumb, "left") + "\n") + nav_parts.append(">>\n" + breadcrumb + "\n") title_suffix = f" for {file_path}" if file_path else "" @@ -709,7 +749,7 @@ class NomadNetworkNode(): self.owner.view_succeeded(group_name, repo_name, remote_identity) page_content = "".join(content_parts) nav_content = "".join(nav_parts) - return self.render_template(page_content, nav_content=nav_content, st=st) + return self.render_template(page_content, nav_content=nav_content, template="commits", st=st) def serve_commit_page(self, path, data, request_id, link_id, remote_identity, requested_at): st = time.time() @@ -744,7 +784,7 @@ class NomadNetworkNode(): # Breadcrumb navigation nav_parts = [] breadcrumb = f"{self.m_link("Node", self.PATH_INDEX)} / {self.m_link(group_name, self.PATH_GROUP, g=group_name)} / {self.m_link(repo_name, self.PATH_REPO, g=group_name, r=repo_name)} / {resolved_hash[:7]}" - nav_parts.append(self.m_align(breadcrumb, "left") + "\n") + nav_parts.append(">>\n" + breadcrumb + "\n") nav_content = "".join(nav_parts) # Verify it's actually a commit object @@ -842,7 +882,7 @@ class NomadNetworkNode(): self.owner.view_succeeded(group_name, repo_name, remote_identity) page_content = "".join(content_parts) - return self.render_template(page_content, nav_content=nav_content, st=st) + return self.render_template(page_content, nav_content=nav_content, template="commit", st=st) def serve_refs_page(self, path, data, request_id, link_id, remote_identity, requested_at): st = time.time() @@ -857,7 +897,7 @@ class NomadNetworkNode(): # Breadcrumb navigation breadcrumb = f"{self.m_link("Node", self.PATH_INDEX)} / {self.m_link(group_name, self.PATH_GROUP, g=group_name)} / {self.m_link(repo_name, self.PATH_REPO, g=group_name, r=repo_name)} / refs" - nav_parts.append(self.m_align(breadcrumb, "left") + "\n") + nav_parts.append(">>\n" + breadcrumb + "\n") nav_content = "".join(nav_parts) if not group_name or not repo_name: @@ -944,7 +984,7 @@ class NomadNetworkNode(): self.owner.view_succeeded(group_name, repo_name, remote_identity) page_content = "".join(content_parts).rstrip()+"\n" - return self.render_template(page_content, nav_content=nav_content, st=st) + return self.render_template(page_content, nav_content=nav_content, template="refs", st=st) def serve_stats_page(self, path, data, request_id, link_id, remote_identity, requested_at): st = time.time() @@ -1027,7 +1067,7 @@ class NomadNetworkNode(): page_content = "".join(content_parts) nav_content = "".join(nav_parts) - return self.render_template(page_content, nav_content=nav_content, st=st) + return self.render_template(page_content, nav_content=nav_content, template="stats", st=st) ####################### # Git Data Extraction # @@ -1695,4 +1735,28 @@ DEFAULT_FRONT_TEMPLATE = """>Groups {PAGE_CONTENT}""" # Repositories page template -DEFAULT_GROUP_TEMPLATE = """{PAGE_CONTENT}""" \ No newline at end of file +DEFAULT_GROUP_TEMPLATE = """{PAGE_CONTENT}""" + +# Repository page template +DEFAULT_REPO_TEMPLATE = """{PAGE_CONTENT}""" + +# Tree page template +DEFAULT_TREE_TEMPLATE = """{PAGE_CONTENT}""" + +# Blob page template +DEFAULT_BLOB_TEMPLATE = """{PAGE_CONTENT}""" + +# Commits page template +DEFAULT_COMMITS_TEMPLATE = """{PAGE_CONTENT}""" + +# Commit page template +DEFAULT_COMMIT_TEMPLATE = """{PAGE_CONTENT}""" + +# Refs page template +DEFAULT_REFS_TEMPLATE = """{PAGE_CONTENT}""" + +# Stats page template +DEFAULT_STATS_TEMPLATE = """{PAGE_CONTENT}""" + +# Fallback template +FALLBACK_TEMPLATE = """{PAGE_CONTENT}""" \ No newline at end of file