models: Move some functions to zerver.lib.display_recipient.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
Anders Kaseorg
2023-12-14 18:04:08 -08:00
committed by Alex Vandiver
parent f77648f279
commit 0c8d6dab65
10 changed files with 73 additions and 65 deletions

View File

@@ -15,19 +15,13 @@ from zerver.actions.message_send import (
) )
from zerver.actions.uploads import check_attachment_reference_change, do_claim_attachments from zerver.actions.uploads import check_attachment_reference_change, do_claim_attachments
from zerver.lib.addressee import Addressee 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.exceptions import JsonableError, RealmDeactivatedError, UserDeactivatedError
from zerver.lib.message import SendMessageRequest, render_markdown, truncate_topic from zerver.lib.message import SendMessageRequest, render_markdown, truncate_topic
from zerver.lib.recipient_parsing import extract_direct_message_recipient_ids, extract_stream_id 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.scheduled_messages import access_scheduled_message
from zerver.lib.string_validation import check_stream_topic from zerver.lib.string_validation import check_stream_topic
from zerver.models import ( from zerver.models import Client, Realm, ScheduledMessage, Subscription, UserProfile
Client,
Realm,
ScheduledMessage,
Subscription,
UserProfile,
get_recipient_ids,
)
from zerver.models.users import get_system_bot from zerver.models.users import get_system_bot
from zerver.tornado.django_api import send_event from zerver.tornado.django_api import send_event

View File

