Esempio n. 1
0
 def computereplacement(matchobj):
     text, coding = Header.decode_header(matchobj.group(0))[0]
     try:
         return text.strip().decode(coding).encode('utf-8')
     except Exception as e:
         logging.error(e)
         return text
Esempio n. 2
0
    def _extract_recipient(self, header):
        """Extract recipient name and email address from header"""
        v_list = email_header.decode_header(header)
        if len(v_list) == 2:
            # User name and Email already split.
            name = str(v_list[0][0].strip())
            address = str(v_list[1][0].strip())
            address = address.replace("<", "").replace(">", "").strip()
            if self.encoding:
                enc = chardet.detect(name)['encoding']
                if not enc:
                    enc = 'ascii'
                name = name.decode(enc).encode(self.encoding)
            return (name, address)
        else:
            entry = v_list[0][0].strip()
            parsed_addr = email.utils.parseaddr(entry)

            name = parsed_addr[0]
            address = parsed_addr[1]

            if address:
                address = address.strip()

            if self.encoding:
                enc = chardet.detect(name)['encoding']
                if not enc:
                    enc = 'ascii'
                name = name.decode(enc).encode(self.encoding)

            return (name, address)
Esempio n. 3
0
 def computereplacement(matchobj):
     text, coding = Header.decode_header(matchobj.group(0))[0]
     try:
         return text.strip().decode(coding).encode('utf-8')
     except Exception as e:
         logging.error(e)
         return text
Esempio n. 4
0
def decodeHeader(header, charset="utf-8"):
    try:
        h = Header.decode_header(header)
        buf = [b[0].decode(b[1] or 'ascii') for b in h]
        return u''.join(buf)

    except(UnicodeError, UnicodeDecodeError, LookupError, \
           email.errors.HeaderParseError):
        return unicode("".join(header.splitlines()), charset, 'ignore')
Esempio n. 5
0
def decodeHeader(header, charset="utf-8"):
    try:
        h = Header.decode_header(header)
        buf = [b[0].decode(b[1] or 'ascii') for b in h]
        return u''.join(buf)

    except(UnicodeError, UnicodeDecodeError, LookupError, \
           email.errors.HeaderParseError):
        return unicode("".join(header.splitlines()), charset, 'ignore')
Esempio n. 6
0
def decodeHeader(header, charset=constants.DEFAULT_CHARSET):
    try:
        decoded    = Header.make_header(Header.decode_header(header))
        unicodeStr = decoded.__unicode__()

        return  constants.EMPTY.join(unicodeStr.splitlines())

    except(UnicodeError, UnicodeDecodeError, LookupError):
        return unicode("".join(header.splitlines()), charset, 'ignore')
Esempio n. 7
0
def _log_subject(mi, log):
    encoded_subject = mi.msg.get('subject')
    try:
        subject, encoding = Header.decode_header(encoded_subject)[0]
    except Header.HeaderParseError:
        log.info("%s Subject cannot be parsed" % (mi.i,))
        return
    if encoding is None or encoding == 'iso-8859-1':
        s = subject
    else:
        s = encoded_subject
    log.info("%s Subject: %r" % (mi.i, s))
Esempio n. 8
0
def _log_subject(mi, log):
    encoded_subject = mi.msg.get('subject')
    try:
        subject, encoding = Header.decode_header(encoded_subject)[0]
    except Header.HeaderParseError:
        log.info("%s Subject cannot be parsed" % (mi.i, ))
        return
    if encoding is None or encoding == 'iso-8859-1':
        s = subject
    else:
        s = encoded_subject
    log.info("%s Subject: %r" % (mi.i, s))
Esempio n. 9
0
def decode_header(s):
  from email import Header
  def d(s,c):
    try:
      return s.decode(c or 'latin1', 'ignore')
    except LookupError:
      return s.decode('latin1', 'ignore')
  try:
    s = u' '.join( d(s1,t1) for (s1,t1) in Header.decode_header(s) )
  except Header.HeaderParseError:
    s = s.decode('latin1', 'ignore')
  return s
