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'^(?Psmtps?)://(?P[\w.-]+)(:(?P\d+))?$') @implementer(IMailService) class MailService: def __init__(self): cfg = component.getUtility(IConfig) smtp_url = cfg.get('mail_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('mail_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 ', f'{user.cn} <{user.uid}@{self.base_domain}>', {'Subject': 'Welcome to the Computer Science Club'}, body, )