emails: Extract get_narrow_url into a function.

Reorganized a bit by tabbott to avoid doing a bunch of database
queries twice.
This commit is contained in:
Vishnu Ks
2019-06-04 12:45:42 +00:00
committed by Tim Abbott
parent 443439d388
commit 66ee5b870a
2 changed files with 47 additions and 19 deletions

View File

@@ -1,5 +1,5 @@
from typing import Any, Dict, Iterable, List, Tuple
from typing import Any, Dict, Iterable, List, Optional, Tuple, Union
from confirmation.models import one_click_unsubscribe_link
from django.conf import settings
@@ -164,33 +164,25 @@ def build_message_list(user_profile: UserProfile, messages: List[Message]) -> Li
def message_header(user_profile: UserProfile, message: Message) -> Dict[str, Any]:
if message.recipient.type == Recipient.PERSONAL:
narrow_link = get_narrow_url(user_profile, message)
header = "You and %s" % (message.sender.full_name,)
html_link = personal_narrow_url(
realm=user_profile.realm,
sender=message.sender,
)
header_html = "<a style='color: #ffffff;' href='%s'>%s</a>" % (html_link, header)
header_html = "<a style='color: #ffffff;' href='%s'>%s</a>" % (narrow_link, header)
elif message.recipient.type == Recipient.HUDDLE:
disp_recipient = get_display_recipient(message.recipient)
assert not isinstance(disp_recipient, str)
other_recipients = [r['full_name'] for r in disp_recipient
display_recipient = get_display_recipient(message.recipient)
assert not isinstance(display_recipient, str)
narrow_link = get_narrow_url(user_profile, message,
display_recipient=display_recipient)
other_recipients = [r['full_name'] for r in display_recipient
if r['id'] != user_profile.id]
header = "You and %s" % (", ".join(other_recipients),)
other_user_ids = [r['id'] for r in disp_recipient
if r['id'] != user_profile.id]
html_link = huddle_narrow_url(
realm=user_profile.realm,
other_user_ids=other_user_ids,
)
header_html = "<a style='color: #ffffff;' href='%s'>%s</a>" % (html_link, header)
header_html = "<a style='color: #ffffff;' href='%s'>%s</a>" % (narrow_link, header)
else:
stream = Stream.objects.only('id', 'name').get(id=message.recipient.type_id)
narrow_link = get_narrow_url(user_profile, message, stream=stream)
header = "%s > %s" % (stream.name, message.topic_name())
stream_link = stream_narrow_url(user_profile.realm, stream)
topic_link = topic_narrow_url(user_profile.realm, stream, message.topic_name())
header_html = "<a href='%s'>%s</a> > <a href='%s'>%s</a>" % (
stream_link, stream.name, topic_link, message.topic_name())
stream_link, stream.name, narrow_link, message.topic_name())
return {"plain": header,
"html": header_html,
"stream_message": message.recipient.type_name() == "stream"}
@@ -245,6 +237,39 @@ def build_message_list(user_profile: UserProfile, messages: List[Message]) -> Li
return messages_to_render
def get_narrow_url(user_profile: UserProfile, message: Message,
display_recipient: Optional[Union[str, List[Dict[str, Any]]]]=None,
stream: Optional[Stream]=None) -> str:
"""The display_recipient and stream arguments are optional. If not
provided, we'll compute them from the message; they exist as a
performance optimization for cases where the caller needs those
data too.
"""
if message.recipient.type == Recipient.PERSONAL:
assert stream is None
assert display_recipient is None
return personal_narrow_url(
realm=user_profile.realm,
sender=message.sender,
)
elif message.recipient.type == Recipient.HUDDLE:
assert stream is None
if display_recipient is None:
display_recipient = get_display_recipient(message.recipient)
assert display_recipient is not None
assert not isinstance(display_recipient, str)
other_user_ids = [r['id'] for r in display_recipient
if r['id'] != user_profile.id]
return huddle_narrow_url(
realm=user_profile.realm,
other_user_ids=other_user_ids,
)
else:
assert display_recipient is None
if stream is None:
stream = Stream.objects.only('id', 'name').get(id=message.recipient.type_id)
return topic_narrow_url(user_profile.realm, stream, message.topic_name())
def message_content_allowed_in_missedmessage_emails(user_profile: UserProfile) -> bool:
return user_profile.realm.message_content_allowed_in_email_notifications and \
user_profile.message_content_in_email_notifications

View File

@@ -106,6 +106,9 @@ class TestDigestEmailMessages(ZulipTestCase):
with queries_captured() as queries:
handle_digest_email(othello.id, cutoff)
# This can definitely be optimized; for both the huddle and
# stream cases, the get_narrow_url API ends up double-fetching
# some data because of how the functions are organized.
self.assert_length(queries, 9)
self.assertEqual(mock_send_future_email.call_count, 1)