Esempio n. 1
0
def decodeMessageAsString(msg):
    """ This helper method takes Message object or string and returns
        string which does not contain base64 encoded parts
        Returns message without any encoding in parts
    """
    if isinstance(msg, str):
        msg = Parser().parsestr(msg)

    new = deepcopy(msg)
    # From is utf8 encoded: '=?utf-8?q?Site_Administrator_=3C=3E?='
    new.replace_header('From', decode_header(new['From'])[0][0])
    new.replace_header('Subject', decode_header(new['Subject'])[0][0])
    charset = Charset('utf-8')
    charset.header_encoding = SHORTEST
    charset.body_encoding = QP
    charset.output_charset = 'utf-8'

    for part in new.walk():
        if part.get_content_maintype() == "multipart":
            continue
        decoded = part.get_payload(decode=1)
        del part['Content-Transfer-Encoding']
        part.set_payload(decoded, charset)

    return new.as_string()
Esempio n. 2
0
def decodeMessageAsString(msg):
    """ This helper method takes Message object or string and returns
        string which does not contain base64 encoded parts
        Returns message without any encoding in parts
    """
    if isinstance(msg, str):
        msg = Parser().parsestr(msg)

    new = deepcopy(msg)
    # From is utf8 encoded: '=?utf-8?q?Site_Administrator_=3C=3E?='
    new.replace_header('From', decode_header(new['From'])[0][0])
    new.replace_header('Subject', decode_header(new['Subject'])[0][0])
    charset = Charset('utf-8')
    charset.header_encoding = SHORTEST
    charset.body_encoding = QP
    charset.output_charset = 'utf-8'

    for part in new.walk():
        if part.get_content_maintype() == "multipart":
            continue
        decoded = part.get_payload(decode=1)
        del part['Content-Transfer-Encoding']
        part.set_payload(decoded, charset)

    return new.as_string()
    def _set_charset(self, mime):
        from email.Charset import Charset, QP, BASE64, SHORTEST
        mime_encoding = self.config.get('notification', 'mime_encoding').lower()

        charset = Charset()
        charset.input_charset = 'utf-8'
        charset.output_charset = 'utf-8'
        charset.input_codec = 'utf-8'
        charset.output_codec = 'utf-8'
        if mime_encoding == 'base64':
            charset.header_encoding = BASE64
            charset.body_encoding = BASE64
        elif mime_encoding in ('qp', 'quoted-printable'):
            charset.header_encoding = QP
            charset.body_encoding = QP
        elif mime_encoding == 'none':
            charset.header_encoding = SHORTEST
            charset.body_encoding = None

        del mime['Content-Transfer-Encoding']
        mime.set_charset(charset)
Esempio n. 4
0
    def create_message(self):

        if self.attach:
            self.create_multipart_message()
        else:
            self.create_text_message()
        """comment
        """
        charset = Charset(self.encoding)
        charset.header_encoding = QP
        charset.body_encoding = QP
        self.msg.set_charset(charset)
        """
Esempio n. 5
0
    def create_message(self):

        if self.attach:
            self.create_multipart_message()
        else:
            self.create_text_message()

        """comment
        """
        charset = Charset(self.encoding)
        charset.header_encoding = QP
        charset.body_encoding = QP
        self.msg.set_charset(charset)
        """
