Email app is breaking long lines, any fix?

567 views
Skip to first unread message

John Crawford

unread,
May 5, 2011, 8:50:21 PM5/5/11
to django...@googlegroups.com
I'm using the filebased email backend for testing (although the
console version had the same problem). When I send email, either via
function or template, lines that are too long, are broken, with an
'=' sign at the end. For instance:

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

When sending email, is there some maximum-linelength variable, or
something, that's truncating/breaking lines? Any way to prevent this
from happening?

Code I'm using to test:

EMAIL_BACKEND = 'django.core.mail.backends.filebased.EmailBackend'
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, 'm...@test.com', ['m...@test.com'])

Thanks.
John C>

Jason Culverhouse

unread,
May 6, 2011, 12:33:40 AM5/6/11
to django...@googlegroups.com

On May 5, 2011, at 5:50 PM, John Crawford wrote:

> I'm using the filebased email backend for testing (although the console version had the same problem). When I send email, either via function or template, lines that are too long, are broken, with an '=' sign at the end. For instance:
>
> this is a test of a really long line that has more words that could possibl=
> y fit in a single column of text.
>
> When sending email, is there some maximum-linelength variable, or something, that's truncating/breaking lines? Any way to prevent this from happening?

The answer is no, it it the underlying python email.MIMEText object that is performing the encoding
The only encoding that isn;t going to wrap is charset="us-ascii"

http://www.rfc-editor.org/rfc/rfc5322.txt

2.1.1. Line Length Limits

There are two limits that this specification places on the number of
characters in a line. Each line of characters MUST be no more than
998 characters, and SHOULD be no more than 78 characters, excluding
the CRLF.

The 998 character limit is due to limitations in many implementations
that send, receive, or store IMF messages which simply cannot handle
more than 998 characters on a line. Receiving implementations would
do well to handle an arbitrarily large number of characters in a line
for robustness sake. However, there are so many implementations that
(in compliance with the transport requirements of [RFC5321]) do not
accept messages containing more than 1000 characters including the CR
and LF per line, it is important for implementations not to create
such messages.

The more conservative 78 character recommendation is to accommodate
the many implementations of user interfaces that display these
messages which may truncate, or disastrously wrap, the display of
more than 78 characters per line, in spite of the fact that such
implementations are non-conformant to the intent of this
specification (and that of [RFC5321] if they actually cause
information to be lost). Again, even though this limitation is put
on messages, it is incumbent upon implementations that display
messages to handle an arbitrarily large number of characters in a
line (certainly at least up to the 998 character limit) for the sake
of robustness.


Jason


>
> Code I'm using to test:
>
> EMAIL_BACKEND = 'django.core.mail.backends.filebased.EmailBackend'
> 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, 'm...@test.com', ['m...@test.com'])
>
> Thanks.
> John C>
>

> --
> You received this message because you are subscribed to the Google Groups "Django users" group.
> To post to this group, send email to django...@googlegroups.com.
> To unsubscribe from this group, send email to django-users...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/django-users?hl=en.
>

Tom Evans

unread,
May 6, 2011, 4:51:49 AM5/6/11
to django...@googlegroups.com
On Fri, May 6, 2011 at 5:33 AM, Jason Culverhouse <ja...@mischievous.org> wrote:
>
>
> The answer is no, it it the underlying python email.MIMEText object that is performing the encoding
> The only encoding that isn;t going to wrap is charset="us-ascii"
>
> http://www.rfc-editor.org/rfc/rfc5322.txt
>
> 2.1.1.  Line Length Limits

2.1.1 doesn't apply here, the email is simply formatted using the
Quoted-Printable transfer encoding.

http://en.wikipedia.org/wiki/Quoted-printable

An email client would read "=\r\n" as a soft line break, and remove it
when displaying the message.

Cheers

Tom

John Crawford

unread,
May 6, 2011, 8:54:19 AM5/6/11
to Django users
> The only encoding that isn;t going to wrap is charset="us-ascii"

Actually, looking at the resulting file, it *does* say it's
charset="us-ascii".

> An email client would read "=\r\n" as a soft line break, and remove it
> when displaying the message.

I tried cutting/pasting the text, and sending it to myself, but the
resulting email still displayed as wrapped (I'm using Eudora 7 on
Windows XP). However, I'm not sure if I managed to *exactly* duplicate
the scenario if Django sent a real email. When I cut/pasted the text
(from Notepad++) into Eudora, it *looked* the same - an "=" followed
by a carriage return, but that's not to say it is exactly what Django
would have done, I admit.

Maybe I should back up a level and explain my original problem :) I'm
using the *django-registration* app, which can send an email with an
account activation link, where the link is a long URL, with a random
token at the end, matching a token in the new account.

And the email (or text file) that I'm seeing generated, contains a
line break in the *token* part of the URL - so a user couldn't just
cut/paste the link and have it work.

The *django-registration* app has been around for a while, I'm sure
I'm not the first one to encounter this scenario, it must work fine
for zillions of other people :)

If you're sure email readers will handle the text properly, then I
guess I have to skip using Django's file-based email backend, and
actually configure something to send real email. I was hoping to not
do this just yet, but so it goes. :)

Thanks for the replies.
John C>

John Crawford

unread,
May 17, 2011, 4:02:18 PM5/17/11
to Django users
Actually, upon looking more at the output, it has *both* "utf-8" and
"us-ascii" as the charset. I'm not sure if this is the result of code
changes I've made, or I just missed it the first time around - but my
Django email output now looks like this:

---------- MESSAGE FOLLOWS ----------
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: quoted-printable
Subject: some_subject
From: m...@test.com
To: m...@test.com
Date: Tue, 17 May 2011 19:58:16 -0000
Message-ID: <20110517195816.16624.1004@CRAY>
X-Peer: 127.0.0.1

Content-Type: text/us-ascii; charset=3D"us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit

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 ------------

So although I'm creating a MIMEText object with a plain, "us-ascii"
string - somewhere, Django is sending a charset of "utf-8". At least
if I read this correctly.

So does anyone know how to tell Django to *not* send "utf-8"? Thanks.

Ian Clelland

unread,
May 17, 2011, 5:50:59 PM5/17/11
to django...@googlegroups.com
On Tue, May 17, 2011 at 1:02 PM, John Crawford <cyc...@speakeasy.net> wrote:
Actually, upon looking more at the output, it has *both* "utf-8" and
"us-ascii" as the charset.

Actually, it doesn't. It only has utf-8. The first nine lines of your pasted output are the actual email headers. Following the blank line is the email body, which begins with three lines that *look* like headers, but are actually just part of the message, and any email client would just render them as text at the top of the message.

(In addition to the blank line, this is alse evidenced by the fact that the '=' in 'charset='us-ascii'" was escaped as '=3D', as is normal for quoted-printable-encoded text)
What are you *actually* doing to send this email? It sounds like you are creating some kind of object and passing that as the body to send_mail, while send_mail is expecting text, and is just coercing your object into a string and using that as the message body.

It is definitely possible to tell Django not to use UTF-8 encoding, but you won't be able to use the send_mail shortcut to do it. You will have to use an EmailMessage object directly[1]. You should be able to instantiate an EmailMessage, set the headers yourself, and call send() on it.

(Also, 'text/us-ascii' is not a registered MIME type; you probably want to say something like 'text/plain; charset=us-ascii')




--
Regards,
Ian Clelland
<clel...@gmail.com>

John Crawford

unread,
May 17, 2011, 6:23:17 PM5/17/11
to Django users
> What are you *actually* doing to send this email?

This is the basic version - the one with two headers, I was
experimenting with a MIMEText object:

from django.core.mail import send_mail

def page_worked(request):
the_text = u'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, 'm...@test.com',
['m...@test.com'])

However - this is not the *actual* problem, only sample code - the
*actual* problem is with the django-registration app. Given a text
template to create a registration email, it's breaking the lines.

Although it would be nice to understand everything that's going on
here - all I *really* want to do is have the app send non-broken
email. :)

John Crawford

unread,
May 17, 2011, 6:30:11 PM5/17/11
to Django users
> Actually, it doesn't. It only has utf-8. The first nine lines of your pasted
output are the actual email headers.

Okay, that makes more sense. That particular experiment I was using a
MIMEObject's to_string() function. Although I had passed in plain text
to the object, clearly it put its own headers on the string output.

Also minor note - my test string usually does *not* have the 'u'
Unicode prefix on it, that was just the last change I had made, I
forgot to remove it. :)

John Crawford

unread,
Jun 9, 2011, 6:33:36 PM6/9/11
to Django users
Just for the record, to close this off - the problem was solved when I
finally configured Django to send email via my *ISP*. Apparently
Django was doing some unnecessary formatting, whether the output went
to file, console, or even *smtp*, going to a local smtp server: python
-m smtpd -n -c DebuggingServer localhost:1025

Sigh... Live and learn.

John C>
Reply all
Reply to author
Forward
0 new messages