Back to index

moin  1.9.0~rc2
Functions | Variables
MoinMoin.mail.sendmail Namespace Reference

Functions

def encodeAddress
def sendmail
def encodeSpamSafeEmail
def decodeSpamSafeEmail

Variables

tuple logging = log.getLogger(__name__)
dictionary _transdict = {"AT": "@", "DOT": ".", "DASH": "-"}

Function Documentation

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 or an uppercase letter 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

Definition at line 199 of file sendmail.py.

00199 
00200 def decodeSpamSafeEmail(address):
00201     """ Decode obfuscated email address to standard email address
00202 
00203     Decode a spam-safe email address in `address` by applying the
00204     following rules:
00205 
00206     Known all-uppercase words and their translation:
00207         "DOT"   -> "."
00208         "AT"    -> "@"
00209         "DASH"  -> "-"
00210 
00211     Any unknown all-uppercase words or an uppercase letter simply get stripped.
00212     Use that to make it even harder for spam bots!
00213 
00214     Blanks (spaces) simply get stripped.
00215 
00216     @param address: obfuscated email address string
00217     @rtype: string
00218     @return: decoded email address
00219     """
00220     email = []
00221 
00222     # words are separated by blanks
00223     for word in address.split():
00224         # is it all-uppercase?
00225         if word.isalpha() and word == word.upper():
00226             # strip unknown CAPS words
00227             word = _transdict.get(word, '')
00228         email.append(word)
00229 
00230     # return concatenated parts
00231     return ''.join(email)
00232 

Here is the caller graph for this function:

def MoinMoin.mail.sendmail.encodeAddress (   address,
  charset 
)
Encode email address to enable non ascii names

e.g. '"Jürgen Hermann" <jh@web.de>'. According to the RFC, the name
part should be encoded, the address should not.

@param address: email address, possibly using '"name" <address>' format
@type address: unicode
@param charset: specifying both the charset and the encoding, e.g
                quoted printable or base64.
@type charset: email.Charset.Charset instance
@rtype: string
@return: encoded address

Definition at line 21 of file sendmail.py.

00021 
00022 def encodeAddress(address, charset):
00023     """ Encode email address to enable non ascii names
00024 
00025     e.g. '"Jürgen Hermann" <jh@web.de>'. According to the RFC, the name
00026     part should be encoded, the address should not.
00027 
00028     @param address: email address, possibly using '"name" <address>' format
00029     @type address: unicode
00030     @param charset: specifying both the charset and the encoding, e.g
00031                     quoted printable or base64.
00032     @type charset: email.Charset.Charset instance
00033     @rtype: string
00034     @return: encoded address
00035     """
00036     assert isinstance(address, unicode)
00037     composite = re.compile(r'(?P<phrase>.*?)(?P<blanks>\s*)<(?P<addr>.*)>', re.UNICODE)
00038     match = composite.match(address)
00039     if match:
00040         phrase = match.group('phrase')
00041         try:
00042             str(phrase)  # is it pure ascii?
00043         except UnicodeEncodeError:
00044             phrase = phrase.encode(config.charset)
00045             phrase = Header(phrase, charset)
00046         blanks = match.group('blanks')
00047         addr = match.group('addr')
00048         if phrase:
00049             return "%s%s<%s>" % (str(phrase), str(blanks), str(addr))
00050         else:
00051             return str(addr)
00052     else:
00053         # a pure email address, should encode to ascii without problem
00054         return str(address)
00055 

Here is the caller graph for this function:

def MoinMoin.mail.sendmail.encodeSpamSafeEmail (   email_address,
  obfuscation_text = '' 
)
Encodes a standard email address to an obfuscated address
@param email_address: mail address to encode.
                      Known characters and their all-uppercase words translation:
                      "." -> " DOT "
                      "@" -> " AT "
                      "-" -> " DASH "
@param obfuscation_text: optional text to obfuscate the email.
                         All characters in the string must be alphabetic
                         and they will be added in uppercase.

Definition at line 178 of file sendmail.py.

00178 
00179 def encodeSpamSafeEmail(email_address, obfuscation_text=''):
00180     """ Encodes a standard email address to an obfuscated address
00181     @param email_address: mail address to encode.
00182                           Known characters and their all-uppercase words translation:
00183                           "." -> " DOT "
00184                           "@" -> " AT "
00185                           "-" -> " DASH "
00186     @param obfuscation_text: optional text to obfuscate the email.
00187                              All characters in the string must be alphabetic
00188                              and they will be added in uppercase.
00189     """
00190     address = email_address.lower()
00191     # uppercase letters will be stripped by decodeSpamSafeEmail
00192     for word, sign in _transdict.items():
00193         address = address.replace(sign, ' %s ' % word)
00194     if obfuscation_text.isalpha():
00195         # is the obfuscation_text alphabetic
00196         address = address.replace(' AT ', ' AT %s ' % obfuscation_text.upper())
00197 
00198     return address

Here is the caller graph for this function:

def MoinMoin.mail.sendmail.sendmail (   request,
  to,
  subject,
  text,
  mail_from = None 
)
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)
@param mail_from: override default mail_from
@type mail_from: unicode
@rtype: tuple
@return: (is_ok, Description of error or OK message)

