Coverage for app / backend / src / couchers / email / send.py: 100%
17 statements
« prev ^ index » next coverage.py v7.13.2, created at 2026-02-03 06:18 +0000
« prev ^ index » next coverage.py v7.13.2, created at 2026-02-03 06:18 +0000
1from typing import Any
3from sqlalchemy.orm import Session
5from couchers.config import config
6from couchers.email import queue_email
7from couchers.i18n import LocalizationContext
8from couchers.templating import Jinja2Template, template_folder
9from couchers.utils import now
12def send_simple_pretty_email(
13 session: Session, recipient: str, subject: str, template_name: str, template_args: dict[str, Any]
14) -> None:
15 """
16 This is a simplified version of couchers.notifications.background._send_email_notification
18 It's for the few security emails where we don't have a user to email but send directly to an email address.
19 """
21 # Not yet localizable
22 loc_context = LocalizationContext.en_utc()
24 template_args = {
25 **template_args,
26 "header_subject": subject,
27 "footer_timezone_name": loc_context.localized_timezone,
28 "footer_copyright_year": now().year,
29 "footer_email_is_critical": True, # Results in no unsubscribe footer.
30 }
32 # Format plaintext template
33 plain_tmplt_body = (template_folder / f"{template_name}.txt").read_text()
34 plain_tmplt_footer = (template_folder / "_footer.txt").read_text()
35 plain_tmplt = Jinja2Template(source=plain_tmplt_body + plain_tmplt_footer, html=False)
36 plain = plain_tmplt.render(template_args, loc_context)
38 # Format html template
39 html_tmplt = Jinja2Template(
40 source=(template_folder / "generated_html" / f"{template_name}.html").read_text(), html=True
41 )
42 html = html_tmplt.render(template_args, loc_context)
44 queue_email(
45 session,
46 sender_name=config["NOTIFICATION_EMAIL_SENDER"],
47 sender_email=config["NOTIFICATION_EMAIL_ADDRESS"],
48 recipient=recipient,
49 subject=config["NOTIFICATION_PREFIX"] + subject,
50 plain=plain,
51 html=html,
52 source_data=config["VERSION"] + f"/{template_name}",
53 )