Code

Fix charset of first text-part of outgoing multipart messages, thanks
authorschlatterbeck <schlatterbeck@57a73879-2fb5-44c3-a270-3262357dd7e2>
Mon, 4 Oct 2010 12:56:37 +0000 (12:56 +0000)
committerschlatterbeck <schlatterbeck@57a73879-2fb5-44c3-a270-3262357dd7e2>
Mon, 4 Oct 2010 12:56:37 +0000 (12:56 +0000)
Dirk Geschke for reporting, see
http://thread.gmane.org/gmane.comp.bug-tracking.roundup.user/10223
This also adds some regression tests to test incoming latin1 and
outgoing single- and multipart utf-8 and latin1 messages

git-svn-id: http://svn.roundup-tracker.org/svnroot/roundup/roundup/trunk@4529 57a73879-2fb5-44c3-a270-3262357dd7e2

CHANGES.txt
doc/acknowledgements.txt
roundup/roundupdb.py
test/test_mailgw.py

index 59d6426cd5707abb9714fc3918eb438d9bb61875..55bcab3771a859a9baacd93dd6052d51992821e6 100644 (file)
@@ -30,6 +30,9 @@ Fixed:
   (thanks Ezio Melotti)
 - fixed registration, issue2550665 (thanks Timo Paulssen)
 - make sorting of multilinks in the web interface more robust, issue2550663
+- Fix charset of first text-part of outgoing multipart messages, thanks Dirk
+  Geschke for reporting, see
+  http://thread.gmane.org/gmane.comp.bug-tracking.roundup.user/10223
 
 
 2010-07-12 1.4.15
index 86967f2430017cbec3bf0fc3834ada644296f1aa..54f2d5b69a904622578d26583510e8c76ae6d537 100644 (file)
@@ -42,6 +42,7 @@ Hernan Martinez Foffani,
 Stuart D. Gathman,
 Martin Geisler,
 Ajit George,
+Dirk Geschke,
 Frank Gibbons,
 Johannes Gijsbers,
 Christian Glass,
index 7d40da471f46277215e13edf4841c3970bc55d53..d3576b1732e19e56febb738db917800dec5ef269 100644 (file)
@@ -472,6 +472,7 @@ class IssueClass:
             if message_files:
                 # first up the text as a part
                 part = MIMEText(body)
+                part.set_charset(charset)
                 encode_quopri(part)
                 message.attach(part)
 
index 600bc81fdc2c350a5f4fb74c3ac1baa426b261d3..47b8eeb77607bb1f67ed1db103c203c9e0b3f651 100644 (file)
@@ -458,6 +458,29 @@ SnVzdCBhIHRlc3QK
 --bCsyhTFzCvuiizWF--
 
 --bxyzzy--
