view MoinMoin/util/ @ 58:285ba792d278

use Header() for From: and To:, too imported from: moin--main--1.5--patch-60
author Thomas Waldmann <>
date Fri, 30 Sep 2005 17:44:41 +0000
parents aedb415dc3a4
children 26270b13f6df
line wrap: on
line source

# -*- coding: iso-8859-1 -*-
    MoinMoin - email helper functions

    @copyright: 2003 by Jürgen Hermann <>
    @license: GNU GPL, see COPYING for details.

import os

_transdict = {"AT": "@", "DOT": ".", "DASH": "-"}

def sendmail(request, to, subject, text, **kw):
    """ Create and send a text/plain message
    Return a tuple of success or error indicator and message.
    @param request: the request object
    @param to: recipients (list)
    @param subject: subject of email (unicode)
    @param text: email body text (unicode)
    @keyword mail_from: override default mail_from (string)
    @rtype: tuple
    @return: (is_ok, Description of error or OK message)
    import smtplib, socket
    from email.Message import Message
    from email.Charset import Charset, QP
    from email.Utils import formatdate, make_msgid
    from email.Header import Header
    from MoinMoin import config

    _ = request.getText
    cfg = request.cfg    
    mail_from = kw.get('mail_from', '') or cfg.mail_from
    mail_from = Header(mail_from)
    subject = subject.encode(config.charset)    

    # Create a text/plain body using CRLF (see RFC2822)
    text = text.replace(u'\n', u'\r\n')
    text = text.encode(config.charset)

    # Create a message using config.charset and quoted printable
    # encoding, which should be supported better by mail clients.
    # TODO: check if its really works better for major mail clients
    msg = Message()
    charset = Charset(config.charset)
    charset.header_encoding = QP
    charset.body_encoding = QP
    # Create message headers
    # Don't expose emails addreses of the other subscribers, instead we
    # use the same mail_from, e.g. "My Wiki <>"
    msg['From'] = mail_from
    msg['To'] = mail_from
    msg['Date'] = formatdate()
    msg['Message-ID'] = make_msgid()
    msg['Subject'] = Header(subject, charset)
    if cfg.mail_sendmail:
        # Set the BCC.  This will be stripped later by sendmail.
        msg['BCC'] = ','.join(to)
        # Set Return-Path so that it isn't set (generally incorrectly) for us.
        msg['Return-Path'] = mail_from

    # Send the message
    if not cfg.mail_sendmail:
            server = smtplib.SMTP(cfg.mail_smarthost)
                if cfg.mail_login:
                    user, pwd = cfg.mail_login.split()
                    try: # try to do tls
                        if server.has_extn('starttls'):
                    server.login(user, pwd)
                server.sendmail(mail_from, to, msg.as_string())
                except AttributeError:
                    # in case the connection failed, SMTP has no "sock" attribute
        except smtplib.SMTPException, e:
            return (0, str(e))
        except (os.error, socket.error), e:
            return (0, _("Connection to mailserver '%(server)s' failed: %(reason)s") % {
                'server': cfg.mail_smarthost, 
                'reason': str(e)
            sendmailp = os.popen(cfg.mail_sendmail, "w") 
            # msg contains everything we need, so this is a simple write
            sendmail_status = sendmailp.close()
            if sendmail_status:
                return (0, str(sendmail_status))
            return (0, _("Mail not sent"))

    return (1, _("Mail sent OK"))

def decodeSpamSafeEmail(address):
    """ Decode obfuscated email address to standard email address

    Decode a spam-safe email address in `address` by applying the
    following rules:
    Known all-uppercase words and their translation:
        "DOT"   -> "."
        "AT"    -> "@"
        "DASH"  -> "-"

    Any unknown all-uppercase words simply get stripped.
    Use that to make it even harder for spam bots!

    Blanks (spaces) simply get stripped.
    @param address: obfuscated email address string
    @rtype: string
    @return: decoded email address
    email = []

    # words are separated by blanks
    for word in address.split():
        # is it all-uppercase?
        if word.isalpha() and word == word.upper():
            # strip unknown CAPS words
            word = _transdict.get(word, '')

    # return concatenated parts
    return ''.join(email)