allura-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From brond...@apache.org
Subject allura git commit: [#8241] Send mails using quoted-printable if the lines are longer than SMTP allows
Date Thu, 04 Oct 2018 01:45:31 GMT
Repository: allura
Updated Branches:
  refs/heads/db/8241 [created] 322203a87


[#8241] Send mails using quoted-printable if the lines are longer than SMTP allows


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/322203a8
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/322203a8
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/322203a8

Branch: refs/heads/db/8241
Commit: 322203a8713ec00357d66448f5fec9ade7b43db1
Parents: 1a10d0d
Author: Dave Brondsema <dave@brondsema.net>
Authored: Wed Oct 3 14:51:04 2018 -0400
Committer: Dave Brondsema <dave@brondsema.net>
Committed: Wed Oct 3 21:36:59 2018 -0400

----------------------------------------------------------------------
 Allura/allura/lib/mail_util.py    | 30 +++++++++++++++++++++++++++---
 Allura/allura/tests/test_tasks.py | 24 +++++++++++++++++++++++-
 2 files changed, 50 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/322203a8/Allura/allura/lib/mail_util.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/mail_util.py b/Allura/allura/lib/mail_util.py
index bb768a1..ae72f93 100644
--- a/Allura/allura/lib/mail_util.py
+++ b/Allura/allura/lib/mail_util.py
@@ -175,11 +175,35 @@ def identify_sender(peer, email_address, headers, msg):
     return M.User.anonymous()
 
 
+# http://www.jebriggs.com/blog/2010/07/smtp-maximum-line-lengths/
+MAX_MAIL_LINE_OCTETS = 990
+
+
 def encode_email_part(content, content_type):
     try:
-        return MIMEText(content.encode('ascii'), content_type, 'ascii')
-    except:
-        return MIMEText(content.encode('utf-8'), content_type, 'utf-8')
+        # simplest email - plain ascii
+        encoded_content = content.encode('ascii')
+        encoding = 'ascii'
+    except Exception:
+        # utf8 will get base64 encoded so we only do it if ascii fails
+        encoded_content = content.encode('utf-8')
+        encoding = 'utf-8'
+
+    for line in encoded_content.splitlines():
+        if len(line) > MAX_MAIL_LINE_OCTETS:
+            # switch to Quoted-Printable encoding to avoid too-long lines
+            # we could always Quoted-Printabl, but it makes the output a little messier and
less human-readable
+            # the particular order of all these operations seems to be very important for
everything to end up right
+            msg = MIMEText(None, content_type)
+            msg.replace_header('content-transfer-encoding', 'quoted-printable')
+            cs = email.charset.Charset('utf-8')
+            cs.header_encoding = email.charset.QP
+            cs.body_encoding = email.charset.QP
+            payload = cs.body_encode(content.encode('utf-8'))
+            msg.set_payload(payload, 'utf-8')
+            return msg
+    else:
+        return MIMEText(encoded_content, content_type, encoding)
 
 
 def make_multipart_message(*parts):

http://git-wip-us.apache.org/repos/asf/allura/blob/322203a8/Allura/allura/tests/test_tasks.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/test_tasks.py b/Allura/allura/tests/test_tasks.py
index 7aefa9c..2d27256 100644
--- a/Allura/allura/tests/test_tasks.py
+++ b/Allura/allura/tests/test_tasks.py
@@ -28,7 +28,7 @@ import tg
 import mock
 from pylons import tmpl_context as c, app_globals as g
 from datadiff.tools import assert_equal
-from nose.tools import assert_in
+from nose.tools import assert_in, assert_less
 from ming.orm import FieldProperty, Mapper
 from ming.orm import ThreadLocalORMSession
 from testfixtures import LogCapture
@@ -423,6 +423,28 @@ class TestMailTasks(unittest.TestCase):
             return_path, rcpts, body = _client.sendmail.call_args[0]
             assert_in('From: "Test Admin" <test-admin@users.localhost>', body)
 
+    def test_send_email_long_lines_use_quoted_printable(self):
+        with mock.patch.object(mail_tasks.smtp_client, '_client') as _client:
+            mail_tasks.sendsimplemail(
+                fromaddr=u'"По" <foo@bar.com>',
+                toaddr='blah@blah.com',
+                text=(u'0123456789' * 100) + u'\n\n' + (u'Громады стро ' * 100),
+                reply_to=g.noreply,
+                subject=u'По оживлённым берегам',
+                message_id=h.gen_message_id())
+            return_path, rcpts, body = _client.sendmail.call_args[0]
+            body = body.split('\n')
+
+            for line in body:
+                assert_less(len(line), 991)
+
+            # plain text
+            assert_in('012345678901234567890123456789012345678901234567890123456789012345678901234=',
body)
+            assert_in('=D0=93=D1=80=D0=BE=D0=BC=D0=B0=D0=B4=D1=8B =D1=81=D1=82=D1=80=D0=BE
=D0=93=', body)
+            # html
+            assert_in('<div class=3D"markdown_content"><p>0123456789012345678901234567890123456789=',
body)
+            assert_in('<p>=D0=93=D1=80=D0=BE=D0=BC=D0=B0=D0=B4=D1=8B =D1=81=D1=82=D1=80=D0=BE
=D0=', body)
+
     @td.with_wiki
     def test_receive_email_ok(self):
         c.user = M.User.by_username('test-admin')


Mime
View raw message