From 6d3faf49930b03e1edc06a22b84cf1d00c782b56 Mon Sep 17 00:00:00 2001 From: Serghei Mihai Date: Mon, 22 Aug 2016 13:51:07 +0200 Subject: [PATCH] include filename only for attached inline images (#12872) --- corbo/models.py | 23 +++++++++++++++++++---- tests/test_emailing.py | 11 +++++++---- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/corbo/models.py b/corbo/models.py index c6d1787..1505638 100644 --- a/corbo/models.py +++ b/corbo/models.py @@ -1,3 +1,5 @@ +import os +import hashlib from datetime import datetime import logging import urlparse @@ -23,6 +25,16 @@ channel_choices = ( logger = logging.getLogger(__name__) + +def transform_image_src(src, **kwargs): + basename = os.path.basename(src) + if basename == src: + return src + name, ext = os.path.splitext(src) + hash = hashlib.sha256(name) + return '%s_%s%s' % (os.path.basename(name), hash.hexdigest()[:8], ext) + + class Category(models.Model): name = models.CharField(max_length=64, blank=False, null=False) ctime = models.DateTimeField(auto_now_add=True) @@ -89,8 +101,7 @@ class Broadcast(models.Model): storage = DefaultStorage() for img in html_tree.xpath('//img/@src'): img_path = img.lstrip(storage.base_url) - m.attach(filename=img, data=storage.open(img_path)) - m.attachments[img].is_inline = True + m.attach(filename=transform_image_src(img), data=storage.open(img_path)) for s in subscriptions: if not s.identifier: continue @@ -101,8 +112,12 @@ class Broadcast(models.Model): message = template.render(Context({'unsubscribe_link': unsubscribe_link, 'content': self.announce.text})) m.html = message - m.transformer.load_and_transform() - m.transformer.synchronize_inline_images() + # transform all images sources in order to use image names only + m.transformer.apply_to_images(func=transform_image_src) + # perform transformations in message html, like inline css parsing + m.transformer.load_and_transform(load_images=False) + # mark all attached images as inline + m.transformer.make_all_images_inline() m.transformer.save() handler.body_width = 0 m.text = handler.handle(message) diff --git a/tests/test_emailing.py b/tests/test_emailing.py index 8447e5a..6de7f9d 100644 --- a/tests/test_emailing.py +++ b/tests/test_emailing.py @@ -15,7 +15,7 @@ from django.core.urlresolvers import reverse from django.conf import settings from corbo.models import Category, Announce, Subscription, Broadcast -from corbo.models import channel_choices +from corbo.models import channel_choices, transform_image_src pytestmark = pytest.mark.django_db @@ -82,9 +82,10 @@ def test_check_inline_images(app, categories, announces): storage = DefaultStorage() media_path = os.path.join(os.path.dirname(__file__), 'media') image_name = 'logo.png' - storage.save(image_name, file(os.path.join(media_path, image_name))) + image_name = storage.save(image_name, file(os.path.join(media_path, image_name))) for announce in announces: - announce.text = announce.text + '' % image_name + img_src = "/media/%s" % image_name + announce.text = announce.text + '' % img_src announce.save() uuid = uuid4() s = Subscription.objects.create(category=announce.category, @@ -93,7 +94,9 @@ def test_check_inline_images(app, categories, announces): broadcast.send() assert broadcast.result assert mail.outbox - assert storage.url(image_name) in mail.outbox[0].attachments.keys() + transformed_image_src = transform_image_src(img_src) + assert transformed_image_src in mail.outbox[0].attachments.keys() + assert 'cid:%s' % transformed_image_src in mail.outbox[0].html_body mail.outbox = [] storage.delete(image_name) -- 2.9.3