예제 #1
0
    def send(self,
             to,
             subject,
             body,
             cc=None,
             attachs=(),
             mimetype='text/plain',
             charset=None,
             _callback=None):
        if attachs:
            msg = MIMEMultipart()
        else:
            msg = MIMENonMultipart(*mimetype.split('/', 1))

        to = list(arg_to_iter(to))
        cc = list(arg_to_iter(cc))

        msg['From'] = self.mailfrom
        msg['To'] = COMMASPACE.join(to)
        msg['Date'] = formatdate(localtime=True)
        msg['Subject'] = subject
        rcpts = to[:]
        if cc:
            rcpts.extend(cc)
            msg['Cc'] = COMMASPACE.join(cc)

        if charset:
            msg.set_charset(charset)

        if attachs:
            msg.attach(MIMEText(body, 'plain', charset or 'us-ascii'))
            for attach_name, mimetype, f in attachs:
                part = MIMEBase(*mimetype.split('/'))
                part.set_payload(f.read())
                Encoders.encode_base64(part)
                part.add_header('Content-Disposition', 'attachment; filename="%s"' \
                    % attach_name)
                msg.attach(part)
        else:
            msg.set_payload(body)

        if _callback:
            _callback(to=to,
                      subject=subject,
                      body=body,
                      cc=cc,
                      attach=attachs,
                      msg=msg)

        if self.debug:
            logger.debug(
                'Debug mail sent OK: To=%(mailto)s Cc=%(mailcc)s '
                'Subject="%(mailsubject)s" Attachs=%(mailattachs)d', {
                    'mailto': to,
                    'mailcc': cc,
                    'mailsubject': subject,
                    'mailattachs': len(attachs)
                })
            return

        dfd = self._sendmail(rcpts, msg.as_string().encode(charset or 'utf-8'))
        dfd.addCallbacks(self._sent_ok,
                         self._sent_failed,
                         callbackArgs=[to, cc, subject,
                                       len(attachs)],
                         errbackArgs=[to, cc, subject,
                                      len(attachs)])
        reactor.addSystemEventTrigger('before', 'shutdown', lambda: dfd)
        return dfd
예제 #2
0
def send_email(xfrom,
               to,
               subject,
               body,
               cc=None,
               bcc=None,
               attachments=None,
               host=None):
    if not has_len(host):
        host = 'localhost'

    outer = MIMEMultipart()

    if has_len(xfrom):
        outer['From'] = xfrom
    elif isinstance(xfrom, (list, tuple)) and len(xfrom) == 2:
        outer['From'] = "%s <%s>" % (Header(unidecoder(xfrom[0]),
                                            'utf-8'), xfrom[1])
        xfrom = xfrom[1]
    else:
        raise ValueError("Invalid e-mail sender. (from: %r)" % xfrom)

    outer['Date'] = formatdate(localtime=True)
    smtp = smtplib.SMTP(host)

    if has_len(to):
        to = [to]

    if isinstance(to, (list, tuple)):
        to = list(to)
        outer['To'] = COMMASPACE.join(list(to))
    else:
        raise ValueError("Invalid e-mail recipients. (to: %r)" % to)

    if has_len(cc):
        cc = [cc]

    if isinstance(cc, (list, tuple)):
        to += list(cc)
        outer['Cc'] = COMMASPACE.join(list(cc))

    if has_len(bcc):
        bcc = [bcc]

    if isinstance(bcc, (list, tuple)):
        to += list(bcc)

    if has_len(subject):
        outer['Subject'] = Header(unidecoder(subject), 'utf-8')

    if has_len(body):
        outer.attach(MIMEText(unidecoder(body), _charset='utf-8'))

    if has_len(attachments):
        attachments = [attachments]

    if attachments:
        if isinstance(attachments, (list, tuple)):
            attachments = dict(
                zip(attachments,
                    len(attachments) * ('application/octet-stream', )))

        for attachment in sorted(iterkeys(attachments)):
            fp = open(attachment, 'rb')
            part = MIMEBase('application', 'octet-stream')
            part.set_type(attachments[attachment])
            filename = os.path.basename(attachment)
            part.set_payload(fp.read())
            fp.close()
            encoders.encode_base64(part)
            part.add_header('Content-Disposition',
                            'attachment',
                            filename=filename)
            outer.attach(part)

    smtp.sendmail(xfrom, to, outer.as_string())
    smtp.quit()