Catalyst / admin/Bid-Sentinel 14.8 GB / 57.8 GB 40.0 GB free
Help Sign in

admin / Bid-Sentinel

public

Bid Scrape and Tracking Application with AI Capability

Code Issues Pull requests Pipelines Packages Security Insights Wiki Settings
Bid-Sentinel / bid-sentinel-v2 / backend / app / mailer.py 1519 B · main
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
"""Outgoing email (SMTP). Reports are sent only to the logged-in user's own
address (enforced by the caller). Available only when SMTP_HOST is configured."""
from __future__ import annotations

import logging
from email.message import EmailMessage

import aiosmtplib

from app.config import settings

logger = logging.getLogger("mailer")


def is_available() -> bool:
    return bool(settings.smtp_host.strip())


async def send_report(
    to: str,
    subject: str,
    body: str,
    filename: str,
    content: bytes,
    content_type: str,
) -> None:
    """Send an email with a single file attachment. Raises on failure."""
    msg = EmailMessage()
    msg["From"] = settings.smtp_from or settings.smtp_username or "bid-sentinel@localhost"
    msg["To"] = to
    msg["Subject"] = subject
    msg.set_content(body)

    maintype, _, subtype = content_type.partition("/")
    msg.add_attachment(
        content,
        maintype=maintype or "application",
        subtype=subtype or "octet-stream",
        filename=filename,
    )

    kwargs: dict = {"hostname": settings.smtp_host, "port": settings.smtp_port}
    if settings.smtp_username:
        kwargs["username"] = settings.smtp_username
        kwargs["password"] = settings.smtp_password
    if settings.smtp_port == 465:
        kwargs["use_tls"] = True  # implicit TLS
    else:
        kwargs["start_tls"] = settings.smtp_starttls  # STARTTLS (e.g. port 587)

    await aiosmtplib.send(msg, **kwargs)
    logger.info("Emailed %r to %s", filename, to)