Source

ec2control / ec2control / emailer.py

Full commit
import smtplib
from email.mime.text import MIMEText
import re
from mako.template import Template
import logging
log = logging.getLogger(__name__)

class ParseMail(object):
    def __init__(self, email):
        self.email = email
        self._parse(email)

    def _parse(self, data):
        lines = data.split("\n")
        orig_from = lines[0]
        if orig_from.startswith("From "):
            orig_from = re.split(r"\s", orig_from)[1]
        else:
            orig_from = None
        subject = None
        from_ = None
        command = None
        arguments = []
        for line in lines:
            if subject is None and line.startswith("Subject: "):
                tokens = re.split(r"\s+", line)
                command = tokens[1]
                arguments = tokens[2:]
            elif from_ is None and line.startswith("From: "):
                from_ = re.split(r"\s", line, 1)[1]
                m = re.match(r".*<(.*?)>\s*$", from_)
                if m:
                    from_ = m.group(1)

        self.effective_from = orig_from or from_
        self.command = command
        self.arguments = arguments

class Response(object):
    def __init__(self, config, parsed_struct):
        self.config = config
        self.parsed_struct = parsed_struct

    def send_started(self, instance):
        self._render(status="started", instance=instance)

    def send_command_error(self, exception, instance):
        self._render(status="command_error", exception=exception, instance=instance)

    def send_error(self, exception, instance):
        self._render(status="error", exception=exception, instance=instance)

    def _render(self, **kw):
        t = Template(filename=self.config['response_template'])
        body = t.render(**kw).strip()
        subject = t.get_def("subject").render(**kw).strip()
        self._send(subject, body)

    def _send(self, subject, message):

        msg = MIMEText(message)

        to_addr = self.parsed_struct.effective_from
        cc_addr = self.config['cc']

        msg['Subject'] = subject
        msg['From'] = from_addr = self.config['from_addr']
        msg['To'] = to_addr
        msg['Cc'] = cc_addr
        msg = msg.as_string()

        addrs = set([to_addr] + re.split(r',\s*', cc_addr))

        if from_addr in addrs:
            raise ValueError("From address %s is in the TO list, not sending" % from_addr)

        smtp = smtplib.SMTP(self.config['smtp_host'], int(self.config['smtp_port']))
        log.info("Sending mail to %s", ", ".join(addrs))
        log.info(subject)
        log.debug(message)

        for addr in addrs:
            smtp.sendmail(from_addr, addr, msg)