fix(sendmail): respect inline_images parameter in sendmail
This commit is contained in:
parent
aee0295275
commit
a252e7e265
2 changed files with 62 additions and 3 deletions
|
|
@ -210,7 +210,18 @@ class EMail:
|
|||
|
||||
if has_inline_images:
|
||||
# process inline images
|
||||
message, _inline_images = replace_filename_with_cid(message)
|
||||
provided_images = {}
|
||||
if inline_images:
|
||||
for img in inline_images:
|
||||
if img.get("filename") and img.get("filecontent"):
|
||||
# index by full path and basename for flexible matching
|
||||
provided_images[img["filename"]] = img["filecontent"]
|
||||
basename = img["filename"].rsplit("/", 1)[-1]
|
||||
if basename not in provided_images:
|
||||
provided_images[basename] = img["filecontent"]
|
||||
|
||||
# process inline images while preferring provided_images over disk reads
|
||||
message, _inline_images = replace_filename_with_cid(message, provided_images)
|
||||
|
||||
# prepare parts
|
||||
msg_related = MIMEMultipart("related", policy=policy.SMTP)
|
||||
|
|
@ -552,11 +563,22 @@ def get_footer(email_account, footer=None):
|
|||
return footer
|
||||
|
||||
|
||||
def replace_filename_with_cid(message):
|
||||
def replace_filename_with_cid(message, provided_images=None):
|
||||
"""Replaces <img embed="assets/frappe/images/filename.jpg" ...> with
|
||||
<img src="cid:content_id" ...> and return the modified message and
|
||||
a list of inline_images with {filename, filecontent, content_id}
|
||||
|
||||
Args:
|
||||
message: The HTML message to process
|
||||
provided_images: A dictionary of images to use instead of reading from disk
|
||||
Example:
|
||||
{
|
||||
"assets/frappe/images/filename.jpg": filecontent,
|
||||
"filename.jpg": filecontent,
|
||||
}
|
||||
"""
|
||||
if provided_images is None:
|
||||
provided_images = {}
|
||||
|
||||
inline_images = []
|
||||
|
||||
|
|
@ -571,7 +593,11 @@ def replace_filename_with_cid(message):
|
|||
img_path_escaped = frappe.utils.html_utils.unescape_html(img_path)
|
||||
filename = img_path_escaped.rsplit("/")[-1]
|
||||
|
||||
# check if the image is provided in the provided_images(by checking full path and basename)
|
||||
filecontent = provided_images.get(img_path_escaped) or provided_images.get(filename)
|
||||
if not filecontent:
|
||||
filecontent = get_filecontent_from_path(img_path_escaped)
|
||||
|
||||
if not filecontent:
|
||||
message = re.sub(f"""embed=['"]{re.escape(img_path)}['"]""", "", message)
|
||||
continue
|
||||
|
|
|
|||
|
|
@ -137,6 +137,39 @@ w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
|||
""".format(inline_images[0].get("content_id"))
|
||||
self.assertEqual(message, processed_message)
|
||||
|
||||
def test_sendmail_inline_images_parameter_respected(self):
|
||||
"""Test that inline_images parameter works through sendmail."""
|
||||
|
||||
test_image_content = b"FAKE_PNG_BINARY_CONTENT_FOR_TESTING"
|
||||
|
||||
html_content = '<div><img embed="files/nonexistent_test_image.png" alt="Logo"></div>'
|
||||
|
||||
inline_images = [
|
||||
{
|
||||
"filename": "files/nonexistent_test_image.png",
|
||||
"filecontent": test_image_content,
|
||||
}
|
||||
]
|
||||
|
||||
# Use QueueBuilder directly (what sendmail uses internally)
|
||||
from frappe.email.doctype.email_queue.email_queue import QueueBuilder
|
||||
|
||||
builder = QueueBuilder(
|
||||
recipients=["test@example.com"],
|
||||
sender="me@example.com",
|
||||
subject="Test Inline Images",
|
||||
message=html_content,
|
||||
inline_images=inline_images,
|
||||
)
|
||||
|
||||
# Get the email content that would be sent
|
||||
mail = builder.prepare_email_content()
|
||||
email_string = mail.as_string()
|
||||
|
||||
# Assertions
|
||||
self.assertIn("cid:", email_string)
|
||||
self.assertNotIn('embed="files/nonexistent_test_image.png"', email_string)
|
||||
|
||||
def test_inline_styling(self):
|
||||
html = """
|
||||
<h3>Hi John</h3>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue