diff --git a/zerver/lib/bugdown/__init__.py b/zerver/lib/bugdown/__init__.py index 444e5c8edb..95301765d8 100644 --- a/zerver/lib/bugdown/__init__.py +++ b/zerver/lib/bugdown/__init__.py @@ -35,7 +35,7 @@ from zerver.lib.camo import get_camo_url from zerver.lib.emoji import translate_emoticons, emoticon_regex from zerver.lib.mention import possible_mentions, \ possible_user_group_mentions, extract_user_group -from zerver.lib.notifications import encode_stream +from zerver.lib.url_encoding import encode_stream from zerver.lib.thumbnail import is_thumbor_enabled from zerver.lib.timeout import timeout, TimeoutExpired from zerver.lib.cache import cache_with_key, NotFoundInCache diff --git a/zerver/lib/digest.py b/zerver/lib/digest.py index 5c65782da3..ea9f32678e 100644 --- a/zerver/lib/digest.py +++ b/zerver/lib/digest.py @@ -10,9 +10,9 @@ from django.template import loader from django.conf import settings from django.utils.timezone import now as timezone_now -from zerver.lib.notifications import build_message_list, encode_stream, \ - one_click_unsubscribe_link +from zerver.lib.notifications import build_message_list, one_click_unsubscribe_link from zerver.lib.send_email import send_future_email, FromAddress +from zerver.lib.url_encoding import encode_stream from zerver.models import UserProfile, UserMessage, Recipient, Stream, \ Subscription, UserActivity, get_active_streams, get_user_profile_by_id, \ Realm diff --git a/zerver/lib/notifications.py b/zerver/lib/notifications.py index 7cfb6a84c3..69c1e4c5ed 100644 --- a/zerver/lib/notifications.py +++ b/zerver/lib/notifications.py @@ -9,6 +9,7 @@ from django.utils.translation import ugettext as _ from zerver.decorator import statsd_increment from zerver.lib.send_email import send_future_email, FromAddress from zerver.lib.queue import queue_json_publish +from zerver.lib.url_encoding import pm_narrow_url, stream_narrow_url, topic_narrow_url from zerver.models import ( Recipient, ScheduledEmail, @@ -31,7 +32,6 @@ import lxml.html import re import subprocess import ujson -import urllib from collections import defaultdict import pytz @@ -44,33 +44,6 @@ def one_click_unsubscribe_link(user_profile: UserProfile, email_type: str) -> st Confirmation.UNSUBSCRIBE, url_args = {'email_type': email_type}) -def hash_util_encode(string: str) -> str: - # Do the same encoding operation as hash_util.encodeHashComponent on the - # frontend. - # `safe` has a default value of "/", but we want those encoded, too. - return urllib.parse.quote( - string.encode("utf-8"), safe=b"").replace(".", "%2E").replace("%", ".") - -def encode_stream(stream_id: int, stream_name: str) -> str: - # We encode streams for urls as something like 99-Verona. - stream_name = stream_name.replace(' ', '-') - return str(stream_id) + '-' + hash_util_encode(stream_name) - -def pm_narrow_url(realm: Realm, participants: List[str]) -> str: - participants.sort() - base_url = "%s/#narrow/pm-with/" % (realm.uri,) - return base_url + hash_util_encode(",".join(participants)) - -def stream_narrow_url(realm: Realm, stream: Stream) -> str: - base_url = "%s/#narrow/stream/" % (realm.uri,) - return base_url + encode_stream(stream.id, stream.name) - -def topic_narrow_url(realm: Realm, stream: Stream, topic: str) -> str: - base_url = "%s/#narrow/stream/" % (realm.uri,) - return "%s%s/topic/%s" % (base_url, - encode_stream(stream.id, stream.name), - hash_util_encode(topic)) - def relative_to_full_url(base_url: str, content: str) -> str: # Convert relative URLs to absolute URLs. fragment = lxml.html.fromstring(content) diff --git a/zerver/lib/outgoing_webhook.py b/zerver/lib/outgoing_webhook.py index 61ceb5cc65..35d4175d50 100644 --- a/zerver/lib/outgoing_webhook.py +++ b/zerver/lib/outgoing_webhook.py @@ -15,8 +15,8 @@ from django.utils.translation import ugettext as _ from zerver.models import Realm, UserProfile, get_user_profile_by_id, get_client, \ GENERIC_INTERFACE, Service, SLACK_INTERFACE, email_to_domain, get_service_profile from zerver.lib.actions import check_send_message -from zerver.lib.notifications import encode_stream from zerver.lib.queue import retry_event +from zerver.lib.url_encoding import encode_stream from zerver.lib.validator import check_dict, check_string from zerver.decorator import JsonableError diff --git a/zerver/lib/url_encoding.py b/zerver/lib/url_encoding.py new file mode 100644 index 0000000000..702c29bc05 --- /dev/null +++ b/zerver/lib/url_encoding.py @@ -0,0 +1,31 @@ +import urllib +from typing import List + +from zerver.models import Realm, Stream + +def hash_util_encode(string: str) -> str: + # Do the same encoding operation as hash_util.encodeHashComponent on the + # frontend. + # `safe` has a default value of "/", but we want those encoded, too. + return urllib.parse.quote( + string.encode("utf-8"), safe=b"").replace(".", "%2E").replace("%", ".") + +def encode_stream(stream_id: int, stream_name: str) -> str: + # We encode streams for urls as something like 99-Verona. + stream_name = stream_name.replace(' ', '-') + return str(stream_id) + '-' + hash_util_encode(stream_name) + +def pm_narrow_url(realm: Realm, participants: List[str]) -> str: + participants.sort() + base_url = "%s/#narrow/pm-with/" % (realm.uri,) + return base_url + hash_util_encode(",".join(participants)) + +def stream_narrow_url(realm: Realm, stream: Stream) -> str: + base_url = "%s/#narrow/stream/" % (realm.uri,) + return base_url + encode_stream(stream.id, stream.name) + +def topic_narrow_url(realm: Realm, stream: Stream, topic: str) -> str: + base_url = "%s/#narrow/stream/" % (realm.uri,) + return "%s%s/topic/%s" % (base_url, + encode_stream(stream.id, stream.name), + hash_util_encode(topic))