Esempio n. 6
0
def prepare_message(template, variables, encoding="utf-8"):
    r"""Return a prepared email.Message object.

    >>> template = (u"Subject: @SUBJECT@\n"+
    ...             u"From: @FROM@\n"+
    ...             u"To: @TO@\n"+
    ...             u"BCC: @FROM@\n\n"+
    ...             u"Hello, @GREETED@!")
    >>> variables = dict(SUBJECT="Test",
    ...                  FROM="*****@*****.**",
    ...                  TO="*****@*****.**",
    ...                  GREETED="World")
    >>> message = prepare_message(template, variables)
    >>> message["SUBJECT"] == variables["SUBJECT"]
    True
    >>> message["TO"] == variables["TO"]
    True
    >>> message["FROM"] == message["BCC"] == variables["FROM"]
    True
    >>> message.get_payload()
    'Hello, World!'
    """

    template = u"\r\n".join(template.splitlines())
    template = replace_variables(template, variables)
    template = template.encode(encoding)
    message = message_from_string(template)

    DEFAULT_HEADERS = {"to": "@INVITEDEMAIL@", "from": "@INVITEREMAIL@"}
    for key, value in DEFAULT_HEADERS.iteritems():
        if key not in message:
            value = replace_variables(value, variables)
            if isinstance(value, unicode):
                value = value.encode(encoding)
            message[key] = value

    charset = Charset(encoding)
    charset.header_encoding = QP
    charset.body_encoding = QP
    message.set_charset(charset)

    for field in ("from", "to", "cc", "bcc"):
        try:
            encode_address_field(message, field, encoding, charset)
        except UnicodeEncodeError as error:
            raise InviteException("Invalid '{0}' address: {1}".format(
                field, error))

    return message
Esempio n. 7
0
def prepare_message(template, variables, encoding="utf-8"):
    r"""Return a prepared email.Message object.

    >>> template = (u"Subject: @SUBJECT@\n"+
    ...             u"From: @FROM@\n"+
    ...             u"To: @TO@\n"+
    ...             u"BCC: @FROM@\n\n"+
    ...             u"Hello, @GREETED@!")
    >>> variables = dict(SUBJECT="Test",
    ...                  FROM="*****@*****.**",
    ...                  TO="*****@*****.**",
    ...                  GREETED="World")
    >>> message = prepare_message(template, variables)
    >>> message["SUBJECT"] == variables["SUBJECT"]
    True
    >>> message["TO"] == variables["TO"]
    True
    >>> message["FROM"] == message["BCC"] == variables["FROM"]
    True
    >>> message.get_payload()
    'Hello, World!'
    """

    template = u"\r\n".join(template.splitlines())
    template = replace_variables(template, variables)
    template = template.encode(encoding)
    message = message_from_string(template)

    DEFAULT_HEADERS = {"to": "@INVITEDEMAIL@", "from": "@INVITEREMAIL@"}
    for key, value in DEFAULT_HEADERS.iteritems():
        if key not in message:
            value = replace_variables(value, variables)
            if isinstance(value, unicode):
                value = value.encode(encoding)
            message[key] = value

    charset = Charset(encoding)
    charset.header_encoding = QP
    charset.body_encoding = QP
    message.set_charset(charset)

    for field in ("from", "to", "cc", "bcc"):
        try:
            encode_address_field(message, field, encoding, charset)
        except UnicodeEncodeError as error:
            raise InviteException("Invalid '{0}' address: {1}".format(field, error))

    return message
