message: Add function to remove single newline in triple quoted string.

For multiline strings in triple quotes, a '\n' is included
at the end of each line.

Earlier, to skip '\n' we used to add an escape character '\'
at the end of each line.

This commit adds a function to avoid manually adding '\'.
This commit is contained in:
Prakhar Pratyush 2024-03-23 08:59:56 +05:30 committed by Tim Abbott
parent bd4a095fc3
commit a7dc7c0734
4 changed files with 63 additions and 25 deletions

View File

@ -1,3 +1,4 @@
import re
from dataclasses import dataclass, field from dataclasses import dataclass, field
from datetime import datetime, timedelta from datetime import datetime, timedelta
from typing import ( from typing import (
@ -1439,3 +1440,8 @@ def set_visibility_policy_possible(user_profile: UserProfile, message: Message)
return False return False
return True return True
def remove_single_newlines(content: str) -> str:
content = content.strip("\n")
return re.sub(r"(?<!\n)\n(?!\n)", " ", content)

View File

@ -14,7 +14,7 @@ from zerver.actions.message_send import (
) )
from zerver.actions.reactions import do_add_reaction from zerver.actions.reactions import do_add_reaction
from zerver.lib.emoji import get_emoji_data from zerver.lib.emoji import get_emoji_data
from zerver.lib.message import SendMessageRequest from zerver.lib.message import SendMessageRequest, remove_single_newlines
from zerver.models import Message, Realm, UserProfile from zerver.models import Message, Realm, UserProfile
from zerver.models.users import get_system_bot from zerver.models.users import get_system_bot
@ -314,19 +314,21 @@ def send_initial_realm_messages(realm: Realm) -> None:
start_topic_help_url="/help/starting-a-new-topic", start_topic_help_url="/help/starting-a-new-topic",
) )
content_of_zulip_update_announcements_topic_name = ( content_of_zulip_update_announcements_topic_name = remove_single_newlines(
_(""" (
Welcome! To help you learn about new features and configuration options, \ _("""
Welcome! To help you learn about new features and configuration options,
this topic will receive messages about important changes in Zulip. this topic will receive messages about important changes in Zulip.
You can read these update messages whenever it's convenient, or \ You can read these update messages whenever it's convenient, or
[mute]({mute_topic_help_url}) this topic if you are not interested. \ [mute]({mute_topic_help_url}) this topic if you are not interested.
If your organization does not want to receive these announcements, \ If your organization does not want to receive these announcements,
they can be disabled. [Learn more]({zulip_update_announcements_help_url}). they can be disabled. [Learn more]({zulip_update_announcements_help_url}).
""") """)
).format( ).format(
zulip_update_announcements_help_url="/help/configure-automated-notices#zulip-update-announcements", zulip_update_announcements_help_url="/help/configure-automated-notices#zulip-update-announcements",
mute_topic_help_url="/help/mute-a-topic", mute_topic_help_url="/help/mute-a-topic",
)
) )
welcome_messages: List[Dict[str, str]] = [ welcome_messages: List[Dict[str, str]] = [

View File

@ -13,7 +13,7 @@ from zerver.actions.message_send import (
internal_prep_huddle_message, internal_prep_huddle_message,
internal_prep_stream_message, internal_prep_stream_message,
) )
from zerver.lib.message import SendMessageRequest from zerver.lib.message import SendMessageRequest, remove_single_newlines
from zerver.models.realm_audit_logs import RealmAuditLog from zerver.models.realm_audit_logs import RealmAuditLog
from zerver.models.realms import Realm from zerver.models.realms import Realm
from zerver.models.users import UserProfile, get_system_bot from zerver.models.users import UserProfile, get_system_bot
@ -30,12 +30,12 @@ class ZulipUpdateAnnouncement:
zulip_update_announcements: List[ZulipUpdateAnnouncement] = [ zulip_update_announcements: List[ZulipUpdateAnnouncement] = [
ZulipUpdateAnnouncement( ZulipUpdateAnnouncement(
level=1, level=1,
message="""\ message="""
Zulip is introducing **Zulip updates**! To help you learn about new features and \ Zulip is introducing **Zulip updates**! To help you learn about new features and
configuration options, this topic will receive messages about important changes in Zulip. configuration options, this topic will receive messages about important changes in Zulip.
You can read these update messages whenever it's convenient, or [mute]({mute_topic_help_url}) \ You can read these update messages whenever it's convenient, or [mute]({mute_topic_help_url})
this topic if you are not interested. If your organization does not want to receive these \ this topic if you are not interested. If your organization does not want to receive these
announcements, they can be disabled. [Learn more]({zulip_update_announcements_help_url}). announcements, they can be disabled. [Learn more]({zulip_update_announcements_help_url}).
""".format( """.format(
zulip_update_announcements_help_url="/help/configure-automated-notices#zulip-update-announcements", zulip_update_announcements_help_url="/help/configure-automated-notices#zulip-update-announcements",
@ -52,7 +52,7 @@ def get_latest_zulip_update_announcements_level() -> int:
def get_zulip_update_announcements_message_for_level(level: int) -> str: def get_zulip_update_announcements_message_for_level(level: int) -> str:
zulip_update_announcement = zulip_update_announcements[level - 1] zulip_update_announcement = zulip_update_announcements[level - 1]
return zulip_update_announcement.message return remove_single_newlines(zulip_update_announcement.message)
def get_realms_behind_zulip_update_announcements_level(level: int) -> QuerySet[Realm]: def get_realms_behind_zulip_update_announcements_level(level: int) -> QuerySet[Realm]:
@ -73,22 +73,22 @@ def internal_prep_group_direct_message_for_old_realm(
with override_language(realm.default_language): with override_language(realm.default_language):
topic_name = str(realm.ZULIP_UPDATE_ANNOUNCEMENTS_TOPIC_NAME) topic_name = str(realm.ZULIP_UPDATE_ANNOUNCEMENTS_TOPIC_NAME)
if realm.zulip_update_announcements_stream is None: if realm.zulip_update_announcements_stream is None:
content = """\ content = """
Zulip now supports [configuring]({organization_settings_url}) a stream where Zulip will \ Zulip now supports [configuring]({organization_settings_url}) a stream where Zulip will
send [updates]({zulip_update_announcements_help_url}) about new Zulip features. \ send [updates]({zulip_update_announcements_help_url}) about new Zulip features.
These notifications are currently turned off in your organization. If you configure \ These notifications are currently turned off in your organization. If you configure
a stream within one week, your organization will not miss any update messages. a stream within one week, your organization will not miss any update messages.
""".format( """.format(
zulip_update_announcements_help_url="/help/configure-automated-notices#zulip-update-announcements", zulip_update_announcements_help_url="/help/configure-automated-notices#zulip-update-announcements",
organization_settings_url="/#organization/organization-settings", organization_settings_url="/#organization/organization-settings",
) )
else: else:
content = """\ content = """
Starting tomorrow, users in your organization will receive [updates]({zulip_update_announcements_help_url}) \ Starting tomorrow, users in your organization will receive [updates]({zulip_update_announcements_help_url})
about new Zulip features in #**{zulip_update_announcements_stream}>{topic_name}**. about new Zulip features in #**{zulip_update_announcements_stream}>{topic_name}**.
If you like, you can [configure]({organization_settings_url}) a different stream for \ If you like, you can [configure]({organization_settings_url}) a different stream for
these updates (and [move]({move_content_another_stream_help_url}) any updates sent before the \ these updates (and [move]({move_content_another_stream_help_url}) any updates sent before the
configuration change), or [turn this feature off]({organization_settings_url}) altogether. configuration change), or [turn this feature off]({organization_settings_url}) altogether.
""".format( """.format(
zulip_update_announcements_help_url="/help/configure-automated-notices#zulip-update-announcements", zulip_update_announcements_help_url="/help/configure-automated-notices#zulip-update-announcements",
@ -97,7 +97,9 @@ configuration change), or [turn this feature off]({organization_settings_url}) a
organization_settings_url="/#organization/organization-settings", organization_settings_url="/#organization/organization-settings",
move_content_another_stream_help_url="/help/move-content-to-another-stream", move_content_another_stream_help_url="/help/move-content-to-another-stream",
) )
return internal_prep_huddle_message(realm, sender, content, recipient_users=administrators) return internal_prep_huddle_message(
realm, sender, remove_single_newlines(content), recipient_users=administrators
)
def is_group_direct_message_sent_to_admins_atleast_one_week_ago(realm: Realm) -> bool: def is_group_direct_message_sent_to_admins_atleast_one_week_ago(realm: Realm) -> bool:

View File

@ -5,6 +5,7 @@ import time_machine
from django.conf import settings from django.conf import settings
from django.utils.timezone import now as timezone_now from django.utils.timezone import now as timezone_now
from zerver.lib.message import remove_single_newlines
from zerver.lib.test_classes import ZulipTestCase from zerver.lib.test_classes import ZulipTestCase
from zerver.lib.zulip_update_announcements import ( from zerver.lib.zulip_update_announcements import (
ZulipUpdateAnnouncement, ZulipUpdateAnnouncement,
@ -152,3 +153,30 @@ class ZulipUpdateAnnouncementsTest(ZulipTestCase):
f"#**{realm.zulip_update_announcements_stream}>{realm.ZULIP_UPDATE_ANNOUNCEMENTS_TOPIC_NAME}**", f"#**{realm.zulip_update_announcements_stream}>{realm.ZULIP_UPDATE_ANNOUNCEMENTS_TOPIC_NAME}**",
group_direct_message.content, group_direct_message.content,
) )
def test_remove_single_newlines(self) -> None:
# single newlines and double newlines
input_text = "This is a sentence.\nThis is another sentence.\n\nThis is a third sentence."
expected_output = (
"This is a sentence. This is another sentence.\n\nThis is a third sentence."
)
self.assertEqual(remove_single_newlines(input_text), expected_output)
# single newline at the beginning
input_text = "\nThis is a sentence.\nThis is another sentence.\n\nThis is a third sentence."
expected_output = (
"This is a sentence. This is another sentence.\n\nThis is a third sentence."
)
self.assertEqual(remove_single_newlines(input_text), expected_output)
# single newline at the end
input_text = "This is a sentence.\nThis is another sentence.\n\nThis is a third sentence.\n"
expected_output = (
"This is a sentence. This is another sentence.\n\nThis is a third sentence."
)
self.assertEqual(remove_single_newlines(input_text), expected_output)
# only single newlines in the middle
input_text = "This is a sentence.\nThis is another sentence.\nThis is a third sentence.\nThis is a fourth sentence."
expected_output = "This is a sentence. This is another sentence. This is a third sentence. This is a fourth sentence."
self.assertEqual(remove_single_newlines(input_text), expected_output)