Change: use simpler method for attaching files (#8845)

This commit is contained in:
shamoon 2025-01-21 10:38:21 -08:00 committed by GitHub
parent 0ea4da03a7
commit bfc11a545b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 91 additions and 34 deletions

View File

@ -1,7 +1,5 @@
from email.encoders import encode_base64 from email import message_from_bytes
from email.mime.base import MIMEBase
from pathlib import Path from pathlib import Path
from urllib.parse import quote
from django.conf import settings from django.conf import settings
from django.core.mail import EmailMessage from django.core.mail import EmailMessage
@ -27,35 +25,14 @@ def send_email(
if attachment: if attachment:
# Something could be renaming the file concurrently so it can't be attached # Something could be renaming the file concurrently so it can't be attached
with FileLock(settings.MEDIA_LOCK), attachment.open("rb") as f: with FileLock(settings.MEDIA_LOCK), attachment.open("rb") as f:
file_content = f.read() content = f.read()
if attachment_mime_type == "message/rfc822":
# See https://forum.djangoproject.com/t/using-emailmessage-with-an-attached-email-file-crashes-due-to-non-ascii/37981
content = message_from_bytes(f.read())
main_type, sub_type = ( email.attach(
attachment_mime_type.split("/", 1) filename=attachment.name,
if attachment_mime_type content=content,
else ("application", "octet-stream") mimetype=attachment_mime_type,
) )
mime_part = MIMEBase(main_type, sub_type)
mime_part.set_payload(file_content)
encode_base64(mime_part)
# see https://github.com/stumpylog/tika-client/blob/f65a2b792fc3cf15b9b119501bba9bddfac15fcc/src/tika_client/_base.py#L46-L57
try:
attachment.name.encode("ascii")
except UnicodeEncodeError:
filename_safed = attachment.name.encode("ascii", "ignore").decode(
"ascii",
)
filepath_quoted = quote(attachment.name, encoding="utf-8")
mime_part.add_header(
"Content-Disposition",
f"attachment; filename={filename_safed}; filename*=UTF-8''{filepath_quoted}",
)
else:
mime_part.add_header(
"Content-Disposition",
f"attachment; filename={attachment.name}",
)
email.attach(mime_part)
return email.send() return email.send()

View File

@ -0,0 +1,63 @@
From: =?UTF-8?Q?My_Name=C3=B6er?= <myaddr@volkswagen.de>
Return-Path: <myaddr@volkswagen.de>
X-Original-To: rechnung@domain.de
Delivered-To: rechnung@domain.de
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=domainb.de; s=default;
t=1736973836; bh=bCUrrHd7c5mrvMbK20=;
h=Date:To:From:Subject:From;
b=QPaQKuzx2adfCr0S18KVgA5x01KXZknaaEpQW49Ock2ghScLAvv3ij8xfzUbZewCT
CuUAYBmCxbN5ygIztJXfgWpl1Cx5FsVQNpdZ/6Ns=
Received: by mail.domain.de (Postfix, from userid 121)
id 407BCE078A; Wed, 15 Jan 2025 21:43:56 +0100 (CET)
X-Spam-Checker-Version: SpamAssassin 4.0.0 (2022-12-13) on imail.domain.de
X-Spam-Level:
X-Spam-Status: No, score=-3.0 required=1.7 tests=ALL_TRUSTED,BAYES_00,
DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU autolearn=ham autolearn_force=no
version=4.0.0
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=domain.de; s=default;
t=1736973835; bh=bCUrrHvn+Hd7c5mrvMbK20=;
h=Date:To:From:Subject:From;
b=AjGxzFALRR0AixC1uRhFuQkb4MoBqju1NInlUzx9w+toniNx3ifgkXpGxiV7+JJsr
Z+jNZxck3D3M05ETYnrGInO+vDlosfFU2WqnZn+E=
Received: from [192.168.8.154] (unknown [1.1.1.1])
(using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)
key-exchange X25519 server-signature ECDSA (prime256v1) server-digest
SHA256)
(No client certificate requested)
(Authenticated sender: myuser)
by mail.domain.de (Postfix) with ESMTPSA id C8BC6DF926
for <rechnung@domain.de>; Wed, 15 Jan 2025 21:43:55 +0100 (CET)
Message-ID: <da0c12c1-58c3-4f3d-ab89-9ae04@domain.de>
Date: Wed, 15 Jan 2025 21:43:52 +0100
MIME-Version: 1.0
User-Agent: Mozilla Thunderbird
Content-Language: de-DE
To: rechnung@domain.de
Subject: No Umlauts here
Autocrypt: addr=myaddr@domain.de; keydata=
xsDiBEK4/dERBACj7Kn2Skjnyq/Q69FKLSd9WJg/7Ta3aZwWiaizzAnB/avBoN9/NPkVCQbB
jeJ8G/uOtYDCgjmxeBNMVM3DOMTu4QfLnl0BoQz811bxiaPqQ6YLRA4MZrawZwerIOS2oSk2
FDGKsZvAYCG439QK102XPlSPC7c4/oQ+3fwkeqFpEwCg4XYOfTNzis6CZPgkQqyVrpaYR5kD
/j1HIDd1B75eeCb8ifoyWoWHB+cVHR+kEuMw1FMZt7UQ6Pb5nfQTcpEvrH9BTc0GKmTzj1N3
ExOPaNaGtsc7FAST+5dYflfL1+WVzsNJWgIp6PoAL1XoCZ6l63/qOrHtnp6l42IO8Rg2lDcc
25YdfiRSlTWuKvleT/okyc6jHioEA/9bUPbpdmUyR5kWRkdRBTjjCipl+o8rSlparnnk+7jh
1cvOHJlNJ/MYP9vcgDGYFIv+38sY4+UuBBoNmSS7yN5yKpT+XIsSgMEvyRPP6lr1GJ76aT2v
dIvcozHdC9g+nu6AlKgywdWW3hq5IjqRqnmVQfUN/1dL/D1ZImclEJoZR80lQ2hyaXN0aWFu
IFZvZWxrZXIgPGN2b2Vsa2VyQGtuZWJiLmRlPsJ3BBMRCAA3AhsjBgsJCAcDAgQVAggDBBYC
AwECHgECF4AWIQQl96acg1HmEUgEtrfRc0hiUBebOwUCXwQmvwAKCRDRc0hiUBebOxeiAJ43
bk2DCMuEVho3wRUqEyhNk0/mwQCaA60n1eTn+6bs2WXttTVGkBJGadzOwU0EQrj92RAIAKJz
rvwheohL4D327LEpy1AkIjUJotYUt9fPW+MVDSsoyj67HFTRz1WcK51+/8Fi6jedKxmR3hAi
GlZRvpsJ2chOuaynMac0Uv42rnSGHcLZf0KxLG+r7HOPSEAnSrbDAhWbuqyV994vCIfG9LDz
RDocaUEyJ7M+QV4VGS6Z3PPgxm78kCJ5TGHXRA96ponSptkyfIxvKHBa2TyrhMoLj4TmW4CO
SHmQD2e3EVIYlhERdPEQ5DmCljeO19ZopjNOLcAx4eOyguwvjpdeLUQJdaryWo56USWKbrmU
VrK4OodWkgcUvaagvey0MkABZkY0RMRKrfMuGb+Vw2nH9OGaRysAAwYH/AxC/+/m+OTA6tmA
AXd31vpMNUdVoPjyO+FQ7f8mwXa3SjPZeQLvpA1RfYFdDtSfr16RI8s41xtL12IYZr4nyRG/
wYPmM2WvcTUp3vWVizzHSERlarONc7aaCGXghg6Trpbz7+tv2MOpRLMfJd+6kyCz5pRSGeuX
z0iIxWSny1+Vc9uGgxyjJ21FFuvYPR8xmjfCGXvsnWLhKxTPNdhIG6/im/1/uTznzlfGUvgx
eNuzVphaVSPzP5DBVxJbKZzZYKOydQLx0Z79YF2xCGmz80EsSajpQNMvNYuNQXuH1ogFIP7e
PNOoaoakYuLE1YMhWL+AJzYRRevW8k/VLBgsYvbCRgQYEQIABgUCQrj92QAKCRDRc0hiUBeb
O/HXAJ0WAbB0sQ0SBVF+2Nlabw4HICAiKwCg4Fe9VjcfR4+ZJqq3Mx1c+IAE65c=
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 8bit
But here: üöäüäö

View File

@ -2149,9 +2149,8 @@ class TestWorkflows(
EMAIL_ENABLED=True, EMAIL_ENABLED=True,
PAPERLESS_URL="http://localhost:8000", PAPERLESS_URL="http://localhost:8000",
) )
@mock.patch("httpx.post")
@mock.patch("django.core.mail.message.EmailMessage.send") @mock.patch("django.core.mail.message.EmailMessage.send")
def test_workflow_email_include_file(self, mock_email_send, mock_post): def test_workflow_email_include_file(self, mock_email_send):
""" """
GIVEN: GIVEN:
- Document updated workflow with email action - Document updated workflow with email action
@ -2199,6 +2198,24 @@ class TestWorkflows(
mock_email_send.assert_called_once() mock_email_send.assert_called_once()
mock_email_send.reset_mock()
# test with .eml file
test_file2 = shutil.copy(
self.SAMPLE_DIR / "eml_with_umlaut.eml",
self.dirs.scratch_dir / "eml_with_umlaut.eml",
)
doc2 = Document.objects.create(
title="sample eml",
checksum="123456",
filename=test_file2,
mime_type="message/rfc822",
)
run_workflows(WorkflowTrigger.WorkflowTriggerType.DOCUMENT_UPDATED, doc2)
mock_email_send.assert_called_once()
@override_settings( @override_settings(
EMAIL_ENABLED=False, EMAIL_ENABLED=False,
) )