Example #1
0
    def _decode_message(self, msg):
        assert isinstance(msg, email.message.Message)

        headers = {name: self._decode_header(value) for name, value in msg.items()}
        subject = self._decode_header(msg.get(u'subject', u''))
        from_header = self._decode_header(msg.get(u'from', u''))
        from_name, from_mail = parseaddr(from_header)

        text = u''
        html = u''
        attachments = []
        for part in msg.walk():
            if part.is_multipart():
                continue
            content_type = part.get_content_type()
            charset = part.get_content_charset()
            content = part.get_payload(decode=True)
            disposition = self._decode_header(part.get(u'Content-Disposition', u''))
            is_attachment = disposition.startswith(u'attachment')
            if not text and content_type == u'text/plain' and not is_attachment:
                text = self._decode_content(content, charset)
            elif not html and content_type == u'text/html' and not is_attachment:
                html = self._decode_content(content, charset)
            else:
                default = u'attachment{}'.format(guess_extension(content_type, u'.bin'))
                filename = part.get_filename(default)
                attachments.append(Attachment(
                        file=ContentFile(content),
                        name=filename,
                        content_type=content_type,
                        ))

        recipients = []
        for header_name, type in ((u'to', Recipient.TYPES.TO),
                                  (u'cc', Recipient.TYPES.CC),
                                  (u'bcc', Recipient.TYPES.BCC)):
            header = self._decode_header(msg.get(header_name, u''))
            for rcp_address in header.split(','):
                rcp_name, rcp_mail = parseaddr(rcp_address)
                if rcp_mail:
                    recipients.append(Recipient(
                            name=rcp_name,
                            mail=rcp_mail,
                            type=type,
                            status=Recipient.STATUSES.INBOUND,
                            ))

        message = Message(
                type=Message.TYPES.INBOUND,
                processed=None,
                from_name=from_name,
                from_mail=from_mail,
                subject=subject,
                text=text,
                html=html,
                headers=headers,
                )
        message.save()

        for recipient in recipients:
            recipient.message = message
            recipient.save()

        for attachment in attachments:
            attachment.generic_object = message
            attachment.save()

        return message
Example #2
0
    def _enqueue(self, message):
        # Based on djrill.mail.backends.DjrillBackend; We can't use Djrill directly because it
        # sends the mail synchronously during user requests.
        sanitized = sanitize_address(message.from_email, message.encoding)
        from_name, from_mail = parseaddr(sanitized)

        subject = message.subject
        text = message.body if message.content_subtype != u'html' else None
        html = message.body if message.content_subtype == u'html' else None
        headers = message.extra_headers

        # We may have only one plaintext and one html message body. If the message has more
        # plaintext and/or html aternatives, they are converted to attachments.
        remnant_alternatives = []
        for content, content_type in getattr(message, u'alternatives', []):
            if content_type == u'text/plain' and text is None:
                text = content
            elif content_type == u'text/html' and html is None:
                html = content
            else:
                ext = guess_extension(content_type, u'.bin')
                remnant_alternatives.append((u'message{}'.format(ext), content, content_type))

        recipients = []
        for addresses, type in ((message.to, Recipient.TYPES.TO),
                                (message.cc, Recipient.TYPES.CC),
                                (message.bcc, Recipient.TYPES.BCC)):
            for addr in addresses:
                sanitized = sanitize_address(addr, message.encoding)
                name, mail = parseaddr(sanitized)
                recipients.append(Recipient(
                        name=name,
                        mail=mail,
                        type=type,
                        status=Recipient.STATUSES.QUEUED,
                        ))

        attachments = []
        for attachment in message.attachments + remnant_alternatives:
            if isinstance(attachment, MIMEBase):
                name = attachment.get_filename()
                content = attachment.get_payload(decode=True)
                content_type = attachment.get_content_type()
            else:
                name, content, content_type = attachment
            if not content_type:
                content_type = DEFAULT_ATTACHMENT_MIME_TYPE
            if not name:
                name = u'attachment{}'.format(guess_extension(content_type, u'.bin'))
            attachments.append(Attachment(
                    file=ContentFile(content),
                    name=name,
                    content_type=content_type,
                    ))

        msg = Message(
                type=Message.TYPES.OUTBOUND,
                from_name=from_name,
                from_mail=from_mail,
                subject=subject,
                text=text or u'',
                html=html or u'',
                headers=headers,
                )
        msg.save()
        message.instance = msg

        for recipient in recipients:
            recipient.message = msg
            recipient.save()

        for attachment in attachments:
            attachment.generic_object = msg
            attachment.save()