Esempio n. 8
0
def 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)
    """
    import smtplib, socket
    from email.Message import Message
    from email.Charset import Charset, QP
    from email.Utils import formatdate, make_msgid

    _ = request.getText
    cfg = request.cfg
    mail_from = mail_from or cfg.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
    msg.set_charset(charset)

    # work around a bug in python 2.4.3 and above:
    msg.set_payload('=')
    if msg.as_string().endswith('='):
        text = charset.body_encode(text)

    msg.set_payload(text)

    # Create message headers
    # Don't expose emails addreses of the other subscribers, instead we
    # use the same mail_from, e.g. u"Jürgen Wiki <*****@*****.**>"
    address = encodeAddress(mail_from, charset)
    msg['From'] = address
    msg['To'] = address
    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'] = address

    # Send the message
    if not cfg.mail_sendmail:
        try:
            logging.debug("trying to send mail (smtp) via smtp server '%s'" % cfg.mail_smarthost)
            host, port = (cfg.mail_smarthost + ':25').split(':')[:2]
            server = smtplib.SMTP(host, int(port))
            try:
                #server.set_debuglevel(1)
                if cfg.mail_login:
                    user, pwd = cfg.mail_login.split()
                    try: # try to do tls
                        server.ehlo()
                        if server.has_extn('starttls'):
                            server.starttls()
                            server.ehlo()
                            logging.debug("tls connection to smtp server established")
                    except:
                        logging.debug("could not establish a tls connection to smtp server, continuing without tls")
                    logging.debug("trying to log in to smtp server using account '%s'" % user)
                    server.login(user, pwd)
                server.sendmail(mail_from, to, msg.as_string())
            finally:
                try:
                    server.quit()
                except AttributeError:
                    # in case the connection failed, SMTP has no "sock" attribute
                    pass
        except smtplib.SMTPException, e:
            logging.exception("smtp mail failed with an exception.")
            return (0, str(e))
        except (os.error, socket.error), e:
            logging.exception("smtp mail failed with an exception.")
            return (0, _("Connection to mailserver '%(server)s' failed: %(reason)s") % {
                'server': cfg.mail_smarthost,
                'reason': str(e)
            })
Esempio n. 9
0
# NNTP message encoding trivia

from email.Header import Header
from email.Charset import Charset
from StringIO import StringIO
import email.Charset
import base64
import quopri
import re

charset = Charset('utf-8')
charset.header_encoding = email.Charset.SHORTEST
charset.body_encoding = email.Charset.SHORTEST

line_end_re = re.compile(r'\r\n|\n\r|\n(?!\r)|\r(?!\n)')

def encode_header_word(word):
    if type(word) is unicode:
        # see if it is plain ascii first
        try:
            return word.encode('us-ascii')
        except:
            # try to encode non-ascii headers using email.Header.  The
            # 1000000 value is a maximum line length, meaning never
            # fold header lines.  This is important for the XOVER
            # response.
            return str(Header(word, charset, 1000000))
    else:
        return word

# base64 encode a string, splitting lines in the output
Esempio n. 10
0
def 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)
    """
    import smtplib, socket
    from email.Message import Message
    from email.Charset import Charset, QP
    from email.Utils import formatdate, make_msgid

    _ = request.getText
    cfg = request.cfg
    mail_from = mail_from or cfg.mail_from

    logging.debug("send mail, from: %r, subj: %r" % (mail_from, subject))
    logging.debug("send mail, to: %r" % (to, ))

    if not to:
        return (1, _("No recipients, nothing to do"))

    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
    msg.set_charset(charset)

    # work around a bug in python 2.4.3 and above:
    msg.set_payload('=')
    if msg.as_string().endswith('='):
        text = charset.body_encode(text)

    msg.set_payload(text)

    # Create message headers
    # Don't expose emails addreses of the other subscribers, instead we
    # use the same mail_from, e.g. u"Jürgen Wiki <*****@*****.**>"
    address = encodeAddress(mail_from, charset)
    msg['From'] = address
    msg['To'] = address
    msg['Date'] = formatdate()
    msg['Message-ID'] = make_msgid()
    msg['Subject'] = Header(subject, charset)
    # See RFC 3834 section 5:
    msg['Auto-Submitted'] = 'auto-generated'

    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'] = address

    # Send the message
    if not cfg.mail_sendmail:
        try:
            logging.debug("trying to send mail (smtp) via smtp server '%s'" %
                          cfg.mail_smarthost)
            host, port = (cfg.mail_smarthost + ':25').split(':')[:2]
            server = smtplib.SMTP(host, int(port))
            try:
                #server.set_debuglevel(1)
                if cfg.mail_login:
                    user, pwd = cfg.mail_login.split()
                    try:  # try to do tls
                        server.ehlo()
                        if server.has_extn('starttls'):
                            server.starttls()
                            server.ehlo()
                            logging.debug(
                                "tls connection to smtp server established")
                    except:
                        logging.debug(
                            "could not establish a tls connection to smtp server, continuing without tls"
                        )
                    logging.debug(
                        "trying to log in to smtp server using account '%s'" %
                        user)
                    server.login(user, pwd)
                server.sendmail(mail_from, to, msg.as_string())
            finally:
                try:
                    server.quit()
                except AttributeError:
                    # in case the connection failed, SMTP has no "sock" attribute
                    pass
        except UnicodeError, e:
            logging.exception("unicode error [%r -> %r]" % (
                mail_from,
                to,
            ))
            return (0, str(e))
        except smtplib.SMTPException, e:
            logging.exception("smtp mail failed with an exception.")
            return (0, str(e))
