Add suject template, pretty_from field and more mail server configuration
All checks were successful
/ test (push) Successful in 13s

This commit is contained in:
phil 2024-12-13 15:57:40 +01:00
parent d159254fdf
commit ab824960ac
4 changed files with 237 additions and 38 deletions

View file

@ -11,7 +11,7 @@ from email.message import EmailMessage
from fastapi import FastAPI
from aiosmtplib import send
from pydantic import BaseModel, Field, EmailStr
from pydantic import BaseModel, Field, computed_field
from pydantic_settings import BaseSettings, SettingsConfigDict
USER = os.environ.get("USER", "root")
@ -24,14 +24,12 @@ class MailSettings(BaseSettings):
enable: bool = True
sender: str = f"{USER}@{HOST_NAME}"
to: str = f"{USER}@{HOST_NAME}"
server: str = "localhost"
server_port: int = 25
server_start_tls: bool = False
subject: str = "SMS from {pretty_from}"
template: str = textwrap.dedent(
"""\
{text}
---
From: {from} {fromName}
From: {pretty_from}
Sent: {sentStamp:%c}
Received: {receivedStamp:%c}
Sim: {sim}
@ -39,19 +37,38 @@ class MailSettings(BaseSettings):
)
class MailServerSettings(BaseSettings):
model_config = SettingsConfigDict(env_prefix="SMS_HANDLER_MAIL_SERVER_")
hostname: str = "localhost"
port: int = 25
username: str | None = None
password: str | None = None
start_tls: bool = False
use_tls: bool = False
class Settings(BaseSettings):
model_config = SettingsConfigDict(env_prefix="SMS_HANDLER_")
mail: MailSettings = MailSettings()
mail_server: MailServerSettings = MailServerSettings()
class SmsAlert(BaseModel):
from_: str = Field(alias="from") # "from" is reserved word in Python, use an alias
fromName: str = ""
from_: str = Field(alias="from")
fromName: str | None = None
text: str
sentStamp: datetime
receivedStamp: datetime
sim: str
@computed_field
@property
def pretty_from(self) -> str:
if self.fromName is not None:
return f"{self.fromName} ({self.from_})"
else:
return self.from_
settings = Settings()
app = FastAPI()
@ -59,17 +76,20 @@ app = FastAPI()
def send_mail(smsAlert: SmsAlert):
msg = EmailMessage()
msg["Subject"] = f"SMS from {smsAlert.from_}"
fmt = smsAlert.model_dump()
fmt["from"] = fmt.pop("from_")
msg["Subject"] = settings.mail.subject.format_map(fmt)
msg["From"] = settings.mail.sender
msg["To"] = settings.mail.to
fmt = dict(smsAlert) # Make a dict for sms
fmt["from"] = fmt.pop("from_")
msg.set_content(settings.mail.template.format_map(fmt))
return send(
msg,
hostname=settings.mail.server,
port=settings.mail.server_port,
start_tls=settings.mail.server_start_tls,
hostname=settings.mail_server.hostname,
username=settings.mail_server.username,
password=settings.mail_server.password,
port=settings.mail_server.port,
start_tls=settings.mail_server.start_tls,
use_tls=settings.mail_server.use_tls,
)
@ -85,26 +105,8 @@ def main():
from argparse import ArgumentParser
parser = ArgumentParser(description=__doc__)
parser.add_argument(
"-l", "--host", type=str, default="0.0.0.0", help="Addess to listen to"
)
parser.add_argument(
"-p", "--port", type=int, default=8025, help="Port to listen to"
)
parser.add_argument(
"-v", "--version", action="store_true", help="Print version and exit"
)
parser.add_argument("-l", "--host", default="0.0.0.0")
parser.add_argument("-p", "--port", type=int, default=8025)
args = parser.parse_args()
if args.version:
import sys
from importlib.metadata import version
print(version("sms_handler"))
sys.exit(0)
run(app, host=args.host, port=args.port)
if __name__ == "__main__":
main()