Example #3
0
    def _enqueue(self, message):
        # Based on djrill.mail.backends.DjrillBackend; We can't use Djrill directly because it
        # sends the mail synchronously during user requests.
        from_name, from_mail = parseaddr(message.from_email)
        subject = message.subject
        text = message.body if message.content_subtype != u'html' else None
        html = message.body if message.content_subtype == u'html' else None
        headers = message.extra_headers

        # We may have only one plaintext and one html message body. If the message has more
        # plaintext and/or html aternatives, they are converted to attachments.
        remnant_alternatives = []
        for content, content_type in getattr(message, u'alternatives', []):
            if content_type == u'text/plain' and text is None:
                text = content
            elif content_type == u'text/html' and html is None:
                html = content
            else:
                ext = guess_extension(content_type, u'.bin')
                remnant_alternatives.append((u'message{}'.format(ext), content, content_type))

        recipients = []
        for addresses, type in ((message.to, Recipient.TYPES.TO),
                                (message.cc, Recipient.TYPES.CC),
                                (message.bcc, Recipient.TYPES.BCC)):
            for addr in addresses:
                name, mail = parseaddr(addr)
                recipients.append(Recipient(
                        name=name,
                        mail=mail,
                        type=type,
                        status=Recipient.STATUSES.QUEUED,
                        ))

        attachments = []
        for attachment in message.attachments + remnant_alternatives:
            if isinstance(attachment, MIMEBase):
                name = attachment.get_filename()
                content = attachment.get_payload(decode=True)
                content_type = attachment.get_content_type()
            else:
                name, content, content_type = attachment
            if not content_type:
                content_type = DEFAULT_ATTACHMENT_MIME_TYPE
            if not name:
                name = u'attachment{}'.format(guess_extension(content_type, u'.bin'))
            attachments.append(Attachment(
                    file=ContentFile(content),
                    name=name,
                    ))

        msg = Message(
                type=Message.TYPES.OUTBOUND,
                from_name=from_name,
                from_mail=from_mail,
                subject=subject,
                text=text or u'',
                html=html or u'',
                headers=headers,
                )
        msg.save()
        message.instance = msg

        for recipient in recipients:
            recipient.message = msg
            recipient.save()

        for attachment in attachments:
            attachment.generic_object = msg
            attachment.save()
Example #4
0
 def test_unknown_content_type_with_default_extension(self):
     self.assertEqual(guess_extension(u'application/nonexistent', u'.bin'),
                      u'.bin')
Example #5
0
    def _decode_message(self, msg):
        assert isinstance(msg, email.message.Message)

        headers = {
            name: self._decode_header(value)
            for name, value in msg.items()
        }
        subject = self._decode_header(msg.get(u'subject', u''))
        from_header = self._decode_header(msg.get(u'from', u''))
        from_name, from_mail = parseaddr(from_header)

        text = u''
        html = u''
        attachments = []
        for part in msg.walk():
            if part.is_multipart():
                continue
            content_type = part.get_content_type()
            charset = part.get_content_charset()
            content = part.get_payload(decode=True)
            disposition = self._decode_header(
                part.get(u'Content-Disposition', u''))
            is_attachment = disposition.startswith(u'attachment')
            if not text and content_type == u'text/plain' and not is_attachment:
                text = self._decode_content(content, charset)
            elif not html and content_type == u'text/html' and not is_attachment:
                html = self._decode_content(content, charset)
            else:
                default = u'attachment{}'.format(
                    guess_extension(content_type, u'.bin'))
                filename = part.get_filename(default)
                attachments.append(
                    Attachment(
                        file=ContentFile(content),
                        name=filename,
                    ))

        recipients = []
        for header_name, type in ((u'to', Recipient.TYPES.TO),
                                  (u'cc', Recipient.TYPES.CC),
                                  (u'bcc', Recipient.TYPES.BCC)):
            header = self._decode_header(msg.get(header_name, u''))
            for rcp_address in header.split(','):
                rcp_name, rcp_mail = parseaddr(rcp_address)
                if rcp_mail:
                    recipients.append(
                        Recipient(
                            name=rcp_name,
                            mail=rcp_mail,
                            type=type,
                            status=Recipient.STATUSES.INBOUND,
                        ))

        message = Message(
            type=Message.TYPES.INBOUND,
            processed=None,
            from_name=from_name,
            from_mail=from_mail,
            subject=subject,
            text=text,
            html=html,
            headers=headers,
        )
        message.save()

        for recipient in recipients:
            recipient.message = message
            recipient.save()

        for attachment in attachments:
            attachment.generic_object = message
            attachment.save()

        return message
Example #6
0
 def test_application_pdf(self):
     self.assertEqual(guess_extension(u'application/pdf'), u'.pdf')
Example #7
0
 def test_unknown_content_type(self):
     self.assertIsNone(guess_extension(u'application/nonexistent'))
Example #8
0
 def test_text_plain(self):
     self.assertEqual(guess_extension(u'text/plain'), u'.txt')
Example #9
0
 def test_application_octet_stream(self):
     self.assertEqual(guess_extension(u'application/octet-stream'), u'.bin')
Example #10
0
 def test_unknown_content_type_with_default_extension(self):
     self.assertEqual(guess_extension(u'application/nonexistent', u'.bin'), u'.bin')
Example #11
0
 def test_unknown_content_type(self):
     self.assertIsNone(guess_extension(u'application/nonexistent'))
Example #12
0
 def test_application_pdf(self):
     self.assertEqual(guess_extension(u'application/pdf'), u'.pdf')
Example #13
0
 def test_application_octet_stream(self):
     self.assertEqual(guess_extension(u'application/octet-stream'), u'.bin')
Example #14
0
 def test_text_plain(self):
     self.assertEqual(guess_extension(u'text/plain'), u'.txt')