+'''
+
+    multipart_msg_latin1 = '''From: mary <mary@test.test>
+To: issue_tracker@your.tracker.email.domain.example
+Message-Id: <followup_dummy_id>
+In-Reply-To: <dummy_test_message_id>
+Subject: [issue1] Testing...
+Content-Type: multipart/alternative; boundary=001485f339f8f361fb049188dbba
+
+
+--001485f339f8f361fb049188dbba
+Content-Type: text/plain; charset=ISO-8859-1
+Content-Transfer-Encoding: quoted-printable
+
+umlaut =E4=F6=FC=C4=D6=DC=DF
+
+--001485f339f8f361fb049188dbba
+Content-Type: text/html; charset=ISO-8859-1
+Content-Transfer-Encoding: quoted-printable
+
+<html>umlaut =E4=F6=FC=C4=D6=DC=DF</html>
+
+--001485f339f8f361fb049188dbba--
 '''
 
     def testMultipartKeepAlternatives(self):
@@ -495,6 +518,234 @@ SnVzdCBhIHRlc3QK
                 self.assertEqual(f.content, content [n])
         self.assertEqual(msg.content, 'test attachment second text/plain')
 
+    def testMultipartCharsetUTF8NoAttach(self):
+        c = 'umlaut \xc3\xa4\xc3\xb6\xc3\xbc\xc3\x84\xc3\x96\xc3\x9c\xc3\x9f'
+        self.doNewIssue()
+        self.db.config.NOSY_MAX_ATTACHMENT_SIZE = 0
+        self._handle_mail(self.multipart_msg_latin1)
+        messages = self.db.issue.get('1', 'messages')
+        messages.sort()
+        msg = self.db.msg.getnode (messages[-1])
+        assert(len(msg.files) == 1)
+        name = 'unnamed'
+        content = '<html>' + c + '</html>\n'
+        for n, id in enumerate (msg.files):
+            f = self.db.file.getnode (id)
+            self.assertEqual(f.name, name)
+            self.assertEqual(f.content, content)
+        self.assertEqual(msg.content, c)
+        self.compareMessages(self._get_mail(),
+'''FROM: roundup-admin@your.tracker.email.domain.example
+TO: chef@bork.bork.bork, richard@test.test
+Content-Type: text/plain; charset="utf-8"
+Subject: [issue1] Testing...
+To: chef@bork.bork.bork, richard@test.test
+From: "Contrary, Mary" <issue_tracker@your.tracker.email.domain.example>
+Reply-To: Roundup issue tracker
+ <issue_tracker@your.tracker.email.domain.example>
+MIME-Version: 1.0
+Message-Id: <followup_dummy_id>
+In-Reply-To: <dummy_test_message_id>
+X-Roundup-Name: Roundup issue tracker
+X-Roundup-Loop: hello
+X-Roundup-Issue-Status: chatting
+X-Roundup-Issue-Files: unnamed
+Content-Transfer-Encoding: quoted-printable
+
+
+Contrary, Mary <mary@test.test> added the comment:
+
+umlaut =C3=A4=C3=B6=C3=BC=C3=84=C3=96=C3=9C=C3=9F
+File 'unnamed' not attached - you can download it from http://tracker.examp=
+le/cgi-bin/roundup.cgi/bugs/file1.
+
+----------
+status: unread -> chatting
+
+_______________________________________________________________________
+Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
+<http://tracker.example/cgi-bin/roundup.cgi/bugs/issue1>
+_______________________________________________________________________
+''')
+
+    def testMultipartCharsetLatin1NoAttach(self):
+        c = 'umlaut \xc3\xa4\xc3\xb6\xc3\xbc\xc3\x84\xc3\x96\xc3\x9c\xc3\x9f'
+        self.doNewIssue()
+        self.db.config.NOSY_MAX_ATTACHMENT_SIZE = 0
+        self.db.config.MAIL_CHARSET = 'iso-8859-1'
+        self._handle_mail(self.multipart_msg_latin1)
+        messages = self.db.issue.get('1', 'messages')
+        messages.sort()
+        msg = self.db.msg.getnode (messages[-1])
+        assert(len(msg.files) == 1)
+        name = 'unnamed'
+        content = '<html>' + c + '</html>\n'
+        for n, id in enumerate (msg.files):
+            f = self.db.file.getnode (id)
+            self.assertEqual(f.name, name)
+            self.assertEqual(f.content, content)
+        self.assertEqual(msg.content, c)
+        self.compareMessages(self._get_mail(),
+'''FROM: roundup-admin@your.tracker.email.domain.example
+TO: chef@bork.bork.bork, richard@test.test
+Content-Type: text/plain; charset="iso-8859-1"
+Subject: [issue1] Testing...
+To: chef@bork.bork.bork, richard@test.test
+From: "Contrary, Mary" <issue_tracker@your.tracker.email.domain.example>
+Reply-To: Roundup issue tracker
+ <issue_tracker@your.tracker.email.domain.example>
+MIME-Version: 1.0
+Message-Id: <followup_dummy_id>
+In-Reply-To: <dummy_test_message_id>
+X-Roundup-Name: Roundup issue tracker
+X-Roundup-Loop: hello
+X-Roundup-Issue-Status: chatting
+X-Roundup-Issue-Files: unnamed
+Content-Transfer-Encoding: quoted-printable
+
+
+Contrary, Mary <mary@test.test> added the comment:
+
+umlaut =E4=F6=FC=C4=D6=DC=DF
+File 'unnamed' not attached - you can download it from http://tracker.examp=
+le/cgi-bin/roundup.cgi/bugs/file1.
+
+----------
+status: unread -> chatting
+
+_______________________________________________________________________
+Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
+<http://tracker.example/cgi-bin/roundup.cgi/bugs/issue1>
+_______________________________________________________________________
+''')
+
+    def testMultipartCharsetUTF8AttachFile(self):
+        c = 'umlaut \xc3\xa4\xc3\xb6\xc3\xbc\xc3\x84\xc3\x96\xc3\x9c\xc3\x9f'
+        self.doNewIssue()
+        self._handle_mail(self.multipart_msg_latin1)
+        messages = self.db.issue.get('1', 'messages')
+        messages.sort()
+        msg = self.db.msg.getnode (messages[-1])
+        assert(len(msg.files) == 1)
+        name = 'unnamed'
+        content = '<html>' + c + '</html>\n'
+        for n, id in enumerate (msg.files):
+            f = self.db.file.getnode (id)
+            self.assertEqual(f.name, name)
+            self.assertEqual(f.content, content)
+        self.assertEqual(msg.content, c)
+        self.compareMessages(self._get_mail(),
+'''FROM: roundup-admin@your.tracker.email.domain.example
+TO: chef@bork.bork.bork, richard@test.test
+Content-Type: multipart/mixed; boundary="utf-8"
+Subject: [issue1] Testing...
+To: chef@bork.bork.bork, richard@test.test
+From: "Contrary, Mary" <issue_tracker@your.tracker.email.domain.example>
+Reply-To: Roundup issue tracker
+ <issue_tracker@your.tracker.email.domain.example>
+MIME-Version: 1.0
+Message-Id: <followup_dummy_id>
+In-Reply-To: <dummy_test_message_id>
+X-Roundup-Name: Roundup issue tracker
+X-Roundup-Loop: hello
+X-Roundup-Issue-Status: chatting
+X-Roundup-Issue-Files: unnamed
+Content-Transfer-Encoding: quoted-printable
+
+
+--utf-8
+MIME-Version: 1.0
+Content-Type: text/plain; charset="utf-8"
+Content-Transfer-Encoding: quoted-printable
+
+
+Contrary, Mary <mary@test.test> added the comment:
+
+umlaut =C3=A4=C3=B6=C3=BC=C3=84=C3=96=C3=9C=C3=9F
+
+----------
+status: unread -> chatting
+
+_______________________________________________________________________
+Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
+<http://tracker.example/cgi-bin/roundup.cgi/bugs/issue1>
+_______________________________________________________________________
+--utf-8
+Content-Type: text/html
+MIME-Version: 1.0
+Content-Transfer-Encoding: base64
+Content-Disposition: attachment;
+ filename="unnamed"
+
+PGh0bWw+dW1sYXV0IMOkw7bDvMOEw5bDnMOfPC9odG1sPgo=
+
+--utf-8--
+''')
+
+    def testMultipartCharsetLatin1AttachFile(self):
+        c = 'umlaut \xc3\xa4\xc3\xb6\xc3\xbc\xc3\x84\xc3\x96\xc3\x9c\xc3\x9f'
+        self.doNewIssue()
+        self.db.config.MAIL_CHARSET = 'iso-8859-1'
+        self._handle_mail(self.multipart_msg_latin1)
+        messages = self.db.issue.get('1', 'messages')
+        messages.sort()
+        msg = self.db.msg.getnode (messages[-1])
+        assert(len(msg.files) == 1)
+        name = 'unnamed'
+        content = '<html>' + c + '</html>\n'
+        for n, id in enumerate (msg.files):
+            f = self.db.file.getnode (id)
+            self.assertEqual(f.name, name)
+            self.assertEqual(f.content, content)
+        self.assertEqual(msg.content, c)
+        self.compareMessages(self._get_mail(),
+'''FROM: roundup-admin@your.tracker.email.domain.example
+TO: chef@bork.bork.bork, richard@test.test
+Content-Type: multipart/mixed; boundary="utf-8"
+Subject: [issue1] Testing...
+To: chef@bork.bork.bork, richard@test.test
+From: "Contrary, Mary" <issue_tracker@your.tracker.email.domain.example>
+Reply-To: Roundup issue tracker
+ <issue_tracker@your.tracker.email.domain.example>
+MIME-Version: 1.0
+Message-Id: <followup_dummy_id>
+In-Reply-To: <dummy_test_message_id>
+X-Roundup-Name: Roundup issue tracker
+X-Roundup-Loop: hello
+X-Roundup-Issue-Status: chatting
+X-Roundup-Issue-Files: unnamed
+Content-Transfer-Encoding: quoted-printable
+
+
+--utf-8
+MIME-Version: 1.0
+Content-Type: text/plain; charset="iso-8859-1"
+Content-Transfer-Encoding: quoted-printable
+
+
+Contrary, Mary <mary@test.test> added the comment:
+
+umlaut =E4=F6=FC=C4=D6=DC=DF
+
+----------
+status: unread -> chatting
+
+_______________________________________________________________________
+Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
+<http://tracker.example/cgi-bin/roundup.cgi/bugs/issue1>
+_______________________________________________________________________
+--utf-8
+Content-Type: text/html
+MIME-Version: 1.0
+Content-Transfer-Encoding: base64
+Content-Disposition: attachment;
+ filename="unnamed"
+
+PGh0bWw+dW1sYXV0IMOkw7bDvMOEw5bDnMOfPC9odG1sPgo=
+
+--utf-8--
+''')
+
     def testSimpleFollowup(self):
         self.doNewIssue()
         self._handle_mail('''Content-Type: text/plain;