diff --git a/backend/app/services/handoff_email_templates.py b/backend/app/services/handoff_email_templates.py index f63451e..c5df823 100644 --- a/backend/app/services/handoff_email_templates.py +++ b/backend/app/services/handoff_email_templates.py @@ -1,3 +1,4 @@ +from datetime import datetime from html import escape @@ -25,13 +26,72 @@ def format_sender_line(sender: dict) -> str: name = (sender.get("name") or "").strip() address = (sender.get("address") or "").strip() if not address: - return "unknown sender" + return name or "unknown sender" local = address.split("@", 1)[0].lower() if name and name.lower() not in {local, address.lower()}: return f"{name} <{address}>" return address +def sender_display_name(sender: dict | None) -> str: + sender = sender or {} + name = (sender.get("name") or "").strip() + address = (sender.get("address") or "").strip() + if name: + return name + if address: + return address.split("@", 1)[0].replace(".", " ").replace("_", " ").replace("-", " ").title() + return "unknown sender" + + +def _attribution_date(value) -> str: + if not isinstance(value, datetime): + return "" + return value.strftime("%a, %b %d, %Y at %I:%M %p").replace(" 0", " ") + + +def build_gmail_quote( + *, + sender: dict | None, + event_at, + body_text: str | None, + body_html: str | None, +) -> tuple[str, str]: + identity = format_sender_line(sender or {}) + date = _attribution_date(event_at) + attribution = f"On {date} {identity} wrote:" if date else f"{identity} wrote:" + text_source = (body_text or "").rstrip() + quoted_lines = [f"> {line}" if line else ">" for line in text_source.splitlines()] + quoted_text = f"{attribution}\n" + "\n".join(quoted_lines) + inner_html = (body_html or "").strip() or ( + f"
{escape(text_source).replace(chr(10), '
')}
" + ) + quoted_html = ( + f'
' + f'
{escape(attribution)}
' + f'
' + f"{inner_html}" + f"
" + ) + return quoted_text, quoted_html + + +def attach_quoted_history( + *, + new_text: str, + new_html: str | None, + quoted_text: str, + quoted_html: str, +) -> tuple[str, str]: + body_text = f"{new_text.rstrip()}\n\n{quoted_text}".strip() + visible_html = (new_html or "").strip() or ( + f"
{escape(new_text).replace(chr(10), '
')}
" + ) + body_html = f"{visible_html}
{quoted_html}" + return body_text, body_html + + def _footer_html(agent_email: str) -> str: return f"""