""" Cover-page generator for transcript and summary DOCX files. Layout (all centered): - 5 blank lines - 3 blank lines - Title in uppercase: "TRANSCRIPT" or "SUMMARY" - Next line: date of transcription (e.g. "June 19, 2026") - Next line: "Created by " - 3 blank lines - Disclaimer (underlined) - Page break (ensures content starts on page 2) Environment variables: - COVER_PAGE_ENABLED: "true"/"false" (default: false) - COVER_PAGE_ORGANIZATION: e.g., "A.P.Strom" - SERVER_TIMEZONE: Timezone for document dates (e.g., "America/Toronto"). Defaults to "UTC". """ import os from datetime import datetime from typing import Optional from zoneinfo import ZoneInfo, ZoneInfoNotFoundError from docx import Document from docx.shared import Pt from docx.enum.text import WD_ALIGN_PARAGRAPH from docx.oxml import OxmlElement from docx.oxml.ns import qn def _get_server_timezone(): tz_name = (os.getenv("SERVER_TIMEZONE") or "UTC").strip() try: return ZoneInfo(tz_name) except (ZoneInfoNotFoundError, KeyError, ValueError): return ZoneInfo("UTC") def _add_centered_paragraph(doc: Document, text: str = "", font_size: Pt = Pt(12), bold: bool = False, underline: bool = False): """Add a centered paragraph with given text and style.""" p = doc.add_paragraph() p.alignment = WD_ALIGN_PARAGRAPH.CENTER if text: run = p.add_run(text) run.font.name = "Courier" run.font.size = font_size run.bold = bold run.underline = underline return p def _add_blank_lines(doc: Document, count: int): """Add specified number of blank lines (empty centered paragraphs).""" for _ in range(count): _add_centered_paragraph(doc) def _add_page_break(doc: Document): """Insert a page break paragraph to force next content to page 2.""" p = doc.add_paragraph() pPr = p._p.get_or_add_pPr() # Clean existing formatting for child in list(pPr): tag = child.tag.split("}")[-1] if "}" in child.tag else child.tag if tag in ("tabs", "spacing", "ind"): pPr.remove(child) page_break = OxmlElement("w:pageBreak") page_break.set("{http://schemas.openxmlformats.org/wordprocessingml/2006/main}val", "1") pPr.append(page_break) def add_cover_page( doc: Document, title: str, date_str: Optional[str] = None, ): """ Insert a cover page at the current cursor position. - title: e.g., "TRANSCRIPT" or "SUMMARY" - date_str: optional date string (e.g., "June 19, 2026"); if not provided, uses current server time in SERVER_TIMEZONE. """ # 5 blank lines _add_blank_lines(doc, 5) # 3 blank lines _add_blank_lines(doc, 3) # Title in uppercase _add_centered_paragraph(doc, text=title.upper().strip(), font_size=Pt(18), bold=True) # Date of transcription (use provided or current server time) if not date_str: tz = _get_server_timezone() now = datetime.now(tz) date_str = now.strftime("%B %d, %Y") _add_centered_paragraph(doc, text=date_str, font_size=Pt(14)) # Created by + organization org = (os.getenv("COVER_PAGE_ORGANIZATION") or "").strip() if org: _add_centered_paragraph(doc, text=f"Created by {org}", font_size=Pt(12)) # 3 blank lines _add_blank_lines(doc, 3) # Disclaimer: only the word "Disclaimer" is underlined disclaimer_title = "Disclaimer" disclaimer_body = ( "This transcription and any summary derived therefrom may contain errors or inaccuracies." ) # Underlined "Disclaimer" line p = _add_centered_paragraph(doc, text=disclaimer_title, font_size=Pt(10), underline=True) # Body text (not underlined) _add_centered_paragraph(doc, text=disclaimer_body, font_size=Pt(10), underline=False) # Page break after cover page so main content starts on page 2 _add_page_break(doc)