#!/usr/bin/env python3 """standup_bot.py — CLI Daily Standup Bot, Draft implementation. Reads ./standup.md, formats a dated summary, writes to ./standup-output/, and optionally emails via SMTP. Stdlib only. """ import argparse import os import smtplib import sys from datetime import date from email.mime.text import MIMEText from pathlib import Path REQUIRED_SECTIONS = ("## Yesterday", "## Today", "## Blockers") DEFAULT_INPUT = Path("./standup.md") DEFAULT_OUTPUT_DIR = Path("./standup-output") def parse_args(argv=None): p = argparse.ArgumentParser(description="Daily standup formatter") p.add_argument("--input", type=Path, default=DEFAULT_INPUT, help="standup markdown") p.add_argument("--out-dir", type=Path, default=DEFAULT_OUTPUT_DIR, help="output directory") p.add_argument("--to", default=None, help="recipient email (overrides STANDUP_TO)") return p.parse_args(argv) def read_standup(path: Path) -> str: if not path.exists(): print(f"error: {path} not found", file=sys.stderr) sys.exit(2) text = path.read_text(encoding="utf-8") missing = [s for s in REQUIRED_SECTIONS if s not in text] if missing: print(f"error: missing sections {missing!r} in {path}", file=sys.stderr) sys.exit(2) return text def format_summary(text: str, source_name: str, recipient: str | None = None) -> str: today = date.today().isoformat() lines = [f"# Standup — {today}", "", f"_Source: {source_name}_", ""] if recipient: lines.append(f"_Recipient: {recipient}_") lines.append("") for section in REQUIRED_SECTIONS: lines.append(section) lines.append("") capture = False for line in text.splitlines(): if line.strip() == section: capture = True continue if capture: if line.startswith("## ") and line.strip() != section: break lines.append(line) return "\n".join(lines) + "\n" def write_output(summary: str, out_dir: Path) -> Path: out_dir.mkdir(parents=True, exist_ok=True) out_path = out_dir / f"{date.today().isoformat()}.md" out_path.write_text(summary, encoding="utf-8") return out_path def maybe_email(summary: str, to_addr: str | None) -> None: host = os.environ.get("SMTP_HOST") user = os.environ.get("SMTP_USER") pwd = os.environ.get("SMTP_PASS") if not (host and user and pwd): return recipient = to_addr or os.environ.get("STANDUP_TO") if not recipient: return msg = MIMEText(summary) msg["Subject"] = f"Standup — {date.today().isoformat()}" msg["From"] = user msg["To"] = recipient with smtplib.SMTP(host) as s: s.login(user, pwd) s.send_message(msg) def main(argv=None) -> int: args = parse_args(argv) text = read_standup(args.input) summary = format_summary(text, str(args.input), args.to) print(summary, end="") write_output(summary, args.out_dir) maybe_email(summary, args.to) return 0 if __name__ == "__main__": sys.exit(main())