# Copyright 2026 Logan Fick # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Web routes for the custom commands module.""" from pathlib import Path import jinja2 from aiohttp import web from owlbot.api import RouteContext, on_route _template_dir = Path(__file__).resolve().parent / "templates" _jinja_env = jinja2.Environment( loader=jinja2.FileSystemLoader(_template_dir), autoescape=True, ) @on_route("/list", methods=["GET"]) async def command_list_page(ctx: RouteContext) -> web.Response: """ Serve an HTML page listing all custom commands in a table. Columns: Command, Aliases, Response, Cooldown, Permissions. Accessible at /owlbot/custom_commands/list. :param ctx: The route context. :return: HTML response with the command list table. """ rows = await ctx.storage.fetch_all( "SELECT c.name, c.response, c.requires_moderator, c.cooldown, " "GROUP_CONCAT(ca.alias, ', ') AS aliases " "FROM commands c " "LEFT JOIN command_aliases ca ON c.name = ca.command_name " "GROUP BY c.name " "ORDER BY c.name" ) prefix = ctx.commands.prefix commands = [ { "name": row["name"], "aliases": ( ", ".join(f"{prefix}{a}" for a in row["aliases"].split(", ")) if row["aliases"] else "None" ), "response": row["response"], "permissions": "Moderator" if row["requires_moderator"] else "Everyone", "cooldown": "None" if row["cooldown"] == 0 else f"{row['cooldown']}s", } for row in rows ] template = _jinja_env.get_template("list.html") page = template.render(commands=commands, prefix=ctx.commands.prefix) return web.Response(text=page, content_type="text/html")