pyceo/ceod/model/MailService.py

64 lines
2.1 KiB
Python

import datetime
from email.message import EmailMessage
import re
import smtplib
from typing import Dict
import jinja2
from zope import component
from zope.interface import implementer
from ceo_common.interfaces import IMailService, IConfig, IUser
smtp_url_re = re.compile(r'^(?P<scheme>smtps?)://(?P<host>[\w.-]+)(:(?P<port>\d+))?$')
@implementer(IMailService)
class MailService:
def __init__(self):
cfg = component.getUtility(IConfig)
smtp_url = cfg.get('smtp_url')
match = smtp_url_re.match(smtp_url)
if match is None:
raise Exception('Invalid SMTP URL: %s' % smtp_url)
self.smtps = match.group('scheme') == 'smtps'
self.host = match.group('host')
self.port = int(match.group('port') or 25)
self.starttls = cfg.get('smtp_starttls')
assert not (self.smtps and self.starttls)
self.base_domain = cfg.get('base_domain')
self.jinja_env = jinja2.Environment(
loader=jinja2.PackageLoader('ceod.model'),
)
def send(self, _from: str, to: str, headers: Dict[str, str], content: str):
msg = EmailMessage()
msg.set_content(content)
msg['From'] = _from
msg['To'] = to
msg['Date'] = datetime.datetime.now().astimezone().strftime('%a, %d %b %Y %H:%M:%S %z')
for key, val in headers.items():
msg[key] = val
if self.smtps:
client = smtplib.SMTP_SSL(self.host, self.port)
else:
client = smtplib.SMTP(self.host, self.port)
if self.starttls:
client.starttls()
client.ehlo()
client.send_message(msg)
client.quit()
def send_welcome_message_to(self, user: IUser):
template = self.jinja_env.get_template('welcome_message.j2')
# TODO: store surname and givenName in LDAP
first_name = user.cn.split(' ', 1)[0]
body = template.render(name=first_name, user=user.uid)
self.send(
f'Computer Science Club <exec@{self.base_domain}>',
f'{user.cn} <{user.uid}@{self.base_domain}>',
{'Subject': 'Welcome to the Computer Science Club'},
body,
)