Commit d18f99df authored by Florian Apolloner's avatar Florian Apolloner
Browse files

[1.6.x] Changed console and filebackend to use msg.as_bytes to output the data...

[1.6.x] Changed console and filebackend to use msg.as_bytes to output the data as it would get send via smtp.

Backport of c988745c from master.
parent 7c674dd1
Loading
Loading
Loading
Loading
+10 −3
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@ import sys
import threading

from django.core.mail.backends.base import BaseEmailBackend
from django.utils import six

class EmailBackend(BaseEmailBackend):
    def __init__(self, *args, **kwargs):
@@ -12,6 +13,14 @@ class EmailBackend(BaseEmailBackend):
        self._lock = threading.RLock()
        super(EmailBackend, self).__init__(*args, **kwargs)

    def write_message(self, message):
        msg = message.message().as_bytes()
        if six.PY3:
            msg = msg.decode()
        self.stream.write('%s\n' % msg)
        self.stream.write('-' * 79)
        self.stream.write('\n')

    def send_messages(self, email_messages):
        """Write all messages to the stream in a thread-safe way."""
        if not email_messages:
@@ -20,9 +29,7 @@ class EmailBackend(BaseEmailBackend):
            try:
                stream_created = self.open()
                for message in email_messages:
                    self.stream.write('%s\n' % message.message().as_string())
                    self.stream.write('-' * 79)
                    self.stream.write('\n')
                    self.write_message(message)
                    self.stream.flush()  # flush after each message
                if stream_created:
                    self.close()
+6 −1
Original line number Diff line number Diff line
@@ -37,6 +37,11 @@ class EmailBackend(ConsoleEmailBackend):
        kwargs['stream'] = None
        super(EmailBackend, self).__init__(*args, **kwargs)

    def write_message(self, message):
        self.stream.write(message.message().as_bytes() + b'\n')
        self.stream.write(b'-' * 79)
        self.stream.write(b'\n')

    def _get_filename(self):
        """Return a unique file name."""
        if self._fname is None:
@@ -47,7 +52,7 @@ class EmailBackend(ConsoleEmailBackend):

    def open(self):
        if self.stream is None:
            self.stream = open(self._get_filename(), 'a')
            self.stream = open(self._get_filename(), 'ab')
            return True
        return False

+21 −12
Original line number Diff line number Diff line
@@ -2,7 +2,7 @@
from __future__ import unicode_literals

import asyncore
import email
from email.mime.text import MIMEText
import os
import shutil
import smtpd
@@ -17,16 +17,17 @@ from django.core.mail.backends import console, dummy, locmem, filebased, smtp
from django.core.mail.message import BadHeaderError
from django.test import SimpleTestCase
from django.test.utils import override_settings
from django.utils.encoding import force_str, force_text, force_bytes
from django.utils.encoding import force_text, force_bytes
from django.utils.six import PY3, StringIO, binary_type
from django.utils.translation import ugettext_lazy

if PY3:
    from email.utils import parseaddr
    from email import message_from_bytes
    from email import message_from_bytes, message_from_binary_file
else:
    from email.Utils import parseaddr
    message_from_bytes = email.message_from_string
    from email import (message_from_string as message_from_bytes,
        message_from_file as message_from_binary_file)


class HeadersCheckMixin(object):
@@ -588,9 +589,9 @@ class FileBackendTests(BaseEmailBackendTests, SimpleTestCase):
    def get_mailbox_content(self):
        messages = []
        for filename in os.listdir(self.tmp_dir):
            with open(os.path.join(self.tmp_dir, filename), 'r') as fp:
                session = force_text(fp.read()).split('\n' + ('-' * 79) + '\n')
            messages.extend(email.message_from_string(force_str(m)) for m in session if m)
            with open(os.path.join(self.tmp_dir, filename), 'rb') as fp:
                session = fp.read().split(force_bytes('\n' + ('-' * 79) + '\n', encoding='ascii'))
            messages.extend(message_from_bytes(m) for m in session if m)
        return messages

    def test_file_sessions(self):
@@ -600,8 +601,8 @@ class FileBackendTests(BaseEmailBackendTests, SimpleTestCase):
        connection.send_messages([msg])

        self.assertEqual(len(os.listdir(self.tmp_dir)), 1)
        with open(os.path.join(self.tmp_dir, os.listdir(self.tmp_dir)[0])) as fp:
            message = email.message_from_file(fp)
        with open(os.path.join(self.tmp_dir, os.listdir(self.tmp_dir)[0]), 'rb') as fp:
            message = message_from_binary_file(fp)
        self.assertEqual(message.get_content_type(), 'text/plain')
        self.assertEqual(message.get('subject'), 'Subject')
        self.assertEqual(message.get('from'), 'from@example.com')
@@ -624,7 +625,7 @@ class FileBackendTests(BaseEmailBackendTests, SimpleTestCase):
        connection.close()


class ConsoleBackendTests(BaseEmailBackendTests, SimpleTestCase):
class ConsoleBackendTests(HeadersCheckMixin, BaseEmailBackendTests, SimpleTestCase):
    email_backend = 'django.core.mail.backends.console.EmailBackend'

    def setUp(self):
@@ -642,7 +643,7 @@ class ConsoleBackendTests(BaseEmailBackendTests, SimpleTestCase):
        self.stream = sys.stdout = StringIO()

    def get_mailbox_content(self):
        messages = self.stream.getvalue().split(force_str('\n' + ('-' * 79) + '\n'))
        messages = self.stream.getvalue().split(str('\n' + ('-' * 79) + '\n'))
        return [message_from_bytes(force_bytes(m)) for m in messages if m]

    def test_console_stream_kwarg(self):
@@ -652,7 +653,15 @@ class ConsoleBackendTests(BaseEmailBackendTests, SimpleTestCase):
        s = StringIO()
        connection = mail.get_connection('django.core.mail.backends.console.EmailBackend', stream=s)
        send_mail('Subject', 'Content', 'from@example.com', ['to@example.com'], connection=connection)
        self.assertTrue(s.getvalue().startswith('MIME-Version: 1.0\nContent-Type: text/plain; charset="utf-8"\nContent-Transfer-Encoding: 7bit\nSubject: Subject\nFrom: from@example.com\nTo: to@example.com\nDate: '))
        message = force_bytes(s.getvalue().split('\n' + ('-' * 79) + '\n')[0])
        self.assertMessageHasHeaders(message, {
            ('MIME-Version', '1.0'),
            ('Content-Type', 'text/plain; charset="utf-8"'),
            ('Content-Transfer-Encoding', '7bit'),
            ('Subject', 'Subject'),
            ('From', 'from@example.com'),
            ('To', 'to@example.com')})
        self.assertIn(b'\nDate: ', message)


class FakeSMTPServer(smtpd.SMTPServer, threading.Thread):