Esempio n. 10
0
def headerToUnicode(header, fallbackEncoding='utf-8'):
    """Decode a MIME encoded header and return a unicode object.

    @param header: a MIME encoded header to decode
    @param fallbackEncoding: the encoding to use if an unknown encoding is encountered
    """
    segments = []
    for segment, charset in Header.decode_header(header):
        try:
            segments.append(segment.decode(charset or 'ascii', 'replace'))
        except LookupError:
            segments.append(segment.decode(fallbackEncoding, 'replace'))
    return u' '.join(segments)
Esempio n. 11
0
def headerToUnicode(header, fallbackEncoding='utf-8'):
    """Decode a MIME encoded header and return a unicode object.

    @param header: a MIME encoded header to decode
    @param fallbackEncoding: the encoding to use if an unknown encoding is encountered
    """
    segments = []
    for segment, charset in Header.decode_header(header):
        try:
            segments.append(segment.decode(charset or 'ascii', 'replace'))
        except LookupError:
            segments.append(segment.decode(fallbackEncoding, 'replace'))
    return u' '.join(segments)
Esempio n. 12
0
def decode_header(value):
    """Converts an encoded header into a unicode string::

        >>> decode_header(
        ...       'Je les =?utf-8?b?ZMODwql0w4PCqHN0ZQ==?= oui?')
        u'Je les d\\xc3\\xa9t\\xc3\\xa8ste oui?'

    """
    encoded_strings = Header.decode_header(value)
    header_val = Header.Header()
    for string, encoding in encoded_strings:
        header_val.append(string, encoding, errors='replace')
    return unicode(header_val)
Esempio n. 13
0
def decode_header(value):
    """Converts an encoded header into a unicode string::

        >>> decode_header(
        ...       'Je les =?utf-8?b?ZMODwql0w4PCqHN0ZQ==?= oui?')
        u'Je les d\\xc3\\xa9t\\xc3\\xa8ste oui?'

    """
    encoded_strings = Header.decode_header(value)
    header_val = Header.Header()
    for string, encoding in encoded_strings:
        header_val.append(string, encoding, errors='replace')
    return unicode(header_val)
Esempio n. 14
0
def DecodeSingleHeader(s):
    """
    decode headers to UTF-8
    """
    parts = Header.decode_header(s)
    header = []
    for part in parts:
        s, enc = part
        if enc:
            s = unicode(s, enc).encode('utf8', 'replace')
        header.append(s)

    h = " ".join(header)
    return h
Esempio n. 15
0
 def __decode_item(item):
     if isinstance(item, str) and item.startswith('=?'):
         _item = "?=\r\n=?".join(item.split("?==?"))
         decodefrag = Header.decode_header(_item)
         subj_fragments = []
         for s, enc in decodefrag:
             if enc is None:
                 subj_fragments.append(s)
                 continue
             if enc.lower() in ('gb2312', 'gbk', 'gb_1988-80'):
                 enc = 'gb18030'
             s = unicode(s, enc).encode('utf8', 'replace')
             subj_fragments.append(s)
         return ''.join(subj_fragments)
     return item
Esempio n. 16
0
def decode_item(item):
        if isinstance(item, str) and item.startswith('=?') :
            _item = "?=\r\n=?".join(item.split("?==?"))
            decodefrag = Header.decode_header(_item)
            subj_fragments = []
            for s, enc in decodefrag:
                if enc is None:
                    subj_fragments.append(s)
                    continue
                if enc.lower() in ('gb2312', 'gbk', 'gb_1988-80'):
                    enc = 'gb18030'
                s = unicode(s, enc).encode('utf8', 'replace')
                subj_fragments.append(s)
            return ''.join(subj_fragments)
        return item
Esempio n. 17
0
 def __decode_item(item):
     if isinstance(item, str) and item.startswith("=?"):
         _item = "?=\r\n=?".join(item.split("?==?"))
         decodefrag = Header.decode_header(_item)
         subj_fragments = []
         for s, enc in decodefrag:
             if enc is None:
                 subj_fragments.append(s)
                 continue
             if enc.lower() in ("gb2312", "gbk", "gb_1988-80"):
                 enc = "gb18030"
             s = unicode(s, enc).encode("utf8", "replace")
             subj_fragments.append(s)
         return "".join(subj_fragments)
     return item
