commit af3c83b

Artur Manuel  ·  2026-07-30 18:49:01 +0000 UTC
parent 1a7fa44
gtm: add a bunch of things :3
9 files changed,  +127, -66
+1, -0
1@@ -0,0 +1 @@
2+
+4, -7
 1@@ -1,13 +1,10 @@
 2 {
 3-  "title": "My cool capsule",
 4-  "description": "Made with paws :3",
 5+  "default_title": "My cool capsule",
 6+  "default_description": "Made with paws :3",
 7   "content_dir": "./content",
 8   "templates_dir": "./templates",
 9-  "page_settings": {
10-    "ascii_fop": {
11-      "template": "none"
12-    }
13-  },
14+  "assets_dir": "./assets",
15+  "output_dir": "./output",
16   "extra": {
17     "fav_frb_creators": [
18       "PowerPoint Rap Battles",
+17, -0
 1@@ -0,0 +1,17 @@
 2+# BEHOLD, foppy
 3+
 4+⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣰⠀⠀⠀
 5+⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⡴⠻⣀⠀⠀
 6+⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡴⡆⠀⠀⣦⡀⠀⠀⠀⠀⠉⠓⢄⣠⠼⠛⠂
 7+⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡞⠀⣇⠀⠀⡇⢳⡀⠀⠀⠀⠀⠀⣼⠁⠀⠀⠀
 8+⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⠇⠀⠈⠉⠉⠁⠀⡇⠀⠀⠀⠀⠀⠁⠀⠀⠀⠀
 9+⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢺⡀⠀⡇⠀⡇⠀⠀⢧⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
10+⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠓⢢⠀⠀⠀⢠⠶⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
11+⠀⠀⠀⢀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠗⠒⣆⠀⠀⠀⠀⡼⠀⠀⠀⠀⢧⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
12+⠀⠀⠀⣿⠀⠀⠀⠀⠀⠀⢀⡴⠃⠀⠀⣸⠀⠀⠀⠀⡇⠀⠀⠀⠀⠈⢧⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀
13+⠀⠀⣴⠿⢄⡀⠀⠀⠀⣰⠃⠀⠀⠀⢠⠇⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠳⣀⠀⠀⠀⠀⠀⠀⠀⠀
14+⣀⣔⠋⠀⢀⡨⠗⠂⠀⡇⠀⠀⠀⠀⠸⡀⠀⠀⠀⠀⡇⠀⣇⡧⠼⠤⠤⢄⡸⡁⠀⠀⠀⠀⠀⠀⠀
15+⠀⠀⠉⣧⠋⠀⠀⠀⠀⢱⡀⠀⠀⠀⠀⠙⠒⠦⠤⠤⠖⠋⠁⠀⠀⠀⠀⠀⠘⡇⠀⠀⠀⠀⠀⠀⠀
16+⠀⠀⠀⠛⠀⠀⠀⠀⠀⠀⠙⠢⣄⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠞⠁⠀⠀⠀⠀⠀⠀⠀
17+⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠑⠒⠦⢄⣀⡀⠀⠀⠀⠀⣀⠔⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀
18+⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠉⠉⠉⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
+1, -0
1@@ -0,0 +1 @@
2+# hai :3
+7, -0
1@@ -0,0 +1,7 @@
2+I'm a red foppy :3
3+
4+## Here are my favourite rap battle creators!
5+
6+{%- for frb_creator in extra.fav_frb_creators %}
7+- {{ frb_creator }}
8+{%- endfor %}
+1, -41
 1@@ -1,44 +1,4 @@
 2-import sys
 3-from pathlib import Path
 4-
 5-import click
 6-
 7-
 8-EXAMPLE_GTM_CONFIG: str = """
 9-{
10-  "title": "Example capsule",
11-  "description": "I would put more information about my capsule here",
12-  "content_dir": "./content",
13-  "templates_dir": "./templates",
14-  "assets_dir": "./assets",
15-  "page_settings": {},
16-  "extra": {}
17-}
18-"""
19-
20-
21-@click.group()
22-def run():
23-    pass
24-
25-
26-@run.command()
27-@click.option('--path', type=click.Path(exists=True, file_okay=False, writable=True, path_type=Path, executable=True), default=".")
28-def build(path: str):
29-    """Build the Gemini capsules into your output directory"""
30-    sys.stderr.write("Hello, currently I have nothing written for here. Sorry for the inconvenience :(\n")
31-    
32-@run.command()
33-@click.option('--path', type=click.Path(exists=False), default=".")
34-def init(path: str):
35-    """Initialise a gtm project"""
36-    output_path = Path(path)
37-    output_path.mkdir(0o755, parents=True)
38-    output_config_file = output_path / "gtm.json"
39-    output_config_file.write_text(EXAMPLE_GTM_CONFIG)
40-    for dir in ["assets", "content", "templates"]:
41-        (output_path / dir).mkdir(0o755)
42-
43+from gtm.commands import run
44 
45 if __name__ == "__main__":
46     run()
+58, -0
 1@@ -0,0 +1,58 @@
 2+import shutil
 3+import os
 4+from gtm.config import Config
 5+from pathlib import Path
 6+
 7+import click
 8+
 9+
10+EXAMPLE_GTM_CONFIG: str = """
11+{
12+  "title": "Example capsule",
13+  "description": "I would put more information about my capsule here",
14+  "content_dir": "./content",
15+  "templates_dir": "./templates",
16+  "assets_dir": "./assets",
17+  "page_settings": {},
18+  "extra": {}
19+}
20+"""
21+
22+
23+@click.group()
24+def run():
25+    pass
26+
27+
28+@run.command()
29+@click.option(
30+    "--config-path",
31+    type=click.Path(path_type=Path, exists=True),
32+    default="./gtm.json",
33+)
34+def build(config_path: Path):
35+    """Build the Gemini capsules into your output directory"""
36+    config = Config.loads(config_path.read_text())
37+    if not os.path.exists(config.output_dir):
38+        Path(config.output_dir).mkdir(0o755, parents=True)
39+    for dirpath, _, filenames in os.walk(config.content_dir):
40+        for filename in filenames:
41+            output_path = Path(config.output_dir, filename)
42+            if output_path.stem.startswith(".") or output_path.suffix != "gmi":
43+                continue
44+            output_path.parent.mkdir(0o755, parents=True, exist_ok=True)
45+            output_path.touch(0o644)
46+            content = Path(dirpath, filename).read_text()
47+            output_path.write_text(content)
48+
49+
50+@run.command()
51+@click.option("--path", type=click.Path(exists=False, path_type=Path), default=".")
52+def init(path: Path):
53+    """Initialise a gtm project"""
54+    path.mkdir(0o755, parents=True)
55+    config_file = path / "gtm.json"
56+    config_file.touch(0o644)
57+    config_file.write_text(EXAMPLE_GTM_CONFIG)
58+    for dir in ["assets", "content", "templates"]:
59+        (path / dir).mkdir(0o755)
+9, -12
 1@@ -3,26 +3,23 @@ import json
 2 from typing import Any, Self
 3 from os import PathLike
 4 
 5-from gtm.page import Page
 6-
 7-
 8 class Config:
 9     def __init__(
10         self,
11         content_dir: str | PathLike = "./content",
12         templates_dir: str | PathLike = "./templates",
13         assets_dir: str | PathLike = "./assets",
14+        output_dir: str | PathLike = "./output",
15         default_title: str | None = None,
16         default_description: str | None = None,
17-        page_settings: dict[str, Page] = {},
18         extra: dict[str, Any] = {},
19     ):
20         self.content_dir = content_dir
21         self.templates_dir = templates_dir
22         self.assets_dir = assets_dir
23+        self.output_dir = output_dir
24         self.default_title = default_title
25         self.default_description = default_description
26-        self.page_settings = page_settings
27         self.extra = extra
28         pass
29 
30@@ -32,13 +29,13 @@ class Config:
31         doc = json.loads(text)
32         if not isinstance(doc, dict):
33             raise ValueError("Expected JSON config to be a set")
34-        config.assets_dir = doc["assets_dir"]
35-        config.templates_dir = doc["templates_dir"]
36-        config.content_dir = doc["content_dir"]
37-        config.default_title = doc["default_title"]
38-        config.default_description = doc["default_description"]
39-        config.page_settings = doc["page_settings"]
40-        config.extra = doc["extra"]
41+        config.assets_dir = doc.get("assets_dir") or config.assets_dir
42+        config.templates_dir = doc.get("templates_dir") or config.templates_dir
43+        config.content_dir = doc.get("content_dir") or config.content_dir
44+        config.output_dir = doc.get("output_dir") or config.output_dir
45+        config.default_title = doc.get("default_title") or config.default_title
46+        config.default_description = doc.get("default_description") or config.default_description
47+        config.extra = doc.get("extra")
48         return config
49 
50     @classmethod
+29, -6
 1@@ -2,8 +2,12 @@ from gtm.config import Config
 2 
 3 config_text = '''
 4 {
 5-  "title": "My cool capsule",
 6-  "description": "Made with paws :3",
 7+  "default_title": "My cool capsule",
 8+  "default_description": "Made with paws :3",
 9+  "content_dir": "./content",
10+  "templates_dir": "./templates",
11+  "assets_dir": "./assets",
12+  "output_dir": "./output",
13   "extra": {
14     "fav_frb_creators": [
15       "PowerPoint Rap Battles",
16@@ -23,8 +27,27 @@ config_text = '''
17 
18 def test_load_config_from_text():
19     config = Config.loads(config_text)
20+    assert isinstance(config, Config)
21     assert config.default_title == "My cool capsule"
22-    creators = config.extra.get("fav_frb_creators")
23-    assert creators and isinstance(creators, list)
24-    for creator in creators:
25-        assert creator in ["PowerPoint Rap Battles", "AdamDRB", "worms_of_cans", "Indie Game Rap Battles", "Eddiefrb"]
26+    assert config.default_description == "Made with paws :3"
27+    assert config.content_dir == "./content"
28+    assert config.assets_dir == "./assets"
29+    assert config.templates_dir == "./templates"
30+    assert config.output_dir == "./output"
31+    assert config.extra.get("fav_frb_creators")
32+    fav_frb_creators = config.extra.get("fav_frb_creators")
33+    assert isinstance(fav_frb_creators, list)
34+    assert fav_frb_creators == [
35+      "PowerPoint Rap Battles",
36+      "AdamDRB",
37+      "worms_of_cans",
38+      "Indie Game Rap Battles",
39+      "Eddiefrb",
40+    ]
41+    nav_links = config.extra.get("nav_links")
42+    assert isinstance(nav_links, list)
43+    assert nav_links == [
44+      "index",
45+      "ascii_fop",
46+      "hello",
47+    ]