Esempio n. 11
0
def sendmail(subject, text, to=None, cc=None, bcc=None, mail_from=None):
    """ Create and send a text/plain message

    Return a tuple of success or error indicator and message.

    :param subject: subject of email
    :type subject: unicode
    :param text: email body text
    :type text: unicode
    :param to: recipients
    :type to: list
    :param cc: recipients (CC)
    :type cc: list
    :param bcc: recipients (BCC)
    :type bcc: list
    :param mail_from: override default mail_from
    :type mail_from: unicode

    :rtype: tuple
    :returns: (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

    cfg = app.cfg
    mail_from = mail_from or cfg.mail_from

    logging.debug("send mail, from: {0!r}, subj: {1!r}".format(mail_from, subject))
    logging.debug("send mail, to: {0!r}".format(to))

    if not to and not cc and not bcc:
        return (1, _("No recipients, nothing to do"))

    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
    msg.set_charset(charset)

    # work around a bug in python 2.4.3 and above:
    msg.set_payload('=')
    if msg.as_string().endswith('='):
        text = charset.body_encode(text)

    msg.set_payload(text)

    address = encodeAddress(mail_from, charset)
    msg['From'] = address
    if to:
        msg['To'] = ','.join(to)
    if cc:
        msg['CC'] = ','.join(cc)
    msg['Date'] = formatdate()
    msg['Message-ID'] = make_msgid()
    msg['Subject'] = Header(subject, charset)
    # See RFC 3834 section 5:
    msg['Auto-Submitted'] = 'auto-generated'

    if cfg.mail_sendmail:
        if bcc:
            # Set the BCC.  This will be stripped later by sendmail.
            msg['BCC'] = ','.join(bcc)
        # Set Return-Path so that it isn't set (generally incorrectly) for us.
        msg['Return-Path'] = address

    # Send the message
    if not cfg.mail_sendmail:
        try:
            logging.debug("trying to send mail (smtp) via smtp server '{0}'".format(cfg.mail_smarthost))
            host, port = (cfg.mail_smarthost + ':25').split(':')[:2]
            server = smtplib.SMTP(host, int(port))
            try:
                #server.set_debuglevel(1)
                if cfg.mail_username is not None and cfg.mail_password is not None:
                    try: # try to do tls
                        server.ehlo()
                        if server.has_extn('starttls'):
                            server.starttls()
                            server.ehlo()
                            logging.debug("tls connection to smtp server established")
                    except:
                        logging.debug("could not establish a tls connection to smtp server, continuing without tls")
                    logging.debug("trying to log in to smtp server using account '{0}'".format(cfg.mail_username))
                    server.login(cfg.mail_username, cfg.mail_password)
                server.sendmail(mail_from, (to or []) + (cc or []) + (bcc or []), msg.as_string())
            finally:
                try:
                    server.quit()
                except AttributeError:
                    # in case the connection failed, SMTP has no "sock" attribute
                    pass
        except smtplib.SMTPException as e:
            logging.exception("smtp mail failed with an exception.")
            return (0, str(e))
        except (os.error, socket.error) as e:
            logging.exception("smtp mail failed with an exception.")
            return (0, _("Connection to mailserver '%(server)s' failed: %(reason)s",
                server=cfg.mail_smarthost,
                reason=str(e)
            ))
    else:
        try:
            logging.debug("trying to send mail (sendmail)")
            sendmailp = os.popen(cfg.mail_sendmail, "w")
            # msg contains everything we need, so this is a simple write
            sendmailp.write(msg.as_string())
            sendmail_status = sendmailp.close()
            if sendmail_status:
                logging.error("sendmail failed with status: {0!s}".format(sendmail_status))
                return (0, str(sendmail_status))
        except:
            logging.exception("sendmail failed with an exception.")
            return (0, _("Mail not sent"))

    logging.debug("Mail sent successfully")
    return (1, _("Mail sent successfully"))