summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOlivier Dony <odo@openerp.com>2014-10-10 19:21:18 +0200
committerOlivier Dony <odo@openerp.com>2014-10-10 19:21:18 +0200
commitedd94b623eaf44f308daddba51e38c08ccd4e7b0 (patch)
tree1adb10a3a10040bb27a93753a519ddbb715c762c
parentb13898c05806b4270578fe7234e79deda3a5539d (diff)
parent1b49a876196de1f4b6568ff1751f7c7c6b2d5002 (diff)
[MERGE] Forward-port 7.0 up to 1b49a87
-rw-r--r--addons/mail/mail_thread.py9
-rw-r--r--addons/mail/tests/test_mail_gateway.py55
-rw-r--r--openerp/addons/base/ir/ir_mail_server.py33
-rw-r--r--openerp/addons/base/res/res_users.py2
-rw-r--r--openerp/tools/mail.py2
5 files changed, 74 insertions, 27 deletions
diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py
index 0538ad7b7f8..5d303ecff89 100644
--- a/addons/mail/mail_thread.py
+++ b/addons/mail/mail_thread.py
@@ -1154,9 +1154,13 @@ class mail_thread(osv.AbstractModel):
body = tools.append_content_to_html(u'', body, preserve=True)
else:
alternative = False
+ mixed = False
+ html = u''
for part in message.walk():
if part.get_content_type() == 'multipart/alternative':
alternative = True
+ if part.get_content_type() == 'multipart/mixed':
+ mixed = True
if part.get_content_maintype() == 'multipart':
continue # skip container
# part.get_filename returns decoded value if able to decode, coded otherwise.
@@ -1183,8 +1187,11 @@ class mail_thread(osv.AbstractModel):
encoding, errors='replace'), preserve=True)
# 3) text/html -> raw
elif part.get_content_type() == 'text/html':
+ # mutlipart/alternative have one text and a html part, keep only the second
+ # mixed allows several html parts, append html content
+ append_content = not alternative or (html and mixed)
html = tools.ustr(part.get_payload(decode=True), encoding, errors='replace')
- if alternative:
+ if not append_content:
body = html
else:
body = tools.append_content_to_html(body, html, plaintext=False)
diff --git a/addons/mail/tests/test_mail_gateway.py b/addons/mail/tests/test_mail_gateway.py
index 3fbf3d40405..023a009a9ee 100644
--- a/addons/mail/tests/test_mail_gateway.py
+++ b/addons/mail/tests/test_mail_gateway.py
@@ -143,6 +143,53 @@ X-Attachment-Id: f_hkpb27k00
dGVzdAo=
--089e01536c4ed4d17204e49b8e96--"""
+MAIL_MULTIPART_MIXED_TWO = """X-Original-To: raoul@grosbedon.fr
+Delivered-To: raoul@grosbedon.fr
+Received: by mail1.grosbedon.com (Postfix, from userid 10002)
+ id E8166BFACA; Fri, 23 Aug 2013 13:18:01 +0200 (CEST)
+From: "Bruce Wayne" <bruce@wayneenterprises.com>
+Content-Type: multipart/alternative;
+ boundary="Apple-Mail=_9331E12B-8BD2-4EC7-B53E-01F3FBEC9227"
+Message-Id: <6BB1FAB2-2104-438E-9447-07AE2C8C4A92@sexample.com>
+Mime-Version: 1.0 (Mac OS X Mail 7.3 \(1878.6\))
+
+--Apple-Mail=_9331E12B-8BD2-4EC7-B53E-01F3FBEC9227
+Content-Transfer-Encoding: 7bit
+Content-Type: text/plain;
+ charset=us-ascii
+
+First and second part
+
+--Apple-Mail=_9331E12B-8BD2-4EC7-B53E-01F3FBEC9227
+Content-Type: multipart/mixed;
+ boundary="Apple-Mail=_CA6C687E-6AA0-411E-B0FE-F0ABB4CFED1F"
+
+--Apple-Mail=_CA6C687E-6AA0-411E-B0FE-F0ABB4CFED1F
+Content-Transfer-Encoding: 7bit
+Content-Type: text/html;
+ charset=us-ascii
+
+<html><head></head><body>First part</body></html>
+
+--Apple-Mail=_CA6C687E-6AA0-411E-B0FE-F0ABB4CFED1F
+Content-Disposition: inline;
+ filename=thetruth.pdf
+Content-Type: application/pdf;
+ name="thetruth.pdf"
+Content-Transfer-Encoding: base64
+
+SSBhbSB0aGUgQmF0TWFuCg==
+
+--Apple-Mail=_CA6C687E-6AA0-411E-B0FE-F0ABB4CFED1F
+Content-Transfer-Encoding: 7bit
+Content-Type: text/html;
+ charset=us-ascii
+
+<html><head></head><body>Second part</body></html>
+--Apple-Mail=_CA6C687E-6AA0-411E-B0FE-F0ABB4CFED1F--
+
+--Apple-Mail=_9331E12B-8BD2-4EC7-B53E-01F3FBEC9227--
+"""
class TestMailgateway(TestMail):
@@ -164,6 +211,14 @@ class TestMailgateway(TestMail):
self.assertIn('<div dir="ltr">Should create a multipart/mixed: from gmail, <b>bold</b>, with attachment.<br clear="all"><div><br></div>', res.get('body', ''),
'message_parse: html version should be in body after parsing multipart/mixed')
+ res = self.mail_thread.message_parse(cr, uid, MAIL_MULTIPART_MIXED_TWO)
+ self.assertNotIn('First and second part', res.get('body', ''),
+ 'message_parse: text version should not be in body after parsing multipart/mixed')
+ self.assertIn('First part', res.get('body', ''),
+ 'message_parse: first part of the html version should be in body after parsing multipart/mixed')
+ self.assertIn('Second part', res.get('body', ''),
+ 'message_parse: second part of the html version should be in body after parsing multipart/mixed')
+
@mute_logger('openerp.addons.mail.mail_thread', 'openerp.osv.orm')
def test_10_message_process(self):
""" Testing incoming emails processing. """
diff --git a/openerp/addons/base/ir/ir_mail_server.py b/openerp/addons/base/ir/ir_mail_server.py
index a21d8e67176..9e87d393cdb 100644
--- a/openerp/addons/base/ir/ir_mail_server.py
+++ b/openerp/addons/base/ir/ir_mail_server.py
@@ -24,7 +24,7 @@ from email.MIMEBase import MIMEBase
from email.MIMEMultipart import MIMEMultipart
from email.Charset import Charset
from email.Header import Header
-from email.Utils import formatdate, make_msgid, COMMASPACE, parseaddr
+from email.utils import formatdate, make_msgid, COMMASPACE, getaddresses, formataddr
from email import Encoders
import logging
import re
@@ -140,29 +140,14 @@ def encode_rfc2822_address_header(header_text):
``"Name"`` portion by the RFC2047-encoded
version, preserving the address part untouched.
"""
- header_text_utf8 = tools.ustr(header_text).encode('utf-8')
- header_text_ascii = try_coerce_ascii(header_text_utf8)
- if header_text_ascii:
- return header_text_ascii
-
- name, email = parseaddr(header_text_utf8)
- if not name:
- return email
-
- # non-ASCII characters are present, attempt to
- # replace all "Name" patterns with the RFC2047-
- # encoded version
- name_encoded = str(Header(name, 'utf-8'))
- header_text_utf8 = "%s <%s>" % (name_encoded, email)
- # try again after encoding
- header_text_ascii = try_coerce_ascii(header_text_utf8)
- if header_text_ascii:
- return header_text_ascii
- # fallback to extracting pure addresses only, which could
- # still cause a failure downstream if the actual addresses
- # contain non-ASCII characters
- return COMMASPACE.join(extract_rfc2822_addresses(header_text_utf8))
-
+ def encode_addr(addr):
+ name, email = addr
+ if not try_coerce_ascii(name):
+ name = str(Header(name, 'utf-8'))
+ return formataddr((name, email))
+
+ addresses = getaddresses([tools.ustr(header_text).encode('utf-8')])
+ return COMMASPACE.join(map(encode_addr, addresses))
class ir_mail_server(osv.osv):
"""Represents an SMTP server, able to send outgoing emails, with SSL and TLS capabilities."""
diff --git a/openerp/addons/base/res/res_users.py b/openerp/addons/base/res/res_users.py
index 0d6f919c557..3650fdd0e5f 100644
--- a/openerp/addons/base/res/res_users.py
+++ b/openerp/addons/base/res/res_users.py
@@ -354,7 +354,7 @@ class res_users(osv.osv):
if not context:
context={}
ids = []
- if name:
+ if name and operator in ['=', 'ilike']:
ids = self.search(cr, user, [('login','=',name)]+ args, limit=limit, context=context)
if not ids:
ids = self.search(cr, user, [('name',operator,name)]+ args, limit=limit, context=context)
diff --git a/openerp/tools/mail.py b/openerp/tools/mail.py
index d7882dd6b51..d793de3089b 100644
--- a/openerp/tools/mail.py
+++ b/openerp/tools/mail.py
@@ -569,7 +569,7 @@ def append_content_to_html(html, content, plaintext=True, preserve=False, contai
elif plaintext:
content = '\n%s\n' % plaintext2html(content, container_tag)
else:
- content = re.sub(r'(?i)(</?html.*>|</?body.*>|<!\W*DOCTYPE.*>)', '', content)
+ content = re.sub(r'(?i)(</?(?:html|body|head|!\s*DOCTYPE)[^>]*>)', '', content)
content = u'\n%s\n' % ustr(content)
# Force all tags to lowercase
html = re.sub(r'(</?)\W*(\w+)([ >])',