notifications: Handle an edge case in relative_to_full_url.

For messages where the entire rendered body is a message_inline_image
object, we actually don't display any text and just display the
image. These messages may have links to images which might or might
not be internal to Zulip but in both cases there is a chance of this
links being broken when accessed by an email server like Gmail that
doesn't possess the recipient user's cookies.

We don't want to have ugly looking broken images displayed in email
notifications.  So we patch this by inserting a replacement for the
`message_inline_image` block in which we essentially replace the
content with the textual link.

Edited for clarity by tabbott.
This commit is contained in:
Aditya Bansal 2018-01-24 23:53:51 +05:30 committed by Tim Abbott
parent 6f128279e8
commit ecbb763e79
2 changed files with 24 additions and 0 deletions

View File

@ -90,6 +90,18 @@ def relative_to_full_url(base_url: Text, content: Text) -> Text:
for container in inline_image_containers: for container in inline_image_containers:
container.drop_tree() container.drop_tree()
# The previous block handles most inline images, but for messages
# where the entire markdown input was just the URL of an image
# (i.e. the entire body is a message_inline_image object), the
# entire message body will be that image element; here, we need a
# more drastic edit to the content.
if fragment.get('class') == 'message_inline_image':
content_template = '<p><a href="%s" target="_blank" title="%s">%s</a></p>'
image_link = fragment.find('a').get('href')
image_title = fragment.find('a').get('title')
new_content = (content_template % (image_link, image_title, image_link))
fragment = lxml.html.fromstring(new_content)
fragment.make_links_absolute(base_url) fragment.make_links_absolute(base_url)
content = lxml.html.tostring(fragment).decode("utf-8") content = lxml.html.tostring(fragment).decode("utf-8")

View File

@ -448,6 +448,18 @@ class TestMissedMessages(ZulipTestCase):
'title="avatar_103.jpeg">avatar_103.jpeg</a>.</p></div>' 'title="avatar_103.jpeg">avatar_103.jpeg</a>.</p></div>'
self.assertEqual(actual_output, expected_output) self.assertEqual(actual_output, expected_output)
# A message containing only an inline image URL preview, we do
# somewhat more extensive surgery.
test_data = '<div class="message_inline_image"><a href="https://www.google.com/images/srpr/logo4w.png" ' + \
'target="_blank" title="https://www.google.com/images/srpr/logo4w.png">' + \
'<img data-original="/thumbnail/https%3A//www.google.com/images/srpr/logo4w.png?size=0x0" ' + \
'src="/thumbnail/https%3A//www.google.com/images/srpr/logo4w.png?size=0x100"></a></div>'
actual_output = relative_to_full_url("http://example.com", test_data)
expected_output = '<p><a href="https://www.google.com/images/srpr/logo4w.png" ' + \
'target="_blank" title="https://www.google.com/images/srpr/logo4w.png">' + \
'https://www.google.com/images/srpr/logo4w.png</a></p>'
self.assertEqual(actual_output, expected_output)
def test_fix_emoji(self) -> None: def test_fix_emoji(self) -> None:
# An emoji. # An emoji.
test_data = '<p>See <span class="emoji emoji-26c8" title="cloud with lightning and rain">' + \ test_data = '<p>See <span class="emoji emoji-26c8" title="cloud with lightning and rain">' + \