diff --git a/zerver/actions/message_send.py b/zerver/actions/message_send.py index c18147361d..60b1452132 100644 --- a/zerver/actions/message_send.py +++ b/zerver/actions/message_send.py @@ -47,7 +47,7 @@ from zerver.lib.exceptions import ( TopicWildcardMentionNotAllowedError, ZephyrMessageAlreadySentError, ) -from zerver.lib.markdown import MessageRenderingResult +from zerver.lib.markdown import MessageRenderingResult, render_message_markdown from zerver.lib.markdown import version as markdown_version from zerver.lib.mention import MentionBackend, MentionData from zerver.lib.message import ( @@ -55,7 +55,6 @@ from zerver.lib.message import ( SendMessageRequest, check_user_group_mention_allowed, normalize_body, - render_markdown, set_visibility_policy_possible, stream_wildcard_mention_allowed, topic_wildcard_mention_allowed, @@ -160,7 +159,7 @@ def render_incoming_message( ) -> MessageRenderingResult: realm_alert_words_automaton = get_alert_word_automaton(realm) try: - rendering_result = render_markdown( + rendering_result = render_message_markdown( message=message, content=content, realm=realm, @@ -732,7 +731,7 @@ def create_user_messages( topic_participant_user_ids: Set[int], ) -> List[UserMessageLite]: # These properties on the Message are set via - # render_markdown by code in the Markdown inline patterns + # render_message_markdown by code in the Markdown inline patterns ids_with_alert_words = rendering_result.user_ids_with_alert_words is_stream_message = message.is_stream_message() diff --git a/zerver/actions/scheduled_messages.py b/zerver/actions/scheduled_messages.py index c7be7b679b..4acd49090a 100644 --- a/zerver/actions/scheduled_messages.py +++ b/zerver/actions/scheduled_messages.py @@ -17,7 +17,8 @@ from zerver.actions.uploads import check_attachment_reference_change, do_claim_a from zerver.lib.addressee import Addressee from zerver.lib.display_recipient import get_recipient_ids from zerver.lib.exceptions import JsonableError, RealmDeactivatedError, UserDeactivatedError -from zerver.lib.message import SendMessageRequest, render_markdown, truncate_topic +from zerver.lib.markdown import render_message_markdown +from zerver.lib.message import SendMessageRequest, truncate_topic from zerver.lib.recipient_parsing import extract_direct_message_recipient_ids, extract_stream_id from zerver.lib.scheduled_messages import access_scheduled_message from zerver.lib.string_validation import check_stream_topic @@ -77,7 +78,7 @@ def do_schedule_messages( scheduled_message.recipient = send_request.message.recipient topic_name = send_request.message.topic_name() scheduled_message.set_topic_name(topic_name=topic_name) - rendering_result = render_markdown( + rendering_result = render_message_markdown( send_request.message, send_request.message.content, send_request.realm ) scheduled_message.content = send_request.message.content @@ -216,7 +217,7 @@ def edit_scheduled_message( if message_content is not None: # User has updated the scheduled messages's content. - rendering_result = render_markdown( + rendering_result = render_message_markdown( send_request.message, send_request.message.content, send_request.realm ) scheduled_message_object.content = send_request.message.content diff --git a/zerver/lib/markdown/__init__.py b/zerver/lib/markdown/__init__.py index d369417a26..2c4fe1346b 100644 --- a/zerver/lib/markdown/__init__.py +++ b/zerver/lib/markdown/__init__.py @@ -2744,3 +2744,38 @@ def markdown_convert( ) markdown_stats_finish() return ret + + +def render_message_markdown( + message: Message, + content: str, + realm: Optional[Realm] = None, + realm_alert_words_automaton: Optional[ahocorasick.Automaton] = None, + url_embed_data: Optional[Dict[str, Optional[UrlEmbedData]]] = None, + mention_data: Optional[MentionData] = None, + email_gateway: bool = False, +) -> MessageRenderingResult: + """ + This is basically just a wrapper for do_render_markdown. + """ + + if realm is None: + realm = message.get_realm() + + sender = message.sender + sent_by_bot = sender.is_bot + translate_emoticons = sender.translate_emoticons + + rendering_result = markdown_convert( + content, + realm_alert_words_automaton=realm_alert_words_automaton, + message=message, + message_realm=realm, + sent_by_bot=sent_by_bot, + translate_emoticons=translate_emoticons, + url_embed_data=url_embed_data, + mention_data=mention_data, + email_gateway=email_gateway, + ) + + return rendering_result diff --git a/zerver/lib/message.py b/zerver/lib/message.py index f41319a98e..dae7da7eba 100644 --- a/zerver/lib/message.py +++ b/zerver/lib/message.py @@ -17,7 +17,6 @@ from typing import ( Union, ) -import ahocorasick import orjson from django.conf import settings from django.db import connection @@ -39,7 +38,7 @@ from zerver.lib.cache import ( ) from zerver.lib.display_recipient import bulk_fetch_display_recipients, get_display_recipient_by_id from zerver.lib.exceptions import JsonableError, MissingAuthenticationError -from zerver.lib.markdown import MessageRenderingResult, markdown_convert, topic_links +from zerver.lib.markdown import MessageRenderingResult, render_message_markdown, topic_links from zerver.lib.markdown import version as markdown_version from zerver.lib.mention import MentionData from zerver.lib.query_helpers import query_for_ids @@ -59,7 +58,6 @@ from zerver.lib.topic import ( messages_for_topic, ) from zerver.lib.types import DisplayRecipientT, EditHistoryEvent, UserDisplayRecipient -from zerver.lib.url_preview.types import UrlEmbedData from zerver.lib.user_groups import is_user_in_group from zerver.lib.user_topics import build_get_topic_visibility_policy, get_topic_visibility_policy from zerver.lib.users import get_inaccessible_user_ids @@ -344,7 +342,7 @@ def message_to_dict_json(message: Message, realm_id: Optional[int] = None) -> by def save_message_rendered_content(message: Message, content: str) -> str: - rendering_result = render_markdown(message, content, realm=message.get_realm()) + rendering_result = render_message_markdown(message, content, realm=message.get_realm()) rendered_content = None if rendering_result is not None: rendered_content = rendering_result.rendered_content @@ -1046,41 +1044,6 @@ def get_messages_with_usermessage_rows_for_user( ).values_list("message_id", flat=True) -def render_markdown( - message: Message, - content: str, - realm: Optional[Realm] = None, - realm_alert_words_automaton: Optional[ahocorasick.Automaton] = None, - url_embed_data: Optional[Dict[str, Optional[UrlEmbedData]]] = None, - mention_data: Optional[MentionData] = None, - email_gateway: bool = False, -) -> MessageRenderingResult: - """ - This is basically just a wrapper for do_render_markdown. - """ - - if realm is None: - realm = message.get_realm() - - sender = message.sender - sent_by_bot = sender.is_bot - translate_emoticons = sender.translate_emoticons - - rendering_result = markdown_convert( - content, - realm_alert_words_automaton=realm_alert_words_automaton, - message=message, - message_realm=realm, - sent_by_bot=sent_by_bot, - translate_emoticons=translate_emoticons, - url_embed_data=url_embed_data, - mention_data=mention_data, - email_gateway=email_gateway, - ) - - return rendering_result - - def huddle_users(recipient_id: int) -> str: display_recipient: List[UserDisplayRecipient] = get_display_recipient_by_id( recipient_id, diff --git a/zerver/tests/test_events.py b/zerver/tests/test_events.py index b67c921ea5..dcc0c7bf8b 100644 --- a/zerver/tests/test_events.py +++ b/zerver/tests/test_events.py @@ -206,8 +206,8 @@ from zerver.lib.events import ( fetch_initial_state_data, post_process_state, ) +from zerver.lib.markdown import render_message_markdown from zerver.lib.mention import MentionBackend, MentionData -from zerver.lib.message import render_markdown from zerver.lib.muted_users import get_mute_object from zerver.lib.test_classes import ZulipTestCase from zerver.lib.test_helpers import ( @@ -530,7 +530,7 @@ class NormalActionsTest(BaseAction): # Verify direct message editing - content only edit pm = Message.objects.order_by("-id")[0] content = "new content" - rendering_result = render_markdown(pm, content) + rendering_result = render_message_markdown(pm, content) prior_mention_user_ids: Set[int] = set() mention_backend = MentionBackend(self.user_profile.realm_id) mention_data = MentionData( @@ -838,7 +838,7 @@ class NormalActionsTest(BaseAction): # Verify stream message editing - content only message = Message.objects.order_by("-id")[0] content = "new content" - rendering_result = render_markdown(message, content) + rendering_result = render_message_markdown(message, content) prior_mention_user_ids: Set[int] = set() mention_backend = MentionBackend(self.user_profile.realm_id) mention_data = MentionData( @@ -905,7 +905,7 @@ class NormalActionsTest(BaseAction): # Verify special case of embedded content update content = "embed_content" - rendering_result = render_markdown(message, content) + rendering_result = render_message_markdown(message, content) events = self.verify_action( lambda: do_update_embedded_data(self.user_profile, message, content, rendering_result), state_change_expected=False, diff --git a/zerver/tests/test_markdown.py b/zerver/tests/test_markdown.py index 56d9c8a9a6..11b7c40af5 100644 --- a/zerver/tests/test_markdown.py +++ b/zerver/tests/test_markdown.py @@ -39,6 +39,7 @@ from zerver.lib.markdown import ( markdown_convert, maybe_update_markdown_engines, possible_linked_stream_names, + render_message_markdown, topic_links, url_embed_preview_enabled, url_to_a, @@ -56,7 +57,6 @@ from zerver.lib.mention import ( stream_wildcards, topic_wildcards, ) -from zerver.lib.message import render_markdown from zerver.lib.per_request_cache import flush_per_request_caches from zerver.lib.test_classes import ZulipTestCase from zerver.lib.tex import render_tex @@ -472,7 +472,7 @@ class MarkdownTest(ZulipTestCase): sending_client=get_client("test"), realm=user_profile.realm, ) - rendering_result = render_markdown(msg, test["input"]) + rendering_result = render_message_markdown(msg, test["input"]) converted = rendering_result.rendered_content else: converted = markdown_convert_wrapper(test["input"]) @@ -640,7 +640,7 @@ class MarkdownTest(ZulipTestCase): sending_client=get_client("test"), realm=sender_user_profile.realm, ) - converted = render_markdown(msg, content) + converted = render_message_markdown(msg, content) self.assertEqual(converted.rendered_content, with_preview) realm = msg.get_realm() @@ -653,7 +653,7 @@ class MarkdownTest(ZulipTestCase): sending_client=get_client("test"), realm=sender_user_profile.realm, ) - converted = render_markdown(msg, content) + converted = render_message_markdown(msg, content) self.assertEqual(converted.rendered_content, without_preview) @override_settings(EXTERNAL_URI_SCHEME="https://") @@ -729,7 +729,7 @@ class MarkdownTest(ZulipTestCase): sending_client=get_client("test"), realm=sender_user_profile.realm, ) - converted = render_markdown(msg, content) + converted = render_message_markdown(msg, content) self.assertEqual(converted.rendered_content, expected) content = ">http://cdn.wallpapersafari.com/13/6/16eVjx.jpeg\n\nAwesome!" @@ -740,7 +740,7 @@ class MarkdownTest(ZulipTestCase): sending_client=get_client("test"), realm=sender_user_profile.realm, ) - converted = render_markdown(msg, content) + converted = render_message_markdown(msg, content) self.assertEqual(converted.rendered_content, expected) content = ">* http://cdn.wallpapersafari.com/13/6/16eVjx.jpeg\n\nAwesome!" @@ -751,7 +751,7 @@ class MarkdownTest(ZulipTestCase): sending_client=get_client("test"), realm=sender_user_profile.realm, ) - converted = render_markdown(msg, content) + converted = render_message_markdown(msg, content) self.assertEqual(converted.rendered_content, expected) @override_settings(THUMBNAIL_IMAGES=True, INLINE_IMAGE_PREVIEW=True) @@ -766,7 +766,7 @@ class MarkdownTest(ZulipTestCase): sending_client=get_client("test"), realm=sender_user_profile.realm, ) - converted = render_markdown(msg, content) + converted = render_message_markdown(msg, content) self.assertEqual(converted.rendered_content, expected) content = "http://imaging.nikon.com/lineup/dslr/df/img/sample/img_01.jpg\n\n>http://imaging.nikon.com/lineup/dslr/df/img/sample/img_02.jpg\n\n* http://imaging.nikon.com/lineup/dslr/df/img/sample/img_03.jpg\n* https://www.google.com/images/srpr/logo4w.png" @@ -778,7 +778,7 @@ class MarkdownTest(ZulipTestCase): sending_client=get_client("test"), realm=sender_user_profile.realm, ) - converted = render_markdown(msg, content) + converted = render_message_markdown(msg, content) self.assertEqual(converted.rendered_content, expected) content = "Test 1\n[21136101110_1dde1c1a7e_o.jpg](/user_uploads/{realm_id}/6d/F1PX6u16JA2P-nK45PyxHIYZ/21136101110_1dde1c1a7e_o.jpg) \n\nNext image\n[IMG_20161116_023910.jpg](/user_uploads/{realm_id}/69/sh7L06e7uH7NaX6d5WFfVYQp/IMG_20161116_023910.jpg) \n\nAnother screenshot\n[Screenshot-from-2016-06-01-16-22-42.png](/user_uploads/{realm_id}/70/_aZmIEWaN1iUaxwkDjkO7bpj/Screenshot-from-2016-06-01-16-22-42.png)" @@ -791,7 +791,7 @@ class MarkdownTest(ZulipTestCase): sending_client=get_client("test"), realm=sender_user_profile.realm, ) - converted = render_markdown(msg, content) + converted = render_message_markdown(msg, content) self.assertEqual(converted.rendered_content, expected) @override_settings(THUMBNAIL_IMAGES=True, INLINE_IMAGE_PREVIEW=True) @@ -806,12 +806,12 @@ class MarkdownTest(ZulipTestCase): sending_client=get_client("test"), realm=sender_user_profile.realm, ) - converted = render_markdown(msg, content) + converted = render_message_markdown(msg, content) self.assertEqual(converted.rendered_content, expected) content = "https://en.wikipedia.org/static/images/icons/wikipedia.png" expected = '
' - converted = render_markdown(msg, content) + converted = render_message_markdown(msg, content) self.assertEqual(converted.rendered_content, expected) @override_settings(INLINE_IMAGE_PREVIEW=False) @@ -1100,7 +1100,7 @@ class MarkdownTest(ZulipTestCase): content = ":)" expected = ":)
" - converted = render_markdown(msg, content) + converted = render_message_markdown(msg, content) self.assertEqual(converted.rendered_content, expected) def test_same_markup(self) -> None: @@ -1600,7 +1600,7 @@ class MarkdownTest(ZulipTestCase): ) content = "/me makes a list\n* one\n* two" - rendering_result = render_markdown(msg, content) + rendering_result = render_message_markdown(msg, content) self.assertEqual( rendering_result.rendered_content, "/me makes a list
\n/me takes a walk
", @@ -1616,7 +1616,7 @@ class MarkdownTest(ZulipTestCase): self.assertTrue(Message.is_status_message(content, rendering_result.rendered_content)) content = "/me writes a second line\nline" - rendering_result = render_markdown(msg, content) + rendering_result = render_message_markdown(msg, content) self.assertEqual( rendering_result.rendered_content, "/me writes a second line
\nline
@{topic_wildcard} test
', @@ -1984,7 +1984,7 @@ class MarkdownTest(ZulipTestCase): for stream_wildcard in stream_wildcards: content = f"@**{stream_wildcard}** test" - rendering_result = render_markdown(msg, content) + rendering_result = render_message_markdown(msg, content) self.assertEqual( rendering_result.rendered_content, f'@{stream_wildcard} test
', @@ -2000,7 +2000,7 @@ class MarkdownTest(ZulipTestCase): for topic_wildcard in topic_wildcards: content = f"@{topic_wildcard} test" - rendering_result = render_markdown(msg, content) + rendering_result = render_message_markdown(msg, content) self.assertEqual(rendering_result.rendered_content, f"@{topic_wildcard} test
") self.assertFalse(rendering_result.mentions_topic_wildcard) self.assertFalse(rendering_result.mentions_stream_wildcard) @@ -2014,7 +2014,7 @@ class MarkdownTest(ZulipTestCase): for stream_wildcard in stream_wildcards: content = f"@{stream_wildcard} test" - rendering_result = render_markdown(msg, content) + rendering_result = render_message_markdown(msg, content) self.assertEqual(rendering_result.rendered_content, f"@{stream_wildcard} test
") self.assertFalse(rendering_result.mentions_topic_wildcard) self.assertFalse(rendering_result.mentions_stream_wildcard) @@ -2027,7 +2027,7 @@ class MarkdownTest(ZulipTestCase): ) content = "test @alleycat.com test" - rendering_result = render_markdown(msg, content) + rendering_result = render_message_markdown(msg, content) self.assertEqual(rendering_result.rendered_content, "test @alleycat.com test
") self.assertFalse(rendering_result.mentions_stream_wildcard) self.assertEqual(rendering_result.mentions_user_ids, set()) @@ -2039,7 +2039,7 @@ class MarkdownTest(ZulipTestCase): ) content = "@aaron test" - rendering_result = render_markdown(msg, content) + rendering_result = render_message_markdown(msg, content) self.assertEqual(rendering_result.rendered_content, "@aaron test
") self.assertFalse(rendering_result.mentions_stream_wildcard) self.assertEqual(rendering_result.mentions_user_ids, set()) @@ -2053,7 +2053,7 @@ class MarkdownTest(ZulipTestCase): user_id = user_profile.id content = "@**King Hamlet**" - rendering_result = render_markdown(msg, content) + rendering_result = render_message_markdown(msg, content) self.assertEqual( rendering_result.rendered_content, f'@King Hamlet
', @@ -2061,7 +2061,7 @@ class MarkdownTest(ZulipTestCase): self.assertEqual(rendering_result.mentions_user_ids, {user_profile.id}) content = f"@**|{user_id}**" - rendering_result = render_markdown(msg, content) + rendering_result = render_message_markdown(msg, content) self.assertEqual( rendering_result.rendered_content, f'@King Hamlet
', @@ -2081,7 +2081,7 @@ class MarkdownTest(ZulipTestCase): valid_characters_before_mention = ["(", "{", "[", "/", "<"] for character in valid_characters_before_mention: content = f"{character}@**King Hamlet**" - rendering_result = render_markdown(msg, content) + rendering_result = render_message_markdown(msg, content) self.assertEqual( rendering_result.rendered_content, f'{escape(character)}@Othello, the Moor of Venice @_Othello, the Moor of Venice {wildcard}
', @@ -2222,7 +2222,7 @@ class MarkdownTest(ZulipTestCase): for wildcard in topic_wildcards: content = f"@_**{wildcard}**" - rendering_result = render_markdown(msg, content) + rendering_result = render_message_markdown(msg, content) self.assertEqual( rendering_result.rendered_content, f'{wildcard}
', @@ -2240,7 +2240,7 @@ class MarkdownTest(ZulipTestCase): user_id = user_profile.id content = "@**Invalid user** and @**King Hamlet**" - rendering_result = render_markdown(msg, content) + rendering_result = render_message_markdown(msg, content) self.assertEqual( rendering_result.rendered_content, '@Invalid user and '
@@ -2283,7 +2283,7 @@ class MarkdownTest(ZulipTestCase):
user_id = user_profile.id
content = "@_**Invalid user** and @_**King Hamlet**"
- rendering_result = render_markdown(msg, content)
+ rendering_result = render_message_markdown(msg, content)
self.assertEqual(
rendering_result.rendered_content,
' @_Invalid user and @_|123456789 and "
@@ -2346,7 +2346,7 @@ class MarkdownTest(ZulipTestCase):
content = "@**King Hamlet** and @**Cordelia, Lear's daughter**, check this out"
- rendering_result = render_markdown(msg, content)
+ rendering_result = render_message_markdown(msg, content)
self.assertEqual(
rendering_result.rendered_content,
" "
@@ -2365,7 +2365,7 @@ class MarkdownTest(ZulipTestCase):
msg = Message(sender=othello, sending_client=get_client("test"), realm=othello.realm)
content = "> @**King Hamlet** and @**Othello, the Moor of Venice**\n\n @**King Hamlet** and @**Cordelia, Lear's daughter**"
- rendering_result = render_markdown(msg, content)
+ rendering_result = render_message_markdown(msg, content)
self.assertEqual(
rendering_result.rendered_content,
" "
@@ -2388,19 +2388,19 @@ class MarkdownTest(ZulipTestCase):
"\n
"
)
content = "```quote\n@**King Hamlet**\n```"
- rendering_result = render_markdown(msg, content)
+ rendering_result = render_message_markdown(msg, content)
self.assertEqual(rendering_result.rendered_content, expected)
self.assertEqual(rendering_result.mentions_user_ids, set())
content = "> @**King Hamlet**"
- rendering_result = render_markdown(msg, content)
+ rendering_result = render_message_markdown(msg, content)
self.assertEqual(rendering_result.rendered_content, expected)
self.assertEqual(rendering_result.mentions_user_ids, set())
content = "```quote\n@_**King Hamlet**\n```"
- rendering_result = render_markdown(msg, content)
+ rendering_result = render_message_markdown(msg, content)
self.assertEqual(rendering_result.rendered_content, expected)
self.assertEqual(rendering_result.mentions_user_ids, set())
content = "> @_**King Hamlet**"
- rendering_result = render_markdown(msg, content)
+ rendering_result = render_message_markdown(msg, content)
self.assertEqual(rendering_result.rendered_content, expected)
self.assertEqual(rendering_result.mentions_user_ids, set())
@@ -2416,7 +2416,7 @@ class MarkdownTest(ZulipTestCase):
f'{wildcard}'
"
" @@ -2492,7 +2492,7 @@ class MarkdownTest(ZulipTestCase): ) content = "Hey @**Nonexistent User**" - rendering_result = render_markdown(msg, content) + rendering_result = render_message_markdown(msg, content) self.assertEqual( rendering_result.rendered_content, "
Hey @Nonexistent User
" ) @@ -2520,7 +2520,7 @@ class MarkdownTest(ZulipTestCase): full_name="Atomic #123", ) content = "@**Atomic #123**" - rendering_result = render_markdown(msg, content) + rendering_result = render_message_markdown(msg, content) self.assertEqual( rendering_result.rendered_content, '"
@@ -2719,7 +2719,7 @@ class MarkdownTest(ZulipTestCase):
)
content = "Hey @*Nonexistent group*"
- rendering_result = render_markdown(msg, content)
+ rendering_result = render_message_markdown(msg, content)
self.assertEqual(
rendering_result.rendered_content, " Hey @Nonexistent group We'll add you to "
@@ -2758,7 +2758,7 @@ class MarkdownTest(ZulipTestCase):
f'backend'
" #Invalid and #{d.name} Look to "
'#{s.name} #casesens #casesens