From 0652c3befffbe0cc5180b89d8d732110c3b3bd70 Mon Sep 17 00:00:00 2001 From: Parthiv Patel Date: Thu, 13 Apr 2023 08:35:22 +0000 Subject: [PATCH] [PATCH] Upstream patch - 13042023 --- addons/hr_timesheet/models/hr_timesheet.py | 22 ++++++++---- addons/mail/models/mail_thread.py | 18 ++++++---- addons/test_mail/data/test_mail_data.py | 33 ++++++++++++++++++ addons/test_mail/tests/test_mail_gateway.py | 18 ++++++++++ addons/web/static/src/fonts/tiktok_only.woff | Bin 0 -> 1220 bytes .../src/scss/fontawesome_overridden.scss | 16 +++++++++ 6 files changed, 94 insertions(+), 13 deletions(-) create mode 100644 addons/web/static/src/fonts/tiktok_only.woff diff --git a/addons/hr_timesheet/models/hr_timesheet.py b/addons/hr_timesheet/models/hr_timesheet.py index 7ee9d69087..55e2085a3d 100644 --- a/addons/hr_timesheet/models/hr_timesheet.py +++ b/addons/hr_timesheet/models/hr_timesheet.py @@ -170,13 +170,23 @@ class AccountAnalyticLine(models.Model): if self.env.user.has_group('hr_timesheet.group_hr_timesheet_user'): # Then, he is internal user, and we take the domain for this current user return self.env['ir.rule']._compute_domain(self._name) - return ['&', + return [ + '|', + '&', '|', '|', '|', - ('task_id.project_id.message_partner_ids', 'child_of', [self.env.user.partner_id.commercial_partner_id.id]), - ('task_id.message_partner_ids', 'child_of', [self.env.user.partner_id.commercial_partner_id.id]), - ('task_id.project_id.allowed_portal_user_ids', 'child_of', [self.env.user.id]), - ('task_id.allowed_user_ids', 'in', [self.env.user.id]), - ('task_id.project_id.privacy_visibility', '=', 'portal')] + ('task_id.project_id.message_partner_ids', 'child_of', [self.env.user.partner_id.commercial_partner_id.id]), + ('task_id.message_partner_ids', 'child_of', [self.env.user.partner_id.commercial_partner_id.id]), + ('task_id.project_id.allowed_portal_user_ids', 'child_of', [self.env.user.id]), + ('task_id.allowed_user_ids', 'in', [self.env.user.id]), + ('task_id.project_id.privacy_visibility', '=', 'portal'), + '&', + ('task_id', '=', False), + '&', + '|', + ('project_id.message_partner_ids', 'child_of', [self.env.user.partner_id.commercial_partner_id.id]), + ('project_id.allowed_portal_user_ids', 'child_of', [self.env.user.id]), + ('project_id.privacy_visibility', '=', 'portal') + ] def _timesheet_preprocess(self, vals): """ Deduce other field values from the one given. diff --git a/addons/mail/models/mail_thread.py b/addons/mail/models/mail_thread.py index 3dd195b7ed..5cb7d3939a 100644 --- a/addons/mail/models/mail_thread.py +++ b/addons/mail/models/mail_thread.py @@ -1288,25 +1288,27 @@ class MailThread(models.AbstractModel): filename = part.get_filename() # I may not properly handle all charsets encoding = part.get_content_charset() # None if attachment + content = part.get_content() + info = {'encoding': encoding} # 0) Inline Attachments -> attachments, with a third part in the tuple to match cid / attachment if filename and part.get('content-id'): - inner_cid = part.get('content-id').strip('><') - attachments.append(self._Attachment(filename, part.get_content(), {'cid': inner_cid})) + info['cid'] = part.get('content-id').strip('><') + attachments.append(self._Attachment(filename, content, info)) continue # 1) Explicit Attachments -> attachments if filename or part.get('content-disposition', '').strip().startswith('attachment'): - attachments.append(self._Attachment(filename or 'attachment', part.get_content(), {})) + attachments.append(self._Attachment(filename or 'attachment', content, info)) continue # 2) text/plain ->
                 if part.get_content_type() == 'text/plain' and (not alternative or not body):
