From 033c1fc4861eba31bb002c781023c4267a06654d Mon Sep 17 00:00:00 2001 From: "thomas.kopp" Date: Thu, 2 Apr 2026 01:05:07 +0200 Subject: [PATCH] =?UTF-8?q?feat:=20write=5Fmeeting=5Fdocs()=20=E2=80=94=20?= =?UTF-8?q?creates=20index,=20transkript,=20zusammenfassung?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- output.py | 67 ++++++++++++++++++++++++++++++++++++++++++++ tests/test_output.py | 23 +++++++++++++++ 2 files changed, 90 insertions(+) diff --git a/output.py b/output.py index fe82cf1..20e32d6 100644 --- a/output.py +++ b/output.py @@ -59,3 +59,70 @@ def list_transcripts(output_dir: str, limit: int = 20) -> list[dict]: stat = os.stat(full) result.append({"filename": f, "path": full, "size": stat.st_size, "mtime": stat.st_mtime}) return result + + +def write_meeting_docs( + aligned_segments: list[tuple[str, str]], + summary: str, + speakers: list[str], + duration_min: int, + output_dir: str, + dt: "datetime | None" = None, +) -> dict[str, str]: + """Write index, transkript, and zusammenfassung. Returns {type: path}.""" + if dt is None: + dt = datetime.now() + os.makedirs(output_dir, exist_ok=True) + base = dt.strftime("%Y-%m-%d-%H%M") + "-meeting" + date_str = dt.strftime("%d.%m.%Y %H:%M") + frontmatter_base = f"---\ndate: {dt.isoformat(timespec='seconds')}\ntags: [transkript, meeting]\n---\n\n" + + # --- transkript --- + transcript_lines = [] + for speaker, text in aligned_segments: + transcript_lines.append(f"**{speaker}:** {text}\n") + transcript_content = "\n".join(transcript_lines) + transkript_filename = f"{base}-transkript.md" + transkript_path = os.path.join(output_dir, transkript_filename) + with open(transkript_path, "w", encoding="utf-8") as f: + f.write(frontmatter_base) + f.write(transcript_content) + if not transcript_content.endswith("\n"): + f.write("\n") + + # --- zusammenfassung --- + zusammenfassung_filename = f"{base}-zusammenfassung.md" + zusammenfassung_path = os.path.join(output_dir, zusammenfassung_filename) + with open(zusammenfassung_path, "w", encoding="utf-8") as f: + f.write(frontmatter_base) + f.write(summary) + if not summary.endswith("\n"): + f.write("\n") + + # --- index --- + speaker_str = ", ".join(speakers) if speakers else "Unbekannt" + tl_dr = _extract_tldr(summary) + index_content = ( + f"# Meeting — {date_str}\n\n" + f"**Sprecher:** {speaker_str} \n" + f"**Dauer:** {duration_min} min\n\n" + f"> {tl_dr}\n\n" + f"- [Transkript]({transkript_filename})\n" + f"- [Zusammenfassung]({zusammenfassung_filename})\n" + ) + index_filename = f"{base}-index.md" + index_path = os.path.join(output_dir, index_filename) + with open(index_path, "w", encoding="utf-8") as f: + f.write(f"---\ndate: {dt.isoformat(timespec='seconds')}\ntags: [transkript, meeting, index]\n---\n\n") + f.write(index_content) + + return {"index": index_path, "transkript": transkript_path, "zusammenfassung": zusammenfassung_path} + + +def _extract_tldr(summary: str) -> str: + """Return the first non-heading, non-empty line from the summary as TL;DR.""" + for line in summary.splitlines(): + stripped = line.strip() + if stripped and not stripped.startswith("#"): + return stripped[:200] + return "Kein TL;DR verfügbar." diff --git a/tests/test_output.py b/tests/test_output.py index fef93d3..13bc88f 100644 --- a/tests/test_output.py +++ b/tests/test_output.py @@ -58,3 +58,26 @@ def test_slugify(): from output import slugify assert slugify("Mein erstes Diktat") == "mein-erstes-diktat" assert slugify("test -- foo") == "test-foo" + + +def test_write_meeting_docs_creates_three_files(tmp_path): + from output import write_meeting_docs + from datetime import datetime + aligned = [("Thomas", "Gut, dann fangen wir an."), ("Möller", "Ich hab das vorbereitet.")] + paths = write_meeting_docs( + aligned_segments=aligned, + summary="# Meeting\n\n## Wichtigste Punkte\n- Budget besprochen", + speakers=["Thomas", "Möller"], + duration_min=5, + output_dir=str(tmp_path), + dt=datetime(2026, 4, 2, 14, 30), + ) + assert len(paths) == 3 + index_content = open(paths["index"]).read() + assert "Thomas" in index_content + assert "transkript" in index_content + transcript_content = open(paths["transkript"]).read() + assert "**Thomas:**" in transcript_content + assert "Gut, dann fangen wir an." in transcript_content + summary_content = open(paths["zusammenfassung"]).read() + assert "Budget besprochen" in summary_content