示例#1
0
    def instanciate_answer(self, lines):
        answer = self.answer_class()
        msgtxt = ''.join(lines)

        msg = email.message_from_string(msgtxt)
        temporary, permanent = all_failures(msg)

        if permanent:
            answer.is_bounced = True
            answer.email_from = scan_message(msg).pop()
        elif temporary:
            raise TemporaryFailure
        else:
            answer.email_from = msg["From"]

        the_recipient = msg["To"]
        answer.subject = msg["Subject"]
        answer.when = msg["Date"]
        answer.message_id = msg["Message-ID"]

        the_recipient = re.sub(r"\n", "", the_recipient)

        regex = re.compile(r".*[\+\-](.*)@.*")
        the_match = regex.match(the_recipient)
        if the_match is None:
            raise CouldNotFindIdentifier
        answer.email_to = the_recipient
        answer.outbound_message_identifier = the_match.groups()[0]
        logging.info("Reading the parts")
        for part in msg.walk():
            logging.info("Part of type " + part.get_content_type())

            content_type_attr = self.content_types_attrs.get(
                part.get_content_type())
            if content_type_attr:
                charset = part.get_content_charset() or "ISO-8859-1"
                data = part.get_payload(decode=True).decode(charset)

                setattr(
                    answer,
                    content_type_attr,
                    EmailReplyParser.parse_reply(data).strip(),
                )
            else:
                self.handle_not_processed_part(part)

            attachment = self.parse_attachment(part)
            if attachment:
                answer.add_attachment(attachment)

        log = 'New incoming email from %(from)s sent on %(date)s with subject %(subject)s and content %(content)s'
        log = log % {
            'from': answer.email_from,
            'date': answer.when,
            'subject': answer.subject,
            'content': answer.content_text,
        }
        logging.info(log)
        return answer
示例#2
0
    def instanciate_answer(self, lines):
        answer = self.answer_class()
        msgtxt = ''.join(lines)

        msg = email.message_from_string(msgtxt)
        temporary, permanent = all_failures(msg)

        if permanent:
            answer.is_bounced = True
            answer.email_from = scan_message(msg).pop()
        elif temporary:
            raise TemporaryFailure
        else:
            answer.email_from = msg["From"]

        the_recipient = msg["To"]
        answer.subject = msg["Subject"]
        answer.when = msg["Date"]
        answer.message_id = msg["Message-ID"]

        the_recipient = re.sub(r"\n", "", the_recipient)

        regex = re.compile(r".*[\+\-](.*)@.*")
        the_match = regex.match(the_recipient)
        if the_match is None:
            raise CouldNotFindIdentifier
        answer.email_to = the_recipient
        answer.outbound_message_identifier = the_match.groups()[0]
        logging.info("Reading the parts")
        for part in msg.walk():
            logging.info("Part of type " + part.get_content_type())

            content_type_attr = self.content_types_attrs.get(part.get_content_type())
            if content_type_attr:
                charset = part.get_content_charset() or "ISO-8859-1"
                data = part.get_payload(decode=True).decode(charset)

                setattr(
                    answer,
                    content_type_attr,
                    EmailReplyParser.parse_reply(data).strip(),
                    )
            else:
                self.handle_not_processed_part(part)

            attachment = self.parse_attachment(part)
            if attachment:
                answer.add_attachment(attachment)

        log = 'New incoming email from %(from)s sent on %(date)s with subject %(subject)s and content %(content)s'
        log = log % {
            'from': answer.email_from,
            'date': answer.when,
            'subject': answer.subject,
            'content': answer.content_text,
            }
        logging.info(log)
        return answer
示例#3
0
 def __call__(self, msg):
     # This probe only
     from flufl.bounce import scan_message
     failed_addresses = scan_message(msg)
     if failed_addresses:
         message_id = msg['Message-Id']
         logger.warn('Possible bounce: %s',
                     message_id,
                     extra=dict(message_details=msg.items(),
                                failed_addresses=failed_addresses))
示例#4
0
 def parseForReturns(self, damail = 0, emailid = 0 ):
     if (damail == 0):
         damail, emailid = self.next()
     fails = scan_message(damail)
     if len(fails) != 0:
         mail.store(emailid, '+FLAGS', '\\Deleted')
     for fail_s in fails:
         r = session.query(PhoneCarrier).filter_by(email=fail_s).all()
         if len(r) == 0:
             continue
         r = r[0]
         session.delete(r)
     return fails      
