diff --git a/src/teampulse/memo.py b/src/teampulse/memo.py new file mode 100644 index 0000000..993f10c --- /dev/null +++ b/src/teampulse/memo.py @@ -0,0 +1,49 @@ +from datetime import datetime +from pathlib import Path + +from teampulse.models import AuditWindow + + +def generate_memo(window: AuditWindow) -> str: + filtered = [ + e for e in window.entries + if e.display_name != window.presenter and e.display_name != window.moderator + ] + sorted_entries = sorted(filtered, key=lambda e: e.email) + + start = window.start_time.strftime("%H:%M:%S") + end = window.end_time.strftime("%H:%M:%S") + + lines = [ + "# Meeting Chat Audit", + f"Zeitfenster: {start} – {end}", + "", + ] + + if not sorted_entries: + lines += [ + f"## Teilnehmer am Vortrag von {window.presenter} (0)", + f"_Moderator: {window.moderator} — Vortragender und Moderator ausgeschlossen_", + "", + "_Keine Chat-Aktivität in diesem Zeitfenster._", + ] + else: + lines += [ + f"## Teilnehmer am Vortrag von {window.presenter} ({len(sorted_entries)})", + f"_Moderator: {window.moderator} — Vortragender und Moderator ausgeschlossen_", + "", + ] + for entry in sorted_entries: + lines.append(f"- {entry.display_name} <{entry.email}>") + + created = datetime.now().strftime("%Y-%m-%d %H:%M") + lines += ["", f"_Sortiert nach E-Mail-Adresse. Erstellt: {created}_"] + return "\n".join(lines) + + +def save_memo(content: str, directory: Path = Path("."), timestamp: datetime | None = None) -> Path: + ts = timestamp or datetime.now() + filename = f"audit_{ts.strftime('%Y%m%d_%H%M')}.md" + path = directory / filename + path.write_text(content, encoding="utf-8") + return path diff --git a/tests/test_memo.py b/tests/test_memo.py new file mode 100644 index 0000000..56a61dd --- /dev/null +++ b/tests/test_memo.py @@ -0,0 +1,85 @@ +from datetime import datetime +from pathlib import Path + +import pytest + +from teampulse.memo import generate_memo, save_memo +from teampulse.models import AuditEntry, AuditWindow + + +def make_window(**kwargs): + defaults = dict( + presenter="Anna Bauer", + moderator="Oliver Hofmann", + start_time=datetime(2026, 5, 16, 10, 3, 42), + end_time=datetime(2026, 5, 16, 10, 47, 15), + entries=[ + AuditEntry("Thomas Wolf", "t.wolf@company.com"), + AuditEntry("Klaus Huber", "k.huber@company.com"), + AuditEntry("Sandra Vogel", "s.vogel@company.com"), + ], + ) + defaults.update(kwargs) + return AuditWindow(**defaults) + + +def test_memo_contains_presenter_name(): + result = generate_memo(make_window()) + assert "Anna Bauer" in result + + +def test_memo_contains_time_window(): + result = generate_memo(make_window()) + assert "10:03:42" in result + assert "10:47:15" in result + + +def test_memo_sorts_entries_by_email(): + result = generate_memo(make_window()) + idx_huber = result.index("k.huber@company.com") + idx_vogel = result.index("s.vogel@company.com") + idx_wolf = result.index("t.wolf@company.com") + assert idx_huber < idx_vogel < idx_wolf + + +def test_memo_excludes_presenter(): + window = make_window( + entries=[ + AuditEntry("Anna Bauer", "a.bauer@company.com"), + AuditEntry("Klaus Huber", "k.huber@company.com"), + ] + ) + result = generate_memo(window) + assert "a.bauer@company.com" not in result + assert "k.huber@company.com" in result + + +def test_memo_excludes_moderator(): + window = make_window( + entries=[ + AuditEntry("Oliver Hofmann", "o.hofmann@company.com"), + AuditEntry("Klaus Huber", "k.huber@company.com"), + ] + ) + result = generate_memo(window) + assert "o.hofmann@company.com" not in result + assert "k.huber@company.com" in result + + +def test_memo_empty_window(): + window = make_window(entries=[]) + result = generate_memo(window) + assert "Keine Chat-Aktivität" in result + + +def test_memo_contains_moderator_note(): + result = generate_memo(make_window()) + assert "Oliver Hofmann" in result + + +def test_save_memo_writes_file(tmp_path): + window = make_window() + path = save_memo(generate_memo(window), directory=tmp_path, timestamp=datetime(2026, 5, 16, 10, 51)) + assert path.exists() + assert path.name == "audit_20260516_1051.md" + assert "Anna Bauer" in path.read_text()