#!/usr/bin/env python3 """TeamPulse — Teams meeting chat audit tool. Usage: .venv/bin/python main.py [meeting-url] If no URL is given, the clipboard is checked for a Teams meeting link. If neither yields a URL, navigate manually in the browser window. Post !start "Presenter Name" and !stop in the chat to define a time window. A Markdown memo is saved to the current directory when the window closes. """ import platform import subprocess import sys from pathlib import Path sys.path.insert(0, str(Path(__file__).parent / "src")) from playwright.sync_api import sync_playwright from teampulse.auth import create_context, ensure_logged_in from teampulse.memo import generate_memo, save_memo from teampulse.models import AuditEntry from teampulse.monitor import Monitor from teampulse.resolver import Resolver CACHE_PATH = Path.home() / ".teampulse" / "cache.json" TEAMS_URL = "https://teams.microsoft.com" def _read_clipboard() -> str: try: system = platform.system() if system == "Darwin": return subprocess.check_output(["pbpaste"]).decode("utf-8").strip() elif system == "Linux": return subprocess.check_output(["xclip", "-selection", "clipboard", "-o"]).decode("utf-8").strip() elif system == "Windows": return subprocess.check_output( ["powershell", "-command", "Get-Clipboard"], text=True ).strip() except Exception: pass return "" def _get_meeting_url() -> str | None: if len(sys.argv) > 1: url = sys.argv[1].strip() if "teams.microsoft.com" in url or "teams.live.com" in url: print(f"Meeting-URL aus Argument: {url[:60]}...") return url clip = _read_clipboard() if "teams.microsoft.com" in clip or "teams.live.com" in clip: print(f"Meeting-URL aus Clipboard: {clip[:60]}...") return clip return None def main(): meeting_url = _get_meeting_url() with sync_playwright() as playwright: print("Starte Browser...") context = create_context(playwright, headless=False) ensure_logged_in(context) page = context.new_page() if meeting_url: page.goto(meeting_url) else: page.goto(TEAMS_URL) print("\nKeine Meeting-URL gefunden — bitte im Browser zur Chat-Seite navigieren.") print("Tipp: Meeting-Link aus Teams kopieren, dann Skript neu starten.\n") monitor = Monitor(page=page, current_user="") print("Lese eingeloggten Nutzer...") current_user = monitor.get_current_user_display_name() monitor._current_user = current_user print(f"Eingeloggt als: {current_user}") print("\nPoste '!start \"Name des Vortragenden\"' im Chat um zu beginnen.\n") window = monitor.run() resolver = Resolver(cache_path=CACHE_PATH, page=page) print(f"\nLöse {len(window.entries)} E-Mail-Adresse(n) auf...") resolved_entries = [] for entry in window.entries: email = resolver.resolve(entry.display_name) print(f" {entry.display_name} → {email}") resolved_entries.append(AuditEntry(display_name=entry.display_name, email=email)) window.entries = resolved_entries memo_content = generate_memo(window) path = save_memo(memo_content) print(f"\nMemo gespeichert: {path}") print("\n" + memo_content) context.close() if __name__ == "__main__": main()