diff --git a/backend/services/regulars_v2.py b/backend/services/regulars_v2.py new file mode 100644 index 0000000..c2a6625 --- /dev/null +++ b/backend/services/regulars_v2.py @@ -0,0 +1,51 @@ +from dataclasses import dataclass +from pathlib import Path +import re + +HOME = Path.home() +VAULT = HOME / "code" / "dotfiles" +SILAS_DIR = VAULT / "silas" +REGULARS_DIR = VAULT / "regulars" +ARCHIVED_DIR = REGULARS_DIR / "archived" + + +@dataclass +class Regular: + name: str + voice: str + age: int + arc_state: str + lore_body: str + file_path: Path + + +def load_regular(path: Path) -> Regular: + text = path.read_text() + m = re.match(r"^---\n(.*?)\n---\n(.*)$", text, re.DOTALL) + if not m: + raise ValueError(f"No frontmatter in {path}") + fm_raw, body = m.group(1), m.group(2).strip() + fm = {} + for line in fm_raw.splitlines(): + if ":" in line: + k, v = line.split(":", 1) + fm[k.strip()] = v.strip() + return Regular( + name=fm["name"], + voice=fm["voice"], + age=int(fm["age"]), + arc_state=fm.get("arc_state", ""), + lore_body=body, + file_path=path, + ) + + +def load_all_active_regulars() -> list[Regular]: + out = [] + if SILAS_DIR.exists(): + for f in SILAS_DIR.glob("*.md"): + out.append(load_regular(f)) + if REGULARS_DIR.exists(): + for f in REGULARS_DIR.glob("*.md"): + out.append(load_regular(f)) + return out diff --git a/tests/test_regulars_v2.py b/tests/test_regulars_v2.py new file mode 100644 index 0000000..b8b496b --- /dev/null +++ b/tests/test_regulars_v2.py @@ -0,0 +1,27 @@ +from backend.services.regulars_v2 import Regular, load_regular, REGULARS_DIR, SILAS_DIR + + +def test_load_regular_parses_frontmatter_and_body(tmp_path): + lore_file = tmp_path / "silas.md" + lore_file.write_text("""--- +name: Silas +voice: Dennis +age: 54 +arc_state: Cult is splintering after the eclipse failure +--- + +# Silas + +Silas runs a small desert cult outside Truth or Consequences... + +## Arc Log + +- 2026-03-01: First call, introduced the cult +- 2026-03-20: Prophesied the eclipse +""") + reg = load_regular(lore_file) + assert reg.name == "Silas" + assert reg.voice == "Dennis" + assert reg.age == 54 + assert "splintering" in reg.arc_state + assert "Silas runs a small desert cult" in reg.lore_body