Definition at line 56 of file sendmail.py.

00056 
00057 def sendmail(request, to, subject, text, mail_from=None):
00058     """ Create and send a text/plain message
00059 
00060     Return a tuple of success or error indicator and message.
00061 
00062     @param request: the request object
00063     @param to: recipients (list)
00064     @param subject: subject of email (unicode)
00065     @param text: email body text (unicode)
00066     @param mail_from: override default mail_from
00067     @type mail_from: unicode
00068     @rtype: tuple
00069     @return: (is_ok, Description of error or OK message)
00070     """
00071     import smtplib, socket
00072     from email.Message import Message
00073     from email.Charset import Charset, QP
00074     from email.Utils import formatdate, make_msgid
00075 
00076     _ = request.getText
00077     cfg = request.cfg
00078     mail_from = mail_from or cfg.mail_from
00079 
00080     logging.debug("send mail, from: %r, subj: %r" % (mail_from, subject))
00081     logging.debug("send mail, to: %r" % (to, ))
00082 
00083     if not to:
00084         return (1, _("No recipients, nothing to do"))
00085 
00086     subject = subject.encode(config.charset)
00087 
00088     # Create a text/plain body using CRLF (see RFC2822)
00089     text = text.replace(u'\n', u'\r\n')
00090     text = text.encode(config.charset)
00091 
00092     # Create a message using config.charset and quoted printable
00093     # encoding, which should be supported better by mail clients.
00094     # TODO: check if its really works better for major mail clients
00095     msg = Message()
00096     charset = Charset(config.charset)
00097     charset.header_encoding = QP
00098     charset.body_encoding = QP
00099     msg.set_charset(charset)
00100 
00101     # work around a bug in python 2.4.3 and above:
00102     msg.set_payload('=')
00103     if msg.as_string().endswith('='):
00104         text = charset.body_encode(text)
00105 
00106     msg.set_payload(text)
00107 
00108     # Create message headers
00109     # Don't expose emails addreses of the other subscribers, instead we
00110     # use the same mail_from, e.g. u"Jürgen Wiki <noreply@mywiki.org>"
00111     address = encodeAddress(mail_from, charset)
00112     msg['From'] = address
00113     msg['To'] = address
00114     msg['Date'] = formatdate()
00115     msg['Message-ID'] = make_msgid()
00116     msg['Subject'] = Header(subject, charset)
00117     # See RFC 3834 section 5:
00118     msg['Auto-Submitted'] = 'auto-generated'
00119 
00120     if cfg.mail_sendmail:
00121         # Set the BCC.  This will be stripped later by sendmail.
00122         msg['BCC'] = ','.join(to)
00123         # Set Return-Path so that it isn't set (generally incorrectly) for us.
00124         msg['Return-Path'] = address
00125 
00126     # Send the message
00127     if not cfg.mail_sendmail:
00128         try:
00129             logging.debug("trying to send mail (smtp) via smtp server '%s'" % cfg.mail_smarthost)
00130             host, port = (cfg.mail_smarthost + ':25').split(':')[:2]
00131             server = smtplib.SMTP(host, int(port))
00132             try:
00133                 #server.set_debuglevel(1)
00134                 if cfg.mail_login:
00135                     user, pwd = cfg.mail_login.split()
00136                     try: # try to do tls
00137                         server.ehlo()
00138                         if server.has_extn('starttls'):
00139                             server.starttls()
00140                             server.ehlo()
00141                             logging.debug("tls connection to smtp server established")
00142                     except:
00143                         logging.debug("could not establish a tls connection to smtp server, continuing without tls")
00144                     logging.debug("trying to log in to smtp server using account '%s'" % user)
00145                     server.login(user, pwd)
00146                 server.sendmail(mail_from, to, msg.as_string())
00147             finally:
00148                 try:
00149                     server.quit()
00150                 except AttributeError:
00151                     # in case the connection failed, SMTP has no "sock" attribute
00152                     pass
00153         except smtplib.SMTPException, e:
00154             logging.exception("smtp mail failed with an exception.")
00155             return (0, str(e))
00156         except (os.error, socket.error), e:
00157             logging.exception("smtp mail failed with an exception.")
00158             return (0, _("Connection to mailserver '%(server)s' failed: %(reason)s") % {
00159                 'server': cfg.mail_smarthost,
00160                 'reason': str(e)
00161             })
00162     else:
00163         try:
00164             logging.debug("trying to send mail (sendmail)")
00165             sendmailp = os.popen(cfg.mail_sendmail, "w")
00166             # msg contains everything we need, so this is a simple write
00167             sendmailp.write(msg.as_string())
00168             sendmail_status = sendmailp.close()
00169             if sendmail_status:
00170                 logging.error("sendmail failed with status: %s" % str(sendmail_status))
00171                 return (0, str(sendmail_status))
00172         except:
00173             logging.exception("sendmail failed with an exception.")
00174             return (0, _("Mail not sent"))
00175 
00176     logging.debug("Mail sent OK")
00177     return (1, _("Mail sent OK"))

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

dictionary MoinMoin.mail.sendmail._transdict = {"AT": "@", "DOT": ".", "DASH": "-"}

Definition at line 18 of file sendmail.py.

Definition at line 14 of file sendmail.py.