Skip to content

Commit

Permalink
feat($message): support sending redered HTML in email
Browse files Browse the repository at this point in the history
render HTML template via Jinjia2,
and then send it via email

BREAKING CHANGE: support sending redered HTML in email
  • Loading branch information
johnnymillergh committed Nov 9, 2021
1 parent 094a6ff commit f423fec
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 27 deletions.
85 changes: 58 additions & 27 deletions home_guardian/message/email.py
Original file line number Diff line number Diff line change
@@ -1,52 +1,83 @@
import datetime
import smtplib
from email.header import Header
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from typing import List

from loguru import logger

from home_guardian.configuration.application_configuration import application_conf
from home_guardian.template.html_template import render_template

mail_host: str = application_conf.get_string("email.mail_host")
mail_user: str = application_conf.get_string("email.mail_user")
mail_password: str = application_conf.get_string("email.mail_password")
sender: str = f"{mail_user}{application_conf.get_string('email.mail_address_suffix')}"
receivers: List[str] = application_conf.get_list("email.receivers")
_mail_host: str = application_conf.get_string("email.mail_host")
_mail_username: str = application_conf.get_string("email.mail_username")
_mail_password: str = application_conf.get_string("email.mail_password")
_sender: str = (
f"{_mail_username}{application_conf.get_string('email.mail_address_suffix')}"
)
_receivers: List[str] = application_conf.get_list("email.receivers")


def build_message(receiver: str) -> MIMEMultipart:
def build_message(
subject: str,
receiver: str,
template_name: str,
render_dict: dict,
picture_path: str,
) -> MIMEMultipart:
"""
Builds a message with the given subject, receiver, template name and render dict.
:param subject: The subject of the message.
:param receiver: The receiver of the message.
:param template_name: The name of the template to render.
:param render_dict: The render dict for the template.
:param picture_path: The path to the picture to attach.
"""
content: MIMEText = MIMEText(
"This is a email from Python "
+ datetime.datetime.now().strftime("%Y-%m-%d %T"),
"plain",
"utf-8",
)
message: MIMEMultipart = MIMEMultipart()
message["Subject"] = Header(
"Emergency Security Alert, at "
+ datetime.datetime.now().strftime("%Y-%m-%d %T"),
render_template(template_name, render_dict),
"html",
"utf-8",
)
message["From"] = Header(sender)
message: MIMEMultipart = MIMEMultipart("related")
message["Subject"] = Header(subject, "utf-8").encode()
message["From"] = Header(_sender)
message["To"] = Header(receiver)
message["Cc"] = Header(sender)
message["Cc"] = Header(_sender)
message.attach(content)
file = open(picture_path, "rb")
img_data = file.read()
file.close()
img = MIMEImage(img_data)
img.add_header("Content-ID", render_dict["content_id"])
message.attach(img)
return message


def send_email() -> None:
smtp: smtplib.SMTP = smtplib.SMTP(mail_host, 25)
smtp.connect(mail_host, 25)
smtp.login(sender, mail_password)
for receiver in receivers:
message: MIMEMultipart = build_message(receiver)
def send_email(
subject: str, template_name: str, render_dict: dict, picture_path: str
) -> None:
"""
Sends an email with the given subject, template name and render dict.
:param subject: The subject of the message.
:param template_name: The name of the template to render.
:param render_dict: The render dict for the template.
:param picture_path: The path to the picture to attach.
"""
smtp: smtplib.SMTP = smtplib.SMTP(_mail_host, 25)
smtp.connect(_mail_host, 25)
smtp.login(_sender, _mail_password)
for receiver in _receivers:
message: MIMEMultipart = build_message(
subject, receiver, template_name, render_dict, picture_path
)
logger.info(f"Sending email. receiver: {receiver}")
try:
logger.info(f"Sending email. receiver: {receiver}")
smtp.sendmail(sender, [receiver], message.as_string())
smtp.sendmail(_sender, [receiver], message.as_string())
logger.info(
f"Sent email successfully. {smtp}. receiver: {receiver}, message: {message}"
f"Sent email successfully. Receiver: {receiver}, subject: {subject}, template_name: {template_name}"
)
except smtplib.SMTPException:
logger.exception("Exception occurred while sending email!")
Expand Down
13 changes: 13 additions & 0 deletions home_guardian/resources/html_template/security_warning.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Security Warning: {{ subject }}</title>
</head>
<body>
<p style="font-size:18px; font-family:Arial,serif; font-weight:bold">{{ content }}</p>
<p style="font-size:15px; font-family:Arial,serif;">Warning time: {{ warning_time }}</p>
<hr>
<img src="cid:{{ content_id }}" alt="A capture">
</body>
</html>

0 comments on commit f423fec

Please sign in to comment.