Esempio n. 18
0
    def get_addresses(self, message, header_name):
        """Get addresses from the header_name.

        This is usually 'From' or 'To', but other headers may contain
        addresses too, so we allow all, unlike we used to do.

        We expect just one From address and one To address, but
        multiple addresses can also be checked.

        May easily be something ugly like this:
        =?utf-8?q?Portal_Administrator_?=<*****@*****.**>

        From the Python docs:

        decode_header(header)

          Decode a message header value without converting charset.

          Returns a list of (decoded_string, charset) pairs containing
          each of the decoded parts of the header.  Charset is None
          for non-encoded parts of the header, otherwise a lower-case
          string containing the name of the character set specified in
          the encoded string.

          An email.Errors.HeaderParseError may be raised when certain
          decoding error occurs (e.g. a base64 decoding exception).
        """
        if not header_name:
            raise ValueError

        address = message.get(header_name, '')
        try:
            decoded = Header.decode_header(address)
        except HeaderParseError:
            logger.warn("Could not parse header %r", address)
            return []
        logger.debug('Decoded header: %r', decoded)
        for decoded_string, charset in decoded:
            if charset is not None:
                # Surely this is no email address but a name.
                continue
            if '@' not in decoded_string:
                continue

            return email_utils.getaddresses((decoded_string, ))
        return []
Esempio n. 19
0
    def _decode_headers(headers, encoding=None):
        """Decode headers"""
        if type(headers) is not list:
            headers = [headers]
        ret = []
        for header in headers:
            header = email_header.decode_header(header)
            h_ret = []
            for (value, h_encoding) in header:
                decoded_hv = decode_value(value, h_encoding)
                if encoding:
                    enc = chardet.detect(value)['encoding']
                    if not enc:
                        enc = 'ascii'
                    decoded_hv = decoded_hv.decode(enc).encode(encoding)

                h_ret.append(decoded_hv)
            if len(h_ret) == 1:
                h_ret = h_ret[0]
            ret.append(h_ret)
        return ret
Esempio n. 20
0
def decode_header(header_msg):
    result = Header.decode_header(header_msg)
    return decode_mail_string(''.join(t[0] for t in result))
Esempio n. 21
0
#!/usr/bin/env python
# MIME Header Parsing - Chapter 9
# mime_parse_headers.py
# This program requires Python 2.2.2 or above

import sys, email, codecs
from email import Header

msg = email.message_from_file(sys.stdin)
for header, value in msg.items():
    headerparts = Header.decode_header(value)
    headerval = []
    for part in headerparts:
        data, charset = part
	if charset is None:
	    charset = 'ascii'
	dec = codecs.getdecoder(charset)
	enc = codecs.getencoder('iso-8859-1')
	data = enc(dec(data)[0])[0]
	headerval.append(data)
    print "%s: %s" % (header, " ".join(headerval))

    def __call__(self):
        if not self.enabled:
            logger.debug('received mail-in request, but mail-in not enabled')
            raise NotFound
        mail = self.request.get('Mail', '')
        mail = mail.strip()
        if not mail:
            msg = u'No mail found in request'
            logger.warn(msg)
            return msg
        message = message_from_string(mail)

        logger.debug('--------')
        logger.debug(mail)
        logger.debug('--------')
        logger.debug(message)
        from_addresses = self.get_addresses(message, 'From')
        to_addresses = self.get_addresses(message, 'To')
        if not from_addresses or not to_addresses:
            msg = u'No From or To address found in request'
            logger.warn(msg)
            return msg
        for from_name, from_address in from_addresses:
            if from_address:
                break
        portal = getToolByName(self.context, 'portal_url').getPortalObject()
        email_from_address = portal.getProperty('email_from_address')
        if from_address.lower() == email_from_address.lower():
            # This too easily means that a message sent by Poi ends up
            # being added as a reply on an issue that we have just
            # created.
            msg = u'Ignoring mail from portal email_from_address'
            logger.info(msg)
            return msg

        subject_line = message.get('Subject', '')
        subjects = []
        decoded = Header.decode_header(subject_line)
        for decoded_string, charset in decoded:
            if charset:
                decoded_string = decoded_string.decode(charset)
            subjects.append(decoded_string)
        subject = u' '.join(subjects)

        logger.debug("Forum at %s received mail from %r to %r with "
                     "subject %r", self.context.absolute_url(),
                     from_address, to_addresses, subject)
        text, mimetype = self.get_text_and_mimetype(message)
        if not text:
            text = "Warning: no text found in email"
            mimetype = 'text/plain'
            logger.warn(text)
        logger.debug('Got payload with mimetype %s from email.', mimetype)

        # Create an attachment from the complete email.
        attachment = File('email.eml', 'E-mail', mail)

        tags = self.get_tags(message)
        if tags:
            logger.debug("Determined tags: %r", tags)
        else:
            logger.debug("Could not determine tags.")

        # Store original security manager.
        sm = getSecurityManager()
        # Possibly switch to a different user.
        self.switch_user(from_address)

        if self.add_attachments:
            attachments = self.get_attachments(message)
            attachments = [File(filename, filename, data) for filename, data in attachments]
        else:
            attachments = [attachment]

        target = self.find_conversation_or_thread(subject, text, tags, message)
        if target is None:
            # We don't allow creating conversations from mail, only replies
            logger.info('Could not find something to reply to')
        else:
            try:
                self.add_response(target, from_address, subject, text, mimetype, attachments)
            except Unauthorized, exc:
                logger.error(u'Unauthorized to add response: %s', exc)
                return u'Unauthorized'
            logger.info('Added mail as response to target %s',
                        target.absolute_url())
