Question

# settings.py
EMAIL_BACKEND = 'django.core.mail.backends.filebased.EmailBackend'

# view.py
from django.core.mail import send_mail

def send_letter(request):
    the_text = 'this is a test of a really long line that has more words that could possibly fit in a single column of text.'
    send_mail('some_subject', the_text, 'me@test.com', ['me@test.com'])

The Django view code above, results in a text file that contains a broken line:

this is a test of a really long line that has more words that could possibl=
y fit in a single column of text.
-------------------------------------------------------------------------------

Anyone know how to change it so the output file doesn't have linebreaks? Is there some setting in Django that controls this? Version 1.2 of Django.

Update - to back up a level and explain my original problem :) I'm using the django-registration app, which sends an email with an account activation link. This link is a long URL, with a random token at the end (30+ characters), and as a result, the line is breaking in the middle of the token.

In case the problem was using the Django's filebased EmailBackend, I switched to the smtp backend and ran the built-in Python smtpd server, in debugging mode. This dumped my email to the console, where it was still broken.

I'm sure django-registration is working, with zillions of people using it :) So it must be something I've done wrong or mis-configured. I just have no clue what.

Update 2 - according to a post in a Django list, it's really the underlying Python email.MIMEText object, which, if correct, only pushes the problem back a little more. It still doesn't tell me how to fix it. Looking at the docs, I don't see anything that even mentions line-wrapping.

Update 3 (sigh) - I've ruled out it being a MIMEText object problem. I used a pure Python program and the smtplib/MIMEText to create and send a test email, and it worked fine. It also used a charset = "us-ascii", which someone suggested was the only charset to not wrap text in MIMEText objects. I don't know if that's correct or not, but I did look more closely at my Django email output, and it has a charset of "utf-8".

Could the wrong charset be the problem? And if so, how do I change it in Django?

Here's the entire output stream from Django's email:

---------- MESSAGE FOLLOWS ----------
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: quoted-printable
Subject: some_subject
From: me@test.com
To: me@test.com
Date: Tue, 17 May 2011 19:58:16 -0000

this is a test of a really long line that has more words that could possibl=
y fit in a single column of text.
------------ END MESSAGE ------------
Was it helpful?

Solution

You might be able to get your email client to not break on the 78 character soft limit by creating an EmailMessage object and passing in headers={'format': 'flowed'} Like so:

from django.core.mail import EmailMessage

def send_letter(request):
    the_text = 'this is a test of a really long line that has more words that could possibly fit in a single column of text.'
    email = EmailMessage(
        subject='some_subject', 
        body=the_text, 
        from_email='me@test.com', 
        to=['me@test.com'],
        headers={'format': 'flowed'})

    email.send()

If this doesn't work, try using a non-debug smtp setup to send the file to an actual email client that renders the email according to rules defined in the email header.

OTHER TIPS

I've seen this is python2.5 and it's fixed in python2.7.

The relevant code in email/generator.py now has a comment saying

# Header's got lots of smarts, so use it.  Note that this is
# fundamentally broken though because we lose idempotency when
# the header string is continued with tabs.  It will now be
# continued with spaces.  This was reversedly broken before we
# fixed bug 1974.  Either way, we lose.

You can read about the bug here http://bugs.python.org/issue1974

Or you can just change the '\t' to ' ' in this line of email/generator.py

print >> self._fp, Header(
v, maxlinelen=self._maxheaderlen,
header_name=h, continuation_ws='\t').encode()

Try to define EMAIL_BACKEND in your settings.py. Maybe it doesn't solve your problem, but is the right place where to define it, otherwise it's likely not going to be used.

(Since I'm not sure I'm solving your problem here, I was trying to make a comment on your, but apparently I cannot.)

The email lines aren't "broken" per se -- they're just represented in the quoted-printable encoding. As such, at 76 characters, =\n is inserted. Any competent mail client ought to decode the message properly and remove the break.

If you want to represent the body of an email decoded, you can use this by passing decode=True to the the get_payload method:

body = email.get_payload(decode=True)

This tells the message to decode the quoted-printable encoding.

More to the point, if your main concern is getting the python console debugging server to print the message decoded, you could do something quick and dirty like this snippet rather than using the built-in DebuggingServer. More properly, you could parse the "data" string as an Email object, print out the headers you care about, then print the body with decode=True.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top