From 6775f982599ca3e61a2fc0ae8cd8e3e2d9c884cc Mon Sep 17 00:00:00 2001 From: "thomas.kopp" Date: Wed, 1 Apr 2026 02:14:57 +0200 Subject: [PATCH] =?UTF-8?q?feat:=20output=20module=20=E2=80=94=20Markdown?= =?UTF-8?q?=20file=20writer=20with=20slugified=20filenames?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- output.py | 50 ++++++++++++++++++++++++++++++++++++ tests/test_output.py | 60 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 110 insertions(+) create mode 100644 output.py create mode 100644 tests/test_output.py diff --git a/output.py b/output.py new file mode 100644 index 0000000..46635da --- /dev/null +++ b/output.py @@ -0,0 +1,50 @@ +import os +import re +import unicodedata +from datetime import datetime + + +def slugify(text: str) -> str: + for src, dst in [("ä","a"),("ö","o"),("ü","u"),("Ä","a"),("Ö","o"),("Ü","u"),("ß","ss")]: + text = text.replace(src, dst) + text = unicodedata.normalize("NFKD", text) + text = "".join(c for c in text if unicodedata.category(c) != "Mn") + text = text.lower() + text = re.sub(r"[^a-z0-9]+", "-", text) + return text.strip("-") + + +def save_transcript( + title: str, + content: str, + output_dir: str, + dt: datetime | None = None, +) -> str: + if dt is None: + dt = datetime.now() + slug = slugify(title)[:60] + filename = f"{dt.strftime('%Y-%m-%d-%H%M')}-{slug}.md" + os.makedirs(output_dir, exist_ok=True) + path = os.path.join(output_dir, filename) + with open(path, "w", encoding="utf-8") as f: + f.write(f"---\ndate: {dt.isoformat(timespec='seconds')}\ntags: [transkript]\n---\n\n") + f.write(f"# {title}\n\n") + f.write(content) + if not content.endswith("\n"): + f.write("\n") + return path + + +def list_transcripts(output_dir: str, limit: int = 20) -> list[dict]: + if not os.path.exists(output_dir): + return [] + files = sorted( + [f for f in os.listdir(output_dir) if f.endswith(".md")], + reverse=True, + )[:limit] + result = [] + for f in files: + full = os.path.join(output_dir, f) + stat = os.stat(full) + result.append({"filename": f, "path": full, "size": stat.st_size, "mtime": stat.st_mtime}) + return result diff --git a/tests/test_output.py b/tests/test_output.py new file mode 100644 index 0000000..fef93d3 --- /dev/null +++ b/tests/test_output.py @@ -0,0 +1,60 @@ +import os +import tempfile +from datetime import datetime + + +def test_save_transcript_creates_file(): + with tempfile.TemporaryDirectory() as tmpdir: + from output import save_transcript + path = save_transcript( + title="Test Aufnahme", + content="Dies ist ein Test.", + output_dir=tmpdir, + dt=datetime(2026, 4, 1, 14, 32, 0), + ) + assert os.path.exists(path) + + +def test_save_transcript_filename_format(): + with tempfile.TemporaryDirectory() as tmpdir: + from output import save_transcript + path = save_transcript( + title="Mein erstes Diktat", + content="Inhalt.", + output_dir=tmpdir, + dt=datetime(2026, 4, 1, 14, 32, 0), + ) + assert os.path.basename(path) == "2026-04-01-1432-mein-erstes-diktat.md" + + +def test_save_transcript_contains_frontmatter(): + with tempfile.TemporaryDirectory() as tmpdir: + from output import save_transcript + path = save_transcript( + title="Test", + content="Inhalt.", + output_dir=tmpdir, + dt=datetime(2026, 4, 1, 14, 32, 0), + ) + text = open(path).read() + assert "---" in text + assert "date:" in text + assert "transkript" in text + + +def test_save_transcript_contains_content(): + with tempfile.TemporaryDirectory() as tmpdir: + from output import save_transcript + path = save_transcript( + title="Test", + content="Das ist der Inhalt.", + output_dir=tmpdir, + dt=datetime(2026, 4, 1, 14, 32, 0), + ) + assert "Das ist der Inhalt." in open(path).read() + + +def test_slugify(): + from output import slugify + assert slugify("Mein erstes Diktat") == "mein-erstes-diktat" + assert slugify("test -- foo") == "test-foo"