Esempio n. 23
0
#!/usr/bin/env python

import sys, email, codecs
from email import Header

msg = email.message_from_file(sys.stdin)
for header, value in msg.items():
    headerparts = Header.decode_header(value)
    headerval = []
    for part in headerparts:
        data, charset = part
        if charset is None:
            charset = 'ascii'
        dec = codecs.getdecoder(charset)
        enc = codecs.getencoder('iso-8859-1')
        data = enc(dec(data)[0])[0]
        headerval.append(data)
        print "%s: %s" % (header, " ".join(headerval))
Esempio n. 24
0
#!/usr/bin/python
'''
File: mail_parser.py
Author: Sigurd Fosseng
Licence: MIT Licence
Description: Converts the subject of the email given through stdin to Unicode, and sends
it through xmlrpc
'''
from email.Parser import Parser
from email import Header
import xmlrpclib
import sys

#mime handling
data = sys.stdin.read()
message = Parser().parsestr(data)
subject = unicode(Header.make_header(Header.decode_header(message['subject'])))

#send to bot
s = xmlrpclib.Server("http://localhost:5656/")
s.say(subject)
Esempio n. 25
0
    def __call__(self):
        mail = self.request.get('Mail')
        mail = mail.strip()
        if not mail:
            msg = u'No mail found in request'
            logger.warn(msg)
            return msg
        message = message_from_string(mail)
        self.encoding = self._get_encoding(message)

        logger.debug('--------')
        logger.debug(mail)
        logger.debug('--------')
        logger.debug(message)
        from_addresses = self.get_addresses(message, 'From')
        to_addresses = self.get_addresses(message, 'To')
        if not from_addresses or not to_addresses:
            msg = u'No From or To address found in request'
            logger.warn(msg)
            return msg
        # Pick the first one; strange anyway if there would be more.
        from_name, from_address = from_addresses[0]
        portal = getToolByName(self.context, 'portal_url').getPortalObject()
        email_from_address = portal.getProperty('email_from_address')
        if from_address.lower() == email_from_address.lower():
            # This too easily means that a message sent by Poi ends up
            # being added as a reply on an issue that we have just
            # created.
            msg = u'Ignoring mail from portal email_from_address'
            logger.info(msg)
            return msg

        subject_line = message.get('Subject', '')
        subjects = []
        decoded = Header.decode_header(subject_line)
        for decoded_string, charset in decoded:
            if charset:
                decoded_string = decoded_string.decode(charset)
            subjects.append(decoded_string)
        subject = u' '.join(subjects)

        logger.info(
            "Tracker at %s received mail from %r to %r with "
            "subject %r", self.context.absolute_url(),
            from_address, to_addresses, subject)
        details, mimetype = self.get_details_and_mimetype(message)
        logger.debug('Got payload with mimetype %s from email.', mimetype)
        # Transform to an allowed mime type, if needed.
        details, mimetype = self.to_allowed_mimetype(details, mimetype)
        if not details:
            # Details is a required field.
            details = '.'
            mimetype = 'text/plain'
            logger.info('No details found in email.')

        # Create an attachment from the complete email.
        attachment = mail

        tags = self.get_tags(message)
        if tags:
            logger.debug("Determined tags: %r", tags)
        else:
            logger.debug("Could not determine tags.")

        # Get all info that we need from the mail.
        mail_info = {
            'subject': subject,
            'tags': tags,
            'message': message,
            'details': details,
            'from_address': from_address,
            'attachment': attachment,
            'mimetype': mimetype,
        }

        # Possibly switch to a different user.
        user = self.find_user_for_switching(from_address)
        if user is None:
            result = self.create_content(**mail_info)
        else:
            with api.env.adopt_user(user=user):
                current_user = api.user.get_current()
                user_id = current_user.getId()
                user_name = current_user.getUserName()
                logger.info("Switched email=%s to user name=%s (id=%s)",
                            from_address, user_name, user_id)
                role = self.find_role_to_fake()
                if not role:
                    result = self.create_content(**mail_info)
                else:
                    logger.info("Faking %s role for user %s", role, user_id)
                    # Fake a few extra roles as well.  For example,
                    # TrackerManager may not have the 'Copy or Move'
                    # permission, but Anonymous may have.  Go figure.
                    roles = [role, 'Member', 'Anonymous']
                    with api.env.adopt_roles(roles):
                        result = self.create_content(**mail_info)

        # We need to return something.
        if result:
            # error
            return result
        return mail