@@ -1,4 +1,4 @@
from typing import Dict, List, Optional, Set, Tuple, TypedDict from typing import TYPE_CHECKING, Dict, List, Optional, Set, Tuple, TypedDict
from django_stubs_ext import ValuesQuerySet from django_stubs_ext import ValuesQuerySet
@@ -9,8 +9,11 @@ from zerver.lib.cache import (
generic_bulk_cached_fetch, generic_bulk_cached_fetch,
single_user_display_recipient_cache_key, single_user_display_recipient_cache_key,
) )
from zerver.lib.per_request_cache import return_same_value_during_entire_request
from zerver.lib.types import DisplayRecipientT, UserDisplayRecipient from zerver.lib.types import DisplayRecipientT, UserDisplayRecipient
from zerver.models import Recipient, Stream, UserProfile, bulk_get_huddle_user_ids
if TYPE_CHECKING:
from zerver.models import Recipient
display_recipient_fields = [ display_recipient_fields = [
"id", "id",
@@ -44,6 +47,8 @@ def get_display_recipient_remote_cache(
Do not use this for streams. Do not use this for streams.
""" """
from zerver.models import Recipient, UserProfile
assert recipient_type != Recipient.STREAM assert recipient_type != Recipient.STREAM
# The main priority for ordering here is being deterministic. # The main priority for ordering here is being deterministic.
@@ -64,6 +69,8 @@ def user_dict_id_fetcher(user_dict: UserDisplayRecipient) -> int:
def bulk_fetch_single_user_display_recipients(uids: List[int]) -> Dict[int, UserDisplayRecipient]: def bulk_fetch_single_user_display_recipients(uids: List[int]) -> Dict[int, UserDisplayRecipient]:
from zerver.models import UserProfile
return bulk_cached_fetch( return bulk_cached_fetch(
# Use a separate cache key to protect us from conflicts with # Use a separate cache key to protect us from conflicts with
# the get_user_profile_by_id cache. # the get_user_profile_by_id cache.
@@ -85,6 +92,8 @@ def bulk_fetch_stream_names(
Returns dict mapping recipient_id to corresponding display_recipient Returns dict mapping recipient_id to corresponding display_recipient
""" """
from zerver.models import Stream
if len(recipient_tuples) == 0: if len(recipient_tuples) == 0:
return {} return {}
@@ -125,6 +134,8 @@ def bulk_fetch_user_display_recipients(
Returns dict mapping recipient_id to corresponding display_recipient Returns dict mapping recipient_id to corresponding display_recipient
""" """
from zerver.models import Recipient, bulk_get_huddle_user_ids
if len(recipient_tuples) == 0: if len(recipient_tuples) == 0:
return {} return {}
@@ -172,6 +183,8 @@ def bulk_fetch_display_recipients(
Returns dict mapping recipient_id to corresponding display_recipient Returns dict mapping recipient_id to corresponding display_recipient
""" """
from zerver.models import Recipient
stream_recipients = { stream_recipients = {
recipient for recipient in recipient_tuples if recipient[1] == Recipient.STREAM recipient for recipient in recipient_tuples if recipient[1] == Recipient.STREAM
} }
@@ -184,3 +197,50 @@ def bulk_fetch_display_recipients(
# Glue the dicts together and return: # Glue the dicts together and return:
return {**stream_display_recipients, **personal_and_huddle_display_recipients} return {**stream_display_recipients, **personal_and_huddle_display_recipients}
@return_same_value_during_entire_request
def get_display_recipient_by_id(
recipient_id: int, recipient_type: int, recipient_type_id: Optional[int]
) -> List[UserDisplayRecipient]:
"""
returns: an object describing the recipient (using a cache).
If the type is a stream, the type_id must be an int; a string is returned.
Otherwise, type_id may be None; an array of recipient dicts is returned.
"""
# Have to import here, to avoid circular dependency.
from zerver.lib.display_recipient import get_display_recipient_remote_cache
return get_display_recipient_remote_cache(recipient_id, recipient_type, recipient_type_id)
def get_display_recipient(recipient: "Recipient") -> List[UserDisplayRecipient]:
return get_display_recipient_by_id(
recipient.id,
recipient.type,
recipient.type_id,
)
def get_recipient_ids(
recipient: Optional["Recipient"], user_profile_id: int
) -> Tuple[List[int], str]:
from zerver.models import Recipient
if recipient is None:
recipient_type_str = ""
to = []
elif recipient.type == Recipient.STREAM:
recipient_type_str = "stream"
to = [recipient.type_id]
else:
recipient_type_str = "private"
if recipient.type == Recipient.PERSONAL:
to = [recipient.type_id]
else:
to = []
for r in get_display_recipient(recipient):
assert not isinstance(r, str) # It will only be a string for streams
if r["id"] != user_profile_id:
to.append(r["id"])
return to, recipient_type_str

View File

@@ -14,6 +14,7 @@ from zerver.actions.message_send import (
internal_send_private_message, internal_send_private_message,
internal_send_stream_message, internal_send_stream_message,
) )
from zerver.lib.display_recipient import get_display_recipient
from zerver.lib.email_mirror_helpers import ( from zerver.lib.email_mirror_helpers import (
ZulipEmailForwardError, ZulipEmailForwardError,
ZulipEmailForwardUserError, ZulipEmailForwardUserError,
@@ -36,7 +37,6 @@ from zerver.models import (
Stream, Stream,
UserProfile, UserProfile,
get_client, get_client,
get_display_recipient,
get_stream_by_id_in_realm, get_stream_by_id_in_realm,
) )
from zerver.models.users import get_system_bot, get_user_profile_by_id from zerver.models.users import get_system_bot, get_user_profile_by_id

View File

@@ -21,6 +21,7 @@ from django.utils.translation import override as override_language
from lxml.html import builder as e from lxml.html import builder as e
from confirmation.models import one_click_unsubscribe_link from confirmation.models import one_click_unsubscribe_link
from zerver.lib.display_recipient import get_display_recipient
from zerver.lib.markdown.fenced_code import FENCE_RE from zerver.lib.markdown.fenced_code import FENCE_RE
from zerver.lib.message import bulk_access_messages from zerver.lib.message import bulk_access_messages
from zerver.lib.notification_data import get_mentioned_user_group_name from zerver.lib.notification_data import get_mentioned_user_group_name
@@ -44,7 +45,6 @@ from zerver.models import (
UserMessage, UserMessage,
UserProfile, UserProfile,
get_context_for_message, get_context_for_message,
get_display_recipient,
) )
from zerver.models.users import get_user_profile_by_id from zerver.models.users import get_user_profile_by_id

View File

@@ -37,7 +37,7 @@ from zerver.lib.cache import (
to_dict_cache_key, to_dict_cache_key,
to_dict_cache_key_id, to_dict_cache_key_id,
) )
from zerver.lib.display_recipient import bulk_fetch_display_recipients 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.exceptions import JsonableError, MissingAuthenticationError
from zerver.lib.markdown import MessageRenderingResult, markdown_convert, topic_links from zerver.lib.markdown import MessageRenderingResult, markdown_convert, topic_links
from zerver.lib.markdown import version as markdown_version from zerver.lib.markdown import version as markdown_version
@@ -74,7 +74,6 @@ from zerver.models import (
UserMessage, UserMessage,
UserProfile, UserProfile,
UserTopic, UserTopic,
get_display_recipient_by_id,
get_usermessage_by_message_id, get_usermessage_by_message_id,
query_for_ids, query_for_ids,
) )

View File

@@ -39,6 +39,7 @@ from zerver.actions.realm_settings import (
do_set_realm_property, do_set_realm_property,
) )
from zerver.lib.avatar import absolute_avatar_url, get_avatar_for_inaccessible_user from zerver.lib.avatar import absolute_avatar_url, get_avatar_for_inaccessible_user
from zerver.lib.display_recipient import get_display_recipient
from zerver.lib.emoji_utils import hex_codepoint_to_emoji from zerver.lib.emoji_utils import hex_codepoint_to_emoji
from zerver.lib.exceptions import ErrorCode, JsonableError from zerver.lib.exceptions import ErrorCode, JsonableError
from zerver.lib.message import access_message, huddle_users from zerver.lib.message import access_message, huddle_users
@@ -64,7 +65,6 @@ from zerver.models import (
UserGroup, UserGroup,
UserMessage, UserMessage,
UserProfile, UserProfile,
get_display_recipient,
) )
from zerver.models.realms import get_fake_email_domain from zerver.models.realms import get_fake_email_domain
from zerver.models.users import get_user_profile_by_id from zerver.models.users import get_user_profile_by_id

View File

@@ -43,8 +43,8 @@ from zerver.lib.cache import (
realm_alert_words_automaton_cache_key, realm_alert_words_automaton_cache_key,
realm_alert_words_cache_key, realm_alert_words_cache_key,
) )
from zerver.lib.display_recipient import get_display_recipient, get_recipient_ids
from zerver.lib.exceptions import RateLimitedError from zerver.lib.exceptions import RateLimitedError
from zerver.lib.per_request_cache import return_same_value_during_entire_request
from zerver.lib.timestamp import datetime_to_timestamp from zerver.lib.timestamp import datetime_to_timestamp
from zerver.lib.types import ( from zerver.lib.types import (
DefaultStreamDict, DefaultStreamDict,
@@ -56,7 +56,6 @@ from zerver.lib.types import (
ProfileDataElementValue, ProfileDataElementValue,
RealmUserValidator, RealmUserValidator,
UnspecifiedValue, UnspecifiedValue,
UserDisplayRecipient,
UserFieldElement, UserFieldElement,
Validator, Validator,
) )
@@ -139,51 +138,6 @@ def query_for_ids(
return query return query
@return_same_value_during_entire_request
def get_display_recipient_by_id(
recipient_id: int, recipient_type: int, recipient_type_id: Optional[int]
) -> List[UserDisplayRecipient]:
"""
returns: an object describing the recipient (using a cache).
If the type is a stream, the type_id must be an int; a string is returned.
Otherwise, type_id may be None; an array of recipient dicts is returned.
"""
# Have to import here, to avoid circular dependency.
from zerver.lib.display_recipient import get_display_recipient_remote_cache
return get_display_recipient_remote_cache(recipient_id, recipient_type, recipient_type_id)
def get_display_recipient(recipient: "Recipient") -> List[UserDisplayRecipient]:
return get_display_recipient_by_id(
recipient.id,
recipient.type,
recipient.type_id,
)
def get_recipient_ids(
recipient: Optional["Recipient"], user_profile_id: int
) -> Tuple[List[int], str]:
if recipient is None:
recipient_type_str = ""
to = []
elif recipient.type == Recipient.STREAM:
recipient_type_str = "stream"
to = [recipient.type_id]
else:
recipient_type_str = "private"
if recipient.type == Recipient.PERSONAL:
to = [recipient.type_id]
else:
to = []
for r in get_display_recipient(recipient):
assert not isinstance(r, str) # It will only be a string for streams
if r["id"] != user_profile_id:
to.append(r["id"])
return to, recipient_type_str
class Recipient(models.Model): class Recipient(models.Model):
"""Represents an audience that can potentially receive messages in Zulip. """Represents an audience that can potentially receive messages in Zulip.

View File

@@ -4,8 +4,9 @@ import orjson
from typing_extensions import override from typing_extensions import override
from zerver.lib.bot_lib import EmbeddedBotQuitError from zerver.lib.bot_lib import EmbeddedBotQuitError
from zerver.lib.display_recipient import get_display_recipient
from zerver.lib.test_classes import ZulipTestCase from zerver.lib.test_classes import ZulipTestCase
from zerver.models import UserProfile, get_display_recipient, get_service_profile from zerver.models import UserProfile, get_service_profile
from zerver.models.realms import get_realm from zerver.models.realms import get_realm
from zerver.models.users import get_user from zerver.models.users import get_user

View File

@@ -4,6 +4,7 @@ from unittest import mock
from django.utils.timezone import now as timezone_now from django.utils.timezone import now as timezone_now
from zerver.lib.cache import cache_delete, to_dict_cache_key_id from zerver.lib.cache import cache_delete, to_dict_cache_key_id
from zerver.lib.display_recipient import get_display_recipient
from zerver.lib.markdown import version as markdown_version from zerver.lib.markdown import version as markdown_version
from zerver.lib.message import MessageDict, messages_for_ids, sew_messages_and_reactions from zerver.lib.message import MessageDict, messages_for_ids, sew_messages_and_reactions
from zerver.lib.per_request_cache import flush_per_request_caches from zerver.lib.per_request_cache import flush_per_request_caches
@@ -19,7 +20,6 @@ from zerver.models import (
Recipient, Recipient,
Stream, Stream,
UserProfile, UserProfile,
get_display_recipient,
get_stream, get_stream,
) )
from zerver.models.realms import get_realm from zerver.models.realms import get_realm

View File

@@ -18,6 +18,7 @@ from zerver.actions.uploads import do_claim_attachments
from zerver.actions.user_settings import do_change_user_setting from zerver.actions.user_settings import do_change_user_setting
from zerver.actions.users import do_deactivate_user from zerver.actions.users import do_deactivate_user
from zerver.lib.avatar import avatar_url from zerver.lib.avatar import avatar_url
from zerver.lib.display_recipient import get_display_recipient
from zerver.lib.exceptions import JsonableError from zerver.lib.exceptions import JsonableError
from zerver.lib.mention import MentionBackend, MentionData from zerver.lib.mention import MentionBackend, MentionData
from zerver.lib.message import ( from zerver.lib.message import (
@@ -57,7 +58,6 @@ from zerver.models import (
UserMessage, UserMessage,
UserProfile, UserProfile,
UserTopic, UserTopic,
get_display_recipient,
get_stream, get_stream,
) )
from zerver.models.realms import get_realm from zerver.models.realms import get_realm