Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions common/lib/mail_utils.py
Original file line number Diff line number Diff line change
@@ -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
11 changes: 6 additions & 5 deletions lms/djangoapps/bulk_email/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,12 @@

"""
import logging
from django.db import models, transaction
from django.conf import settings
from django.contrib.auth.models import User
from html_to_text import html_to_text
from django.db import models, transaction

from django.conf import settings
from html_to_text import html_to_text
from mail_utils import wrap_message

log = logging.getLogger(__name__)

Expand Down Expand Up @@ -192,8 +193,8 @@ def _render(format_string, message_body, context):
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):
"""
Expand Down