Esempio n. 26
0
    def __call__(self):
        mail = self.request.get('Mail')
        mail = mail.strip()
        if not mail:
            msg = u'No mail found in request'
            logger.warn(msg)
            return msg
        message = message_from_string(mail)
        self.encoding = self._get_encoding(message)

        logger.debug('--------')
        logger.debug(mail)
        logger.debug('--------')
        logger.debug(message)
        from_addresses = self.get_addresses(message, 'From')
        to_addresses = self.get_addresses(message, 'To')
        if not from_addresses or not to_addresses:
            msg = u'No From or To address found in request'
            logger.warn(msg)
            return msg
        # Pick the first one; strange anyway if there would be more.
        from_name, from_address = from_addresses[0]
        portal = getToolByName(self.context, 'portal_url').getPortalObject()
        email_from_address = portal.getProperty('email_from_address')
        if from_address.lower() == email_from_address.lower():
            # This too easily means that a message sent by Poi ends up
            # being added as a reply on an issue that we have just
            # created.
            msg = u'Ignoring mail from portal email_from_address'
            logger.info(msg)
            return msg

        subject_line = message.get('Subject', '')
        subjects = []
        decoded = Header.decode_header(subject_line)
        for decoded_string, charset in decoded:
            if charset:
                decoded_string = decoded_string.decode(charset)
            subjects.append(decoded_string)
        subject = u' '.join(subjects)

        logger.debug("Tracker at %s received mail from %r to %r with "
                     "subject %r", self.context.absolute_url(),
                     from_address, to_addresses, subject)
        details, mimetype = self.get_details_and_mimetype(message)
        if not details:
            details = "Warning: no details found in email"
            mimetype = 'text/plain'
            logger.warn(details)
        logger.debug('Got payload with mimetype %s from email.', mimetype)

        # Create an attachment from the complete email.  Somehow the
        # result is nicer when it is put in a response than in an
        # issue.  Not much we can do about that probably.
        attachment = File('email.eml', 'E-mail', mail)

        tags = self.get_tags(message)
        if tags:
            logger.debug("Determined tags: %r", tags)
        else:
            logger.debug("Could not determine tags.")

        # Store original security manager.
        sm = getSecurityManager()
        # Possibly switch to a different user.
        self.switch_user(from_address)

        issue = self.find_issue(subject, tags, message)
        if issue is None:
            manager = self.get_manager(message, tags)
            logger.debug("Determined manager: %s", manager)
            if not subject:
                # When there is no subject, we always want to create a
                # new issue, as we do not want to try to match a empty
                # or fake subject.
                # We also want to flay the user alive...
                subject = '[no subject]'
            try:
                issue = self.create_issue(
                    title=subject, details=details, contactEmail=from_address,
                    attachment=attachment, responsibleManager=manager,
                    subject=tags)
            except Unauthorized, exc:
                logger.error(u'Unauthorized to create issue: %s', exc)
                return u'Unauthorized'
            logger.info('Created issue from email at %s', issue.absolute_url())