diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
index 49f7b87b..3cdc6aed 100644
--- a/.idea/codeStyles/Project.xml
+++ b/.idea/codeStyles/Project.xml
@@ -24,29 +24,5 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/royalnet.iml b/.idea/royalnet.iml
index 0b92a2cf..d2034fcf 100644
--- a/.idea/royalnet.iml
+++ b/.idea/royalnet.iml
@@ -9,7 +9,7 @@
-
+
diff --git a/pyproject.toml b/pyproject.toml
index 64445241..9f6d3f90 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -2,7 +2,7 @@
[tool.poetry]
name = "royalnet"
- version = "5.1.5"
+ version = "5.1.6"
description = "A multipurpose bot and web framework"
authors = ["Stefano Pigozzi "]
license = "AGPL-3.0+"
diff --git a/royalnet/__main__.py b/royalnet/__main__.py
index 8c429fc0..d848f258 100644
--- a/royalnet/__main__.py
+++ b/royalnet/__main__.py
@@ -17,7 +17,7 @@ log = logging.getLogger(__name__)
@click.command()
-@click.option("-c", "--config-filename", default="./config.toml", type=str,
+@click.option("-c", "--config-filename", default="./config.toml", type=click.Path(exists=True),
help="The filename of the Royalnet configuration file.")
def run(config_filename: str):
# Read the configuration file
diff --git a/royalnet/backpack/stars/api_royalnet_version.py b/royalnet/backpack/stars/api_royalnet_version.py
index d9a3f4f7..26f3b9d0 100644
--- a/royalnet/backpack/stars/api_royalnet_version.py
+++ b/royalnet/backpack/stars/api_royalnet_version.py
@@ -2,14 +2,11 @@ import royalnet
from starlette.requests import Request
from starlette.responses import *
from royalnet.constellation import PageStar
-from ..tables import available_tables
class ApiRoyalnetVersionStar(PageStar):
path = "/api/royalnet/version"
- tables = set(available_tables)
-
async def page(self, request: Request) -> JSONResponse:
return JSONResponse({
"version": {
diff --git a/royalnet/generate.py b/royalnet/generate.py
new file mode 100644
index 00000000..62c06b96
--- /dev/null
+++ b/royalnet/generate.py
@@ -0,0 +1,116 @@
+import toml
+import importlib
+import click
+
+p = click.echo
+
+
+@click.command()
+@click.option("-c", "--config-filename", default="./config.toml", type=click.Path(exists=True),
+ help="The filename of the Royalnet configuration file.")
+@click.option("-f", "--file-format", type=str, help="The name of the format that should be generated.")
+def run(config_filename, file_format):
+ with open(config_filename, "r") as t:
+ config: dict = toml.load(t)
+
+ # Import packs
+ packs_cfg = config["Packs"]
+ pack_names = packs_cfg["active"]
+ packs = {}
+ for pack_name in pack_names:
+ try:
+ packs[pack_name] = importlib.import_module(pack_name)
+ except ImportError as e:
+ p(f"Skipping `{pack_name}`: {e}", err=True)
+ continue
+
+ if file_format == "botfather":
+ for pack_name in packs:
+ pack = packs[pack_name]
+ lines = []
+
+ try:
+ commands = pack.available_commands
+ except AttributeError:
+ p(f"Pack `{pack}` does not have the `available_commands` attribute.", err=True)
+ continue
+ for command in commands:
+ lines.append(f"{command.name} - {command.description}")
+
+ lines.sort()
+ for line in lines:
+ p(line)
+
+ elif file_format == "markdown":
+ for pack_name in packs:
+ pack = packs[pack_name]
+ p(f"# {pack_name}")
+ p("")
+
+ try:
+ commands = pack.available_commands
+ except AttributeError:
+ p(f"Pack `{pack}` does not have the `available_commands` attribute.", err=True)
+ else:
+ p(f"## Commands")
+ p("")
+ for command in commands:
+ p(f"### `{command.name}`")
+ p("")
+ p(f"{command.description}")
+ p("")
+ if len(command.aliases) > 0:
+ p(f"> Aliases: {''.join(['`' + alias + '` ' for alias in command.aliases])}")
+ p("")
+
+ try:
+ events = pack.available_events
+ except AttributeError:
+ p(f"Pack `{pack}` does not have the `available_events` attribute.", err=True)
+ else:
+ p(f"## Events")
+ p("")
+ for event in events:
+ p(f"### `{event.name}`")
+ p("")
+
+ try:
+ page_stars = pack.available_page_stars
+ except AttributeError:
+ p(f"Pack `{pack}` does not have the `available_page_stars` attribute.", err=True)
+ else:
+ p(f"## Page Stars")
+ p("")
+ for page_star in page_stars:
+ p(f"### `{page_star.path}`")
+ p("")
+
+ try:
+ exc_stars = pack.available_exception_stars
+ except AttributeError:
+ p(f"Pack `{pack}` does not have the `available_exception_stars` attribute.", err=True)
+ else:
+ p(f"## Exception Stars")
+ p("")
+ for exc_star in exc_stars:
+ p(f"### `{exc_star.error}`")
+ p("")
+
+ try:
+ tables = pack.available_tables
+ except AttributeError:
+ p(f"Pack `{pack}` does not have the `available_tables` attribute.", err=True)
+ else:
+ p(f"## Tables")
+ p("")
+ for table in tables:
+ p(f"### `{table.__tablename__}`")
+ p("")
+ # TODO: list columns
+
+ else:
+ raise click.ClickException("Unknown format")
+
+
+if __name__ == "__main__":
+ run()
diff --git a/royalnet/version.py b/royalnet/version.py
index e82f6910..a4a20039 100644
--- a/royalnet/version.py
+++ b/royalnet/version.py
@@ -1 +1 @@
-semantic = "5.1.5"
+semantic = "5.1.6"