-                    body = tools.append_content_to_html(body, tools.ustr(part.get_content(),
+                    body = tools.append_content_to_html(body, tools.ustr(content,
                                                                          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_content(), encoding, errors='replace')
+                    html = tools.ustr(content, encoding, errors='replace')
                     if not append_content:
                         body = html
                     else:
@@ -1315,7 +1317,7 @@ class MailThread(models.AbstractModel):
                     body = tools.html_sanitize(body, sanitize_tags=False, strip_classes=True)
                 # 4) Anything else -> attachment
                 else:
-                    attachments.append(self._Attachment(filename or 'attachment', part.get_content(), {}))
+                    attachments.append(self._Attachment(filename or 'attachment', content, info))
 
         return self._message_parse_extract_payload_postprocess(message, {'body': body, 'attachments': attachments})
 
@@ -1735,13 +1737,15 @@ class MailThread(models.AbstractModel):
                 cid = False
                 if len(attachment) == 2:
                     name, content = attachment
+                    info = {}
                 elif len(attachment) == 3:
                     name, content, info = attachment
                     cid = info and info.get('cid')
                 else:
                     continue
                 if isinstance(content, str):
-                    content = content.encode('utf-8')
+                    encoding = info and info.get('encoding')
+                    content = content.encode(encoding or 'utf-8')
                 elif isinstance(content, EmailMessage):
                     content = content.as_bytes()
                 elif content is None:
diff --git a/addons/test_mail/data/test_mail_data.py b/addons/test_mail/data/test_mail_data.py
index 221c86953f..0e8a882e8e 100644
--- a/addons/test_mail/data/test_mail_data.py
+++ b/addons/test_mail/data/test_mail_data.py
@@ -214,6 +214,39 @@ Content-Type: text/html;
 --Apple-Mail=_9331E12B-8BD2-4EC7-B53E-01F3FBEC9227--
 """
 
+MAIL_FILE_ENCODING = """MIME-Version: 1.0
+Date: Sun, 26 Mar 2023 05:23:22 +0200
+Message-ID: {msg_id}
+Subject: {subject}
+From: "Sylvie Lelitre" 
+To: groups@test.com
+Content-Type: multipart/mixed; boundary="000000000000b951de05f7c47a9e"
+
+--000000000000b951de05f7c47a9e
+Content-Type: multipart/alternative; boundary="000000000000b951da05f7c47a9c"
+
+--000000000000b951da05f7c47a9c
+Content-Type: text/plain; charset="UTF-8"
+
+Test Body
+
+--000000000000b951da05f7c47a9c
+Content-Type: text/html; charset="UTF-8"
+
+
Test Body
+ +--000000000000b951da05f7c47a9c-- +--000000000000b951de05f7c47a9e +Content-Type: text/plain; name="test.txt"{charset} +Content-Disposition: attachment; filename="test.txt" +Content-Transfer-Encoding: base64 +X-Attachment-Id: f_lfosfm0l0 +Content-ID: + +{content} + +--000000000000b951de05f7c47a9e-- +""" MAIL_MULTIPART_BINARY_OCTET_STREAM = """X-Original-To: raoul@grosbedon.fr Delivered-To: raoul@grosbedon.fr diff --git a/addons/test_mail/tests/test_mail_gateway.py b/addons/test_mail/tests/test_mail_gateway.py index aec69ce9bd..8939eb916c 100644 --- a/addons/test_mail/tests/test_mail_gateway.py +++ b/addons/test_mail/tests/test_mail_gateway.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- # Part of Odoo, Flectra. See LICENSE file for full copyright and licensing details. +import base64 import socket from unittest.mock import DEFAULT @@ -1468,6 +1469,23 @@ class TestMailgateway(TestMailCommon): self.assertEqual(record.name, 'Spammy') self.assertEqual(record._name, 'mail.test.gateway') + @mute_logger('flectra.addons.mail.models.mail_thread') + def test_message_process_file_encoding(self): + """ Incoming email with file encoding """ + file_content = 'Hello World' + for encoding in ['', 'UTF-8', 'UTF-16LE', 'UTF-32BE']: + file_content_b64 = base64.b64encode(file_content.encode(encoding or 'utf-8')).decode() + record = self.format_and_process(test_mail_data.MAIL_FILE_ENCODING, + self.email_from, 'groups@test.com', + subject='Test Charset %s' % encoding or 'Unset', + charset='; charset="%s"' % encoding if encoding else '', + content=file_content_b64 + ) + attachment = record.message_ids.attachment_ids + self.assertEqual(file_content, attachment.raw.decode(encoding or 'utf-8')) + if encoding not in ['', 'UTF-8']: + self.assertNotEqual(file_content, attachment.raw.decode('utf-8')) + class TestMailThreadCC(TestMailCommon): diff --git a/addons/web/static/src/fonts/tiktok_only.woff b/addons/web/static/src/fonts/tiktok_only.woff new file mode 100644 index 0000000000000000000000000000000000000000..c589fe0ae6543941ab7bb0198ce46819c1cb4cb4 GIT binary patch literal 1220 zcmXT-cXMN4WB>w|BMf{Xnr#Y%4`QPNH@6U9pt==6Q5g`P^+;`ryNjzEP^lj-za!Y`GCKe!H0EAf`8F+K@lY#1(B7l4@FrLE@lABlow3l%TkS`C! z3Je|$ae0ZksSFIvHb8Mjpn5Kb<4d9o@{3D=?n?lwQ2}D3WfOf4R?JCGNJ&UwcqEr^ zIJcs1_IjRAK0FE^4%`i8aoTNF(p~#U>6zIDH41z$vfM_88{|97$LPA4c$6T-GOd)drOIcNNi zA7zd1ft4@d)Yo6%)HRZF*F~P63_FYvw z_?c`U+_+cC9L=GbTQR4#?|jxF2ZDZgwTKUw++Q_+$^6AJ_sCIiezs}vr~mwShC$+iG}H6g?yDOP2>8#l{_^+3oul0QY}n`g{Cel`UWtl#$r^GS z9a?Su3QkN+Y?l&J&M`=c*SnVt~%)?e>@*;bj{W0x|7{hwr=Jf`jS?pY11 z&bAprTCex$y_q&6=yX9!zOVWcGi$MIC#Uae>sR&(Zz~P`GIhr1zx%7M@uqdm(AkyZ z5;V0mXy+NP#arf_?zX;pW|2kKp}5mO-OfHdP&e88)3#?VS*z1-?{bct8uWVQrKtFw z-`LF``m_QQ0VpjcF*N@#msDvKQD(MEVC*(BG}<`*S?VsS8P<#pF-urLX@wD(&zYd< u{sChWBO5218Zf;bQJ5vz#K@Y<-~dts#0GqPy_ literal 0 HcmV?d00001 diff --git a/addons/web/static/src/scss/fontawesome_overridden.scss b/addons/web/static/src/scss/fontawesome_overridden.scss index a234dbc9f8..a2fb3fe1c8 100644 --- a/addons/web/static/src/scss/fontawesome_overridden.scss +++ b/addons/web/static/src/scss/fontawesome_overridden.scss @@ -1,3 +1,19 @@ +// This is a patch of the font awesome library to add the TikTok icon. +@font-face { + font-family: 'FontAwesome-tiktok-only'; + src: url('../../src/fonts/tiktok_only.woff'); + font-weight: normal; + font-style: normal; + font-display: block; +} +.fa.fa-tiktok { + font-family: 'FontAwesome-tiktok-only' !important; + + &:before { + content: '\e07b'; + } +} + // This is rtl language specific fix // It will override the font awesome symbols and flip them 180 degree .o_rtl {