示例#5
0
 def _dispose(self, mlist, msg, msgdata):
     # List isn't doing bounce processing?
     if not mlist.process_bounces:
         return False
     # Try VERP detection first, since it's quick and easy
     context = BounceContext.normal
     addresses = StandardVERP().get_verp(mlist, msg)
     if len(addresses) > 0:
         # Scan the message to see if it contained permanent or temporary
         # failures.  We'll ignore temporary failures, but even if there
         # are no permanent failures, we'll assume VERP bounces are
         # permanent.
         temporary, permanent = all_failures(msg)
         if len(temporary) > 0:
             # This was a temporary failure, so just ignore it.
             return False
     else:
         # See if this was a probe message.
         addresses = ProbeVERP().get_verp(mlist, msg)
         if len(addresses) > 0:
             context = BounceContext.probe
         else:
             # That didn't give us anything useful, so try the old fashion
             # bounce matching modules.  This returns only the permanently
             # failing addresses.  Since Mailman currently doesn't score
             # temporary failures, if we get no permanent failures, we're
             # done.s
             addresses = scan_message(msg)
     # If that still didn't return us any useful addresses, then send it on
     # or discard it.  The addresses will come back from flufl.bounce as
     # bytes/8-bit strings, but we must store them as unicodes in the
     # database.  Assume utf-8 encoding, but be cautious.
     if len(addresses) > 0:
         for address in addresses:
             if isinstance(address, bytes):
                 try:
                     address = address.decode('utf-8')
                 except UnicodeError:
                     log.exception('Ignoring non-UTF-8 encoded '
                                   'address: {0}'.format(address))
                     continue
             self._processor.register(mlist, address, msg, context)
     else:
         log.info('Bounce message w/no discernable addresses: %s',
                  msg.get('message-id', 'n/a'))
         maybe_forward(mlist, msg)
     # Dequeue this message.
     return False
示例#6
0
文件: bounce.py 项目: aswinpj/Mailman
 def _dispose(self, mlist, msg, msgdata):
     # List isn't doing bounce processing?
     if not mlist.process_bounces:
         return False
     # Try VERP detection first, since it's quick and easy
     context = BounceContext.normal
     addresses = StandardVERP().get_verp(mlist, msg)
     if len(addresses) > 0:
         # Scan the message to see if it contained permanent or temporary
         # failures.  We'll ignore temporary failures, but even if there
         # are no permanent failures, we'll assume VERP bounces are
         # permanent.
         temporary, permanent = all_failures(msg)
         if len(temporary) > 0:
             # This was a temporary failure, so just ignore it.
             return False
     else:
         # See if this was a probe message.
         addresses = ProbeVERP().get_verp(mlist, msg)
         if len(addresses) > 0:
             context = BounceContext.probe
         else:
             # That didn't give us anything useful, so try the old fashion
             # bounce matching modules.  This returns only the permanently
             # failing addresses.  Since Mailman currently doesn't score
             # temporary failures, if we get no permanent failures, we're
             # done.s
             addresses = scan_message(msg)
     # If that still didn't return us any useful addresses, then send it on
     # or discard it.  The addresses will come back from flufl.bounce as
     # bytes/8-bit strings, but we must store them as unicodes in the
     # database.  Assume utf-8 encoding, but be cautious.
     if len(addresses) > 0:
         for address in addresses:
             if isinstance(address, bytes):
                 try:
                     address = address.decode('utf-8')
                 except UnicodeError:
                     log.exception('Ignoring non-UTF-8 encoded '
                                   'address: {}'.format(address))
                     continue
             self._processor.register(mlist, address, msg, context)
     else:
         log.info('Bounce message w/no discernable addresses: %s',
                  msg.get('message-id', 'n/a'))
         maybe_forward(mlist, msg)
     # Dequeue this message.
     return False
示例#7
0
    def handle(self, lines):
        answer = self.answer_class()
        msgtxt = ''.join(lines)

        msg = email.message_from_string(msgtxt)
        temporary, permanent = all_failures(msg)
        
        
        if temporary or permanent:
            answer.is_bounced = True
            answer.email_from = scan_message(msg).pop()
        else:
            answer.email_from = msg["From"]


        the_recipient = msg["To"]
        answer.subject = msg["Subject"]
        answer.when = msg["Date"]

        the_recipient = re.sub(r"\n", "", the_recipient)

        regex = re.compile(r".*[\+\-](.*)@.*")

        answer.outbound_message_identifier = regex.match(the_recipient).groups()[0]
        charset = msg.get_charset()
        logging.info("Reading the parts")
        for part in msg.walk():
            logging.info("Part of type "+part.get_content_type())
            if part.get_content_type() == 'text/plain':
                charset = part.get_content_charset()
                if not charset:
                    charset = "ISO-8859-1"
                data = part.get_payload(decode=True).decode(charset)
                text = EmailReplyParser.parse_reply(data)
                text.strip()
                answer.content_text = text
        #logging stuff
        
        log = 'New incoming email from %(from)s sent on %(date)s with subject %(subject)s and content %(content)s'
        log = log % {
            'from':answer.email_from,
            'date':answer.when,
            'subject':answer.subject,
            'content':answer.content_text
            }
        logging.info(log)
        return answer