From f4b0accddbfda5a21a68d46b1d95998266647a55 Mon Sep 17 00:00:00 2001 From: Folker Bernitt Date: Wed, 3 Dec 2014 15:26:15 +0100 Subject: Fixed handling of mails with non us-ascii body. --- service/pixelated/adapter/mail.py | 19 +++++++++++++++---- service/test/unit/adapter/mail_test.py | 8 ++++++++ 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/service/pixelated/adapter/mail.py b/service/pixelated/adapter/mail.py index 472bdad4..949daa9e 100644 --- a/service/pixelated/adapter/mail.py +++ b/service/pixelated/adapter/mail.py @@ -22,8 +22,10 @@ import dateutil.parser as dateparser from pixelated.adapter.status import Status import pixelated.support.date from email.MIMEMultipart import MIMEMultipart -from email.MIMEText import MIMEText +from email.mime.text import MIMEText from pycryptopp.hash import sha256 +import re + class Mail(object): @property @@ -61,10 +63,16 @@ class Mail(object): mime = MIMEMultipart() for key, value in self.headers.items(): mime[str(key)] = str(value) - mime.attach(MIMEText(self.body, 'plain')) + mime.attach(MIMEText(self.body, 'plain', self._charset())) self._mime = mime return mime + def _charset(self): + if 'content_type' in self.headers and 'charset' in self.headers['content_type']: + return re.compile('.*charset=(.*)').match(self.headers['content_type']).group(1) + else: + return 'us-ascii' + @property def raw(self): return self._mime_multipart.as_string() @@ -207,19 +215,22 @@ class PixelatedMail(Mail): @property def headers(self): _headers = {} + hdoc_headers = self.hdoc.content['headers'] for header in ['To', 'Cc', 'Bcc']: - header_value = self.hdoc.content['headers'].get(header) + header_value = hdoc_headers.get(header) if not header_value: continue _headers[header] = header_value if type(header_value) is list else header_value.split(',') _headers[header] = map(lambda x: x.strip(), _headers[header]) for header in ['From', 'Subject']: - _headers[header] = self.hdoc.content['headers'].get(header) + _headers[header] = hdoc_headers.get(header) _headers['Date'] = self._get_date() if self.parts and len(self.parts['alternatives']) > 1: _headers['content_type'] = 'multipart/alternative; boundary="%s"' % self.boundary + elif self.hdoc.content['headers'].get('Content-Type'): + _headers['content_type'] = hdoc_headers.get('Content-Type') return _headers def _get_date(self): diff --git a/service/test/unit/adapter/mail_test.py b/service/test/unit/adapter/mail_test.py index 4ce398b8..e0879b44 100644 --- a/service/test/unit/adapter/mail_test.py +++ b/service/test/unit/adapter/mail_test.py @@ -126,6 +126,14 @@ class TestPixelatedMail(unittest.TestCase): self.assertNotIn(',', address) self.assertEquals(4, len(mail.headers[header_label])) + def test_content_type_is_read_from_headers_for_plain_mail_when_converted_to_raw(self): + fdoc, hdoc, bdoc = test_helper.leap_mail(flags=['\\Recent'], body=u'some umlaut \xc3', extra_headers={'Content-Type': 'text/plain; charset=ISO-8859-1'}) + hdoc.content['headers']['Subject'] = 'The subject' + hdoc.content['headers']['From'] = 'me@pixelated.org' + mail = PixelatedMail.from_soledad(fdoc, hdoc, bdoc, soledad_querier=self.querier) + + mail.raw + class InputMailTest(unittest.TestCase): mail_dict = lambda x: { -- cgit v1.2.3