Wraps long lines in bulk email messages.

RFC 2822 states that line lengths in emails must be less than 998.
Some MTA's add newlines to messages if any line exceeds a certain
limit (the exact limit varies). Sendmail goes so far as to add
'!\n' after the 990th character in a line. To ensure that bulk
mail messages look consistent long lines are wrapped to a
conservative length.

LMS-1466
This commit is contained in:
Usman Khalid
2014-04-24 20:30:31 +05:00
parent e7e9fb32bb
commit 8fd14bfca7
2 changed files with 29 additions and 6 deletions

22
common/lib/mail_utils.py Normal file
View File

@@ -0,0 +1,22 @@
"""
Utilities related to mailing.
"""
import textwrap
MAX_LINE_LENGTH = 900
def wrap_message(message, width=MAX_LINE_LENGTH):
"""
RFC 2822 states that line lengths in emails must be less than 998. Some MTA's add newlines to messages if any line
exceeds a certain limit (the exact limit varies). Sendmail goes so far as to add '!\n' after the 990th character in
a line. To ensure that messages look consistent this helper function wraps long lines to a conservative length.
"""
lines = message.split('\n')
wrapped_lines = [textwrap.fill(
line, width, expand_tabs=False, replace_whitespace=False, drop_whitespace=False, break_on_hyphens=False
) for line in lines]
wrapped_message = '\n'.join(wrapped_lines)
return wrapped_message

View File

@@ -12,11 +12,12 @@ file and check it in at the same time as your model changes. To do that,
"""
import logging
from django.db import models, transaction
from django.contrib.auth.models import User
from html_to_text import html_to_text
from django.conf import settings
from django.contrib.auth.models import User
from django.db import models, transaction
from html_to_text import html_to_text
from mail_utils import wrap_message
log = logging.getLogger(__name__)
@@ -192,8 +193,8 @@ class CourseEmailTemplate(models.Model):
message_body_tag = COURSE_EMAIL_MESSAGE_BODY_TAG.format()
result = result.replace(message_body_tag, message_body, 1)
# finally, return the result, without converting to an encoded byte array.
return result
# finally, return the result, after wrapping long lines and without converting to an encoded byte array.
return wrap_message(result)
def render_plaintext(self, plaintext, context):
"""