refactor: Rename `huddle` to `direct_message_group` in non api files.

This commit completes rename of "huddle" to "direct_message_group"
in all the non API files.

Part of #28640
This commit is contained in:
roanster007 2024-07-08 20:16:01 +05:30 committed by Tim Abbott
parent 4b04e2c09c
commit 7b3e163d55
15 changed files with 210 additions and 175 deletions

View File

@ -175,16 +175,20 @@ class AnalyticsTestCase(ZulipTestCase):
stream.save(update_fields=["recipient"]) stream.save(update_fields=["recipient"])
return stream, recipient return stream, recipient
def create_huddle_with_recipient(self, **kwargs: Any) -> tuple[DirectMessageGroup, Recipient]: def create_direct_message_group_with_recipient(
self, **kwargs: Any
) -> tuple[DirectMessageGroup, Recipient]:
self.name_counter += 1 self.name_counter += 1
defaults = {"huddle_hash": f"hash{self.name_counter}"} defaults = {"huddle_hash": f"hash{self.name_counter}"}
for key, value in defaults.items(): for key, value in defaults.items():
kwargs[key] = kwargs.get(key, value) kwargs[key] = kwargs.get(key, value)
huddle = DirectMessageGroup.objects.create(**kwargs) direct_message_group = DirectMessageGroup.objects.create(**kwargs)
recipient = Recipient.objects.create(type_id=huddle.id, type=Recipient.DIRECT_MESSAGE_GROUP) recipient = Recipient.objects.create(
huddle.recipient = recipient type_id=direct_message_group.id, type=Recipient.DIRECT_MESSAGE_GROUP
huddle.save(update_fields=["recipient"]) )
return huddle, recipient direct_message_group.recipient = recipient
direct_message_group.save(update_fields=["recipient"])
return direct_message_group, recipient
def create_message(self, sender: UserProfile, recipient: Recipient, **kwargs: Any) -> Message: def create_message(self, sender: UserProfile, recipient: Recipient, **kwargs: Any) -> Message:
defaults = { defaults = {
@ -547,8 +551,8 @@ class TestCountStats(AnalyticsTestCase):
self.create_user(realm=self.no_message_realm) self.create_user(realm=self.no_message_realm)
self.create_stream_with_recipient(realm=self.no_message_realm) self.create_stream_with_recipient(realm=self.no_message_realm)
# This huddle should not show up anywhere # This direct_message_group should not show up anywhere
self.create_huddle_with_recipient() self.create_direct_message_group_with_recipient()
def test_upload_quota_used_bytes(self) -> None: def test_upload_quota_used_bytes(self) -> None:
stat = COUNT_STATS["upload_quota_used_bytes::day"] stat = COUNT_STATS["upload_quota_used_bytes::day"]
@ -595,11 +599,11 @@ class TestCountStats(AnalyticsTestCase):
recipient_human1 = Recipient.objects.get(type_id=human1.id, type=Recipient.PERSONAL) recipient_human1 = Recipient.objects.get(type_id=human1.id, type=Recipient.PERSONAL)
recipient_stream = self.create_stream_with_recipient()[1] recipient_stream = self.create_stream_with_recipient()[1]
recipient_huddle = self.create_huddle_with_recipient()[1] recipient_direct_message_group = self.create_direct_message_group_with_recipient()[1]
self.create_message(bot, recipient_human1) self.create_message(bot, recipient_human1)
self.create_message(bot, recipient_stream) self.create_message(bot, recipient_stream)
self.create_message(bot, recipient_huddle) self.create_message(bot, recipient_direct_message_group)
self.create_message(human1, recipient_human1) self.create_message(human1, recipient_human1)
self.create_message(human2, recipient_human1) self.create_message(human2, recipient_human1)
@ -636,19 +640,19 @@ class TestCountStats(AnalyticsTestCase):
recipient_human1 = Recipient.objects.get(type_id=human1.id, type=Recipient.PERSONAL) recipient_human1 = Recipient.objects.get(type_id=human1.id, type=Recipient.PERSONAL)
recipient_stream = self.create_stream_with_recipient()[1] recipient_stream = self.create_stream_with_recipient()[1]
recipient_huddle = self.create_huddle_with_recipient()[1] recipient_direct_message_group = self.create_direct_message_group_with_recipient()[1]
# To be included # To be included
self.create_message(bot, recipient_human1) self.create_message(bot, recipient_human1)
self.create_message(bot, recipient_stream) self.create_message(bot, recipient_stream)
self.create_message(bot, recipient_huddle) self.create_message(bot, recipient_direct_message_group)
self.create_message(human1, recipient_human1) self.create_message(human1, recipient_human1)
self.create_message(human2, recipient_human1) self.create_message(human2, recipient_human1)
# To be excluded # To be excluded
self.create_message(self.hourly_user, recipient_human1) self.create_message(self.hourly_user, recipient_human1)
self.create_message(self.hourly_user, recipient_stream) self.create_message(self.hourly_user, recipient_stream)
self.create_message(self.hourly_user, recipient_huddle) self.create_message(self.hourly_user, recipient_direct_message_group)
do_fill_count_stat_at_hour(stat, self.TIME_ZERO, self.default_realm) do_fill_count_stat_at_hour(stat, self.TIME_ZERO, self.default_realm)
@ -692,11 +696,11 @@ class TestCountStats(AnalyticsTestCase):
self.create_message(user1, recipient_stream4) self.create_message(user1, recipient_stream4)
self.create_message(user2, recipient_stream3) self.create_message(user2, recipient_stream3)
# huddles # direct message groups
recipient_huddle1 = self.create_huddle_with_recipient()[1] recipient_direct_message_group1 = self.create_direct_message_group_with_recipient()[1]
recipient_huddle2 = self.create_huddle_with_recipient()[1] recipient_direct_message_group2 = self.create_direct_message_group_with_recipient()[1]
self.create_message(user1, recipient_huddle1) self.create_message(user1, recipient_direct_message_group1)
self.create_message(user2, recipient_huddle2) self.create_message(user2, recipient_direct_message_group2)
# direct messages # direct messages
recipient_user1 = Recipient.objects.get(type_id=user1.id, type=Recipient.PERSONAL) recipient_user1 = Recipient.objects.get(type_id=user1.id, type=Recipient.PERSONAL)
@ -759,13 +763,13 @@ class TestCountStats(AnalyticsTestCase):
user_recipient = Recipient.objects.get(type_id=user.id, type=Recipient.PERSONAL) user_recipient = Recipient.objects.get(type_id=user.id, type=Recipient.PERSONAL)
private_stream_recipient = self.create_stream_with_recipient(invite_only=True)[1] private_stream_recipient = self.create_stream_with_recipient(invite_only=True)[1]
stream_recipient = self.create_stream_with_recipient()[1] stream_recipient = self.create_stream_with_recipient()[1]
huddle_recipient = self.create_huddle_with_recipient()[1] direct_message_group_recipient = self.create_direct_message_group_with_recipient()[1]
# To be included # To be included
self.create_message(user, user_recipient) self.create_message(user, user_recipient)
self.create_message(user, private_stream_recipient) self.create_message(user, private_stream_recipient)
self.create_message(user, stream_recipient) self.create_message(user, stream_recipient)
self.create_message(user, huddle_recipient) self.create_message(user, direct_message_group_recipient)
do_fill_count_stat_at_hour(stat, self.TIME_ZERO, self.default_realm) do_fill_count_stat_at_hour(stat, self.TIME_ZERO, self.default_realm)
@ -773,7 +777,7 @@ class TestCountStats(AnalyticsTestCase):
self.create_message(self.hourly_user, user_recipient) self.create_message(self.hourly_user, user_recipient)
self.create_message(self.hourly_user, private_stream_recipient) self.create_message(self.hourly_user, private_stream_recipient)
self.create_message(self.hourly_user, stream_recipient) self.create_message(self.hourly_user, stream_recipient)
self.create_message(self.hourly_user, huddle_recipient) self.create_message(self.hourly_user, direct_message_group_recipient)
self.assertTableState( self.assertTableState(
UserCount, UserCount,
@ -806,11 +810,11 @@ class TestCountStats(AnalyticsTestCase):
user = self.create_user(id=1000) user = self.create_user(id=1000)
user_recipient = Recipient.objects.get(type_id=user.id, type=Recipient.PERSONAL) user_recipient = Recipient.objects.get(type_id=user.id, type=Recipient.PERSONAL)
stream_recipient = self.create_stream_with_recipient(id=1000)[1] stream_recipient = self.create_stream_with_recipient(id=1000)[1]
huddle_recipient = self.create_huddle_with_recipient(id=1000)[1] direct_message_group_recipient = self.create_direct_message_group_with_recipient(id=1000)[1]
self.create_message(user, user_recipient) self.create_message(user, user_recipient)
self.create_message(user, stream_recipient) self.create_message(user, stream_recipient)
self.create_message(user, huddle_recipient) self.create_message(user, direct_message_group_recipient)
do_fill_count_stat_at_hour(stat, self.TIME_ZERO) do_fill_count_stat_at_hour(stat, self.TIME_ZERO)
@ -827,13 +831,13 @@ class TestCountStats(AnalyticsTestCase):
recipient_user2 = Recipient.objects.get(type_id=user2.id, type=Recipient.PERSONAL) recipient_user2 = Recipient.objects.get(type_id=user2.id, type=Recipient.PERSONAL)
recipient_stream = self.create_stream_with_recipient()[1] recipient_stream = self.create_stream_with_recipient()[1]
recipient_huddle = self.create_huddle_with_recipient()[1] recipient_direct_message_group = self.create_direct_message_group_with_recipient()[1]
client2 = Client.objects.create(name="client2") client2 = Client.objects.create(name="client2")
self.create_message(user1, recipient_user2, sending_client=client2) self.create_message(user1, recipient_user2, sending_client=client2)
self.create_message(user1, recipient_stream) self.create_message(user1, recipient_stream)
self.create_message(user1, recipient_huddle) self.create_message(user1, recipient_direct_message_group)
self.create_message(user2, recipient_user2, sending_client=client2) self.create_message(user2, recipient_user2, sending_client=client2)
self.create_message(user2, recipient_user2, sending_client=client2) self.create_message(user2, recipient_user2, sending_client=client2)
@ -923,8 +927,8 @@ class TestCountStats(AnalyticsTestCase):
# To be excluded # To be excluded
self.create_message(human2, recipient_human1) self.create_message(human2, recipient_human1)
self.create_message(bot, recipient_human1) self.create_message(bot, recipient_human1)
recipient_huddle = self.create_huddle_with_recipient()[1] recipient_direct_message_group = self.create_direct_message_group_with_recipient()[1]
self.create_message(human1, recipient_huddle) self.create_message(human1, recipient_direct_message_group)
do_fill_count_stat_at_hour(stat, self.TIME_ZERO) do_fill_count_stat_at_hour(stat, self.TIME_ZERO)

View File

@ -33,7 +33,7 @@ create_zulip_test
# This next line can be simplified to "-n0" once we fix our app (and tests) with 0 messages. # This next line can be simplified to "-n0" once we fix our app (and tests) with 0 messages.
./manage.py populate_db --test-suite -n30 --threads=1 \ ./manage.py populate_db --test-suite -n30 --threads=1 \
--max-topics=3 \ --max-topics=3 \
--huddles=0 --personals=0 --percent-huddles=0 --percent-personals=0 --direct-message-groups=0 --personals=0 --percent-direct-message-groups=0 --percent-personals=0
./manage.py dumpdata \ ./manage.py dumpdata \
zerver.UserProfile zerver.Stream zerver.Recipient \ zerver.UserProfile zerver.Stream zerver.Recipient \

View File

@ -62,7 +62,7 @@ def do_delete_user(user_profile: UserProfile, *, acting_user: UserProfile | None
do_deactivate_user(user_profile, acting_user=acting_user) do_deactivate_user(user_profile, acting_user=acting_user)
subscribed_huddle_recipient_ids = set( to_resubscribe_recipient_ids = set(
Subscription.objects.filter( Subscription.objects.filter(
user_profile=user_profile, recipient__type=Recipient.DIRECT_MESSAGE_GROUP user_profile=user_profile, recipient__type=Recipient.DIRECT_MESSAGE_GROUP
).values_list("recipient_id", flat=True) ).values_list("recipient_id", flat=True)
@ -97,7 +97,7 @@ def do_delete_user(user_profile: UserProfile, *, acting_user: UserProfile | None
recipient=recipient, recipient=recipient,
is_user_active=replacement_user.is_active, is_user_active=replacement_user.is_active,
) )
for recipient in Recipient.objects.filter(id__in=subscribed_huddle_recipient_ids) for recipient in Recipient.objects.filter(id__in=to_resubscribe_recipient_ids)
] ]
Subscription.objects.bulk_create(subs_to_recreate) Subscription.objects.bulk_create(subs_to_recreate)
@ -271,8 +271,8 @@ def send_events_for_user_deactivation(user_profile: UserProfile) -> None:
# This code path is parallel to # This code path is parallel to
# get_subscribers_of_target_user_subscriptions, but can't reuse it # get_subscribers_of_target_user_subscriptions, but can't reuse it
# because we need to process stream and huddle subscriptions # because we need to process stream and direct_message_group
# separately. # subscriptions separately.
deactivated_user_subs = Subscription.objects.filter( deactivated_user_subs = Subscription.objects.filter(
user_profile=user_profile, user_profile=user_profile,
recipient__type__in=[Recipient.STREAM, Recipient.DIRECT_MESSAGE_GROUP], recipient__type__in=[Recipient.STREAM, Recipient.DIRECT_MESSAGE_GROUP],
@ -285,18 +285,18 @@ def send_events_for_user_deactivation(user_profile: UserProfile) -> None:
active=True, active=True,
).values_list("recipient__type", "user_profile_id") ).values_list("recipient__type", "user_profile_id")
subscribers_in_deactivated_user_streams = set() peer_stream_subscribers = set()
subscribers_in_deactivated_user_huddles = set() peer_direct_message_group_subscribers = set()
for recipient_type, user_id in subscribers_in_deactivated_user_subs: for recipient_type, user_id in subscribers_in_deactivated_user_subs:
if recipient_type == Recipient.DIRECT_MESSAGE_GROUP: if recipient_type == Recipient.DIRECT_MESSAGE_GROUP:
subscribers_in_deactivated_user_huddles.add(user_id) peer_direct_message_group_subscribers.add(user_id)
else: else:
subscribers_in_deactivated_user_streams.add(user_id) peer_stream_subscribers.add(user_id)
users_with_access_to_deactivated_user = ( users_with_access_to_deactivated_user = (
set(non_guest_user_ids) set(non_guest_user_ids)
| users_involved_in_dms_dict[user_profile.id] | users_involved_in_dms_dict[user_profile.id]
| subscribers_in_deactivated_user_huddles | peer_direct_message_group_subscribers
) )
if users_with_access_to_deactivated_user: if users_with_access_to_deactivated_user:
send_event_on_commit( send_event_on_commit(
@ -304,7 +304,7 @@ def send_events_for_user_deactivation(user_profile: UserProfile) -> None:
) )
users_losing_access_to_deactivated_user = ( users_losing_access_to_deactivated_user = (
subscribers_in_deactivated_user_streams - users_with_access_to_deactivated_user peer_stream_subscribers - users_with_access_to_deactivated_user
) )
if users_losing_access_to_deactivated_user: if users_losing_access_to_deactivated_user:
event_remove_user = dict( event_remove_user = dict(

View File

@ -235,7 +235,7 @@ def convert_direct_message_group_data(
direct_message_group_data: list[ZerverFieldsT], direct_message_group_data: list[ZerverFieldsT],
user_data_map: dict[str, dict[str, Any]], user_data_map: dict[str, dict[str, Any]],
subscriber_handler: SubscriberHandler, subscriber_handler: SubscriberHandler,
huddle_id_mapper: IdMapper[frozenset[str]], direct_message_group_id_mapper: IdMapper[frozenset[str]],
user_id_mapper: IdMapper[str], user_id_mapper: IdMapper[str],
realm_id: int, realm_id: int,
team_name: str, team_name: str,
@ -244,7 +244,9 @@ def convert_direct_message_group_data(
for direct_message_group in direct_message_group_data: for direct_message_group in direct_message_group_data:
if len(direct_message_group["members"]) > 2: if len(direct_message_group["members"]) > 2:
direct_message_group_members = frozenset(direct_message_group["members"]) direct_message_group_members = frozenset(direct_message_group["members"])
direct_message_group_id = huddle_id_mapper.get(direct_message_group_members) direct_message_group_id = direct_message_group_id_mapper.get(
direct_message_group_members
)
direct_message_group_dict = build_direct_message_group(direct_message_group_id) direct_message_group_dict = build_direct_message_group(direct_message_group_id)
direct_message_group_user_ids = { direct_message_group_user_ids = {
user_id_mapper.get(username) for username in direct_message_group["members"] user_id_mapper.get(username) for username in direct_message_group["members"]
@ -653,7 +655,7 @@ def write_message_data(
output_dir: str, output_dir: str,
masking_content: bool, masking_content: bool,
stream_id_mapper: IdMapper[str], stream_id_mapper: IdMapper[str],
huddle_id_mapper: IdMapper[frozenset[str]], direct_message_group_id_mapper: IdMapper[frozenset[str]],
user_id_mapper: IdMapper[str], user_id_mapper: IdMapper[str],
user_handler: UserHandler, user_handler: UserHandler,
zerver_realmemoji: list[dict[str, Any]], zerver_realmemoji: list[dict[str, Any]],
@ -663,14 +665,14 @@ def write_message_data(
mattermost_data_dir: str, mattermost_data_dir: str,
) -> None: ) -> None:
stream_id_to_recipient_id = {} stream_id_to_recipient_id = {}
huddle_id_to_recipient_id = {} direct_message_group_id_to_recipient_id = {}
user_id_to_recipient_id = {} user_id_to_recipient_id = {}
for d in zerver_recipient: for d in zerver_recipient:
if d["type"] == Recipient.STREAM: if d["type"] == Recipient.STREAM:
stream_id_to_recipient_id[d["type_id"]] = d["id"] stream_id_to_recipient_id[d["type_id"]] = d["id"]
elif d["type"] == Recipient.DIRECT_MESSAGE_GROUP: elif d["type"] == Recipient.DIRECT_MESSAGE_GROUP:
huddle_id_to_recipient_id[d["type_id"]] = d["id"] direct_message_group_id_to_recipient_id[d["type_id"]] = d["id"]
if d["type"] == Recipient.PERSONAL: if d["type"] == Recipient.PERSONAL:
user_id_to_recipient_id[d["type_id"]] = d["id"] user_id_to_recipient_id[d["type_id"]] = d["id"]
@ -681,8 +683,8 @@ def write_message_data(
def get_recipient_id_from_direct_message_group_members( def get_recipient_id_from_direct_message_group_members(
direct_message_group_members: frozenset[str], direct_message_group_members: frozenset[str],
) -> int: ) -> int:
receiver_id = huddle_id_mapper.get(direct_message_group_members) receiver_id = direct_message_group_id_mapper.get(direct_message_group_members)
return huddle_id_to_recipient_id[receiver_id] return direct_message_group_id_to_recipient_id[receiver_id]
def get_recipient_id_from_username(username: str) -> int: def get_recipient_id_from_username(username: str) -> int:
receiver_id = user_id_mapper.get(username) receiver_id = user_id_mapper.get(username)
@ -892,7 +894,7 @@ def do_convert_data(mattermost_data_dir: str, output_dir: str, masking_content:
subscriber_handler = SubscriberHandler() subscriber_handler = SubscriberHandler()
user_id_mapper = IdMapper[str]() user_id_mapper = IdMapper[str]()
stream_id_mapper = IdMapper[str]() stream_id_mapper = IdMapper[str]()
huddle_id_mapper = IdMapper[frozenset[str]]() direct_message_group_id_mapper = IdMapper[frozenset[str]]()
print("Generating data for", team_name) print("Generating data for", team_name)
realm = make_realm(realm_id, team) realm = make_realm(realm_id, team)
@ -928,7 +930,7 @@ def do_convert_data(mattermost_data_dir: str, output_dir: str, masking_content:
direct_message_group_data=mattermost_data["direct_channel"], direct_message_group_data=mattermost_data["direct_channel"],
user_data_map=username_to_user, user_data_map=username_to_user,
subscriber_handler=subscriber_handler, subscriber_handler=subscriber_handler,
huddle_id_mapper=huddle_id_mapper, direct_message_group_id_mapper=direct_message_group_id_mapper,
user_id_mapper=user_id_mapper, user_id_mapper=user_id_mapper,
realm_id=realm_id, realm_id=realm_id,
team_name=team_name, team_name=team_name,
@ -993,7 +995,7 @@ def do_convert_data(mattermost_data_dir: str, output_dir: str, masking_content:
output_dir=realm_output_dir, output_dir=realm_output_dir,
masking_content=masking_content, masking_content=masking_content,
stream_id_mapper=stream_id_mapper, stream_id_mapper=stream_id_mapper,
huddle_id_mapper=huddle_id_mapper, direct_message_group_id_mapper=direct_message_group_id_mapper,
user_id_mapper=user_id_mapper, user_id_mapper=user_id_mapper,
user_handler=user_handler, user_handler=user_handler,
zerver_realmemoji=zerver_realmemoji, zerver_realmemoji=zerver_realmemoji,

View File

@ -238,19 +238,21 @@ def convert_stream_subscription_data(
def convert_direct_message_group_data( def convert_direct_message_group_data(
huddle_id_to_huddle_map: dict[str, dict[str, Any]], direct_message_group_id_to_direct_message_group_map: dict[str, dict[str, Any]],
huddle_id_mapper: IdMapper[str], direct_message_group_id_mapper: IdMapper[str],
user_id_mapper: IdMapper[str], user_id_mapper: IdMapper[str],
subscriber_handler: SubscriberHandler, subscriber_handler: SubscriberHandler,
) -> list[ZerverFieldsT]: ) -> list[ZerverFieldsT]:
zerver_direct_message_group: list[ZerverFieldsT] = [] zerver_direct_message_group: list[ZerverFieldsT] = []
for rc_huddle_id in huddle_id_to_huddle_map: for rc_direct_message_group_id in direct_message_group_id_to_direct_message_group_map:
direct_message_group_id = huddle_id_mapper.get(rc_huddle_id) direct_message_group_id = direct_message_group_id_mapper.get(rc_direct_message_group_id)
direct_message_group = build_direct_message_group(direct_message_group_id) direct_message_group = build_direct_message_group(direct_message_group_id)
zerver_direct_message_group.append(direct_message_group) zerver_direct_message_group.append(direct_message_group)
direct_message_group_dict = huddle_id_to_huddle_map[rc_huddle_id] direct_message_group_dict = direct_message_group_id_to_direct_message_group_map[
rc_direct_message_group_id
]
direct_message_group_user_ids = { direct_message_group_user_ids = {
user_id_mapper.get(rc_user_id) for rc_user_id in direct_message_group_dict["uids"] user_id_mapper.get(rc_user_id) for rc_user_id in direct_message_group_dict["uids"]
} }
@ -613,13 +615,13 @@ def process_messages(
user_id_to_recipient_id: dict[int, int], user_id_to_recipient_id: dict[int, int],
stream_id_mapper: IdMapper[str], stream_id_mapper: IdMapper[str],
stream_id_to_recipient_id: dict[int, int], stream_id_to_recipient_id: dict[int, int],
huddle_id_mapper: IdMapper[str], direct_message_group_id_mapper: IdMapper[str],
huddle_id_to_recipient_id: dict[int, int], direct_message_group_id_to_recipient_id: dict[int, int],
thread_id_mapper: IdMapper[str], thread_id_mapper: IdMapper[str],
room_id_to_room_map: dict[str, dict[str, Any]], room_id_to_room_map: dict[str, dict[str, Any]],
dsc_id_to_dsc_map: dict[str, dict[str, Any]], dsc_id_to_dsc_map: dict[str, dict[str, Any]],
direct_id_to_direct_map: dict[str, dict[str, Any]], direct_id_to_direct_map: dict[str, dict[str, Any]],
huddle_id_to_huddle_map: dict[str, dict[str, Any]], direct_message_group_id_to_direct_message_group_map: dict[str, dict[str, Any]],
zerver_realmemoji: list[ZerverFieldsT], zerver_realmemoji: list[ZerverFieldsT],
total_reactions: list[ZerverFieldsT], total_reactions: list[ZerverFieldsT],
uploads_list: list[ZerverFieldsT], uploads_list: list[ZerverFieldsT],
@ -677,9 +679,11 @@ def process_messages(
if is_pm_data: if is_pm_data:
# Message is in a 1:1 or group direct message. # Message is in a 1:1 or group direct message.
rc_channel_id = message["rid"] rc_channel_id = message["rid"]
if rc_channel_id in huddle_id_to_huddle_map: if rc_channel_id in direct_message_group_id_to_direct_message_group_map:
direct_message_group_id = huddle_id_mapper.get(rc_channel_id) direct_message_group_id = direct_message_group_id_mapper.get(rc_channel_id)
message_dict["recipient_id"] = huddle_id_to_recipient_id[direct_message_group_id] message_dict["recipient_id"] = direct_message_group_id_to_recipient_id[
direct_message_group_id
]
else: else:
rc_member_ids = direct_id_to_direct_map[rc_channel_id]["uids"] rc_member_ids = direct_id_to_direct_map[rc_channel_id]["uids"]
@ -748,7 +752,7 @@ def process_messages(
parent_channel_id = dsc_channel["prid"] parent_channel_id = dsc_channel["prid"]
if ( if (
parent_channel_id in direct_id_to_direct_map parent_channel_id in direct_id_to_direct_map
or parent_channel_id in huddle_id_to_huddle_map or parent_channel_id in direct_message_group_id_to_direct_message_group_map
): ):
# Discussion belongs to a direct channel and thus, should not be # Discussion belongs to a direct channel and thus, should not be
# linked. # linked.
@ -842,13 +846,16 @@ def separate_channel_private_and_livechat_messages(
messages: list[dict[str, Any]], messages: list[dict[str, Any]],
dsc_id_to_dsc_map: dict[str, dict[str, Any]], dsc_id_to_dsc_map: dict[str, dict[str, Any]],
direct_id_to_direct_map: dict[str, dict[str, Any]], direct_id_to_direct_map: dict[str, dict[str, Any]],
huddle_id_to_huddle_map: dict[str, dict[str, Any]], direct_message_group_id_to_direct_message_group_map: dict[str, dict[str, Any]],
livechat_id_to_livechat_map: dict[str, dict[str, Any]], livechat_id_to_livechat_map: dict[str, dict[str, Any]],
channel_messages: list[dict[str, Any]], channel_messages: list[dict[str, Any]],
private_messages: list[dict[str, Any]], private_messages: list[dict[str, Any]],
livechat_messages: list[dict[str, Any]], livechat_messages: list[dict[str, Any]],
) -> None: ) -> None:
private_channels_list = [*direct_id_to_direct_map, *huddle_id_to_huddle_map] private_channels_list = [
*direct_id_to_direct_map,
*direct_message_group_id_to_direct_message_group_map,
]
for message in messages: for message in messages:
if not message.get("rid"): if not message.get("rid"):
# Message does not belong to any channel (might be # Message does not belong to any channel (might be
@ -872,7 +879,7 @@ def separate_channel_private_and_livechat_messages(
def map_receiver_id_to_recipient_id( def map_receiver_id_to_recipient_id(
zerver_recipient: list[ZerverFieldsT], zerver_recipient: list[ZerverFieldsT],
stream_id_to_recipient_id: dict[int, int], stream_id_to_recipient_id: dict[int, int],
huddle_id_to_recipient_id: dict[int, int], direct_message_group_id_to_recipient_id: dict[int, int],
user_id_to_recipient_id: dict[int, int], user_id_to_recipient_id: dict[int, int],
) -> None: ) -> None:
# receiver_id represents stream_id/direct_message_group_id/user_id # receiver_id represents stream_id/direct_message_group_id/user_id
@ -880,7 +887,7 @@ def map_receiver_id_to_recipient_id(
if recipient["type"] == Recipient.STREAM: if recipient["type"] == Recipient.STREAM:
stream_id_to_recipient_id[recipient["type_id"]] = recipient["id"] stream_id_to_recipient_id[recipient["type_id"]] = recipient["id"]
elif recipient["type"] == Recipient.DIRECT_MESSAGE_GROUP: elif recipient["type"] == Recipient.DIRECT_MESSAGE_GROUP:
huddle_id_to_recipient_id[recipient["type_id"]] = recipient["id"] direct_message_group_id_to_recipient_id[recipient["type_id"]] = recipient["id"]
elif recipient["type"] == Recipient.PERSONAL: elif recipient["type"] == Recipient.PERSONAL:
user_id_to_recipient_id[recipient["type_id"]] = recipient["id"] user_id_to_recipient_id[recipient["type_id"]] = recipient["id"]
@ -891,7 +898,7 @@ def categorize_channels_and_map_with_id(
team_id_to_team_map: dict[str, dict[str, Any]], team_id_to_team_map: dict[str, dict[str, Any]],
dsc_id_to_dsc_map: dict[str, dict[str, Any]], dsc_id_to_dsc_map: dict[str, dict[str, Any]],
direct_id_to_direct_map: dict[str, dict[str, Any]], direct_id_to_direct_map: dict[str, dict[str, Any]],
huddle_id_to_huddle_map: dict[str, dict[str, Any]], direct_message_group_id_to_direct_message_group_map: dict[str, dict[str, Any]],
livechat_id_to_livechat_map: dict[str, dict[str, Any]], livechat_id_to_livechat_map: dict[str, dict[str, Any]],
) -> None: ) -> None:
direct_message_group_hashed_channels: dict[frozenset[str], Any] = {} direct_message_group_hashed_channels: dict[frozenset[str], Any] = {}
@ -901,16 +908,16 @@ def categorize_channels_and_map_with_id(
elif channel["t"] == "d": elif channel["t"] == "d":
if len(channel["uids"]) > 2: if len(channel["uids"]) > 2:
direct_message_group_members = frozenset(channel["uids"]) direct_message_group_members = frozenset(channel["uids"])
logging.info("Huddle channel found. UIDs: %r", channel["uids"]) logging.info("Direct message group channel found. UIDs: %r", channel["uids"])
if channel["msgs"] == 0: # nocoverage if channel["msgs"] == 0: # nocoverage
# Rocket.Chat exports in the wild sometimes # Rocket.Chat exports in the wild sometimes
# contain duplicates of real huddles, with no # contain duplicates of real direct message
# messages in the duplicate. We ignore these # groups, with no messages in the duplicate.
# minor database corruptions in the Rocket.Chat # We ignore these minor database corruptions
# export. Doing so is safe, because a direct # in the Rocket.Chat export. Doing so is safe,
# message group with no message history has no # because a direct message group with no message
# value in Zulip's data model. # history has no value in Zulip's data model.
logging.debug("Skipping direct message group with 0 messages: %s", channel) logging.debug("Skipping direct message group with 0 messages: %s", channel)
elif ( elif (
direct_message_group_members in direct_message_group_hashed_channels direct_message_group_members in direct_message_group_hashed_channels
@ -920,9 +927,9 @@ def categorize_channels_and_map_with_id(
direct_message_group_members, direct_message_group_members,
direct_message_group_hashed_channels[direct_message_group_members], direct_message_group_hashed_channels[direct_message_group_members],
) )
huddle_id_to_huddle_map[channel["_id"]] = direct_message_group_hashed_channels[ direct_message_group_id_to_direct_message_group_map[channel["_id"]] = (
direct_message_group_members direct_message_group_hashed_channels[direct_message_group_members]
] )
# Ideally, we'd merge the duplicate direct message # Ideally, we'd merge the duplicate direct message
# groups. Doing so correctly requires special # groups. Doing so correctly requires special
@ -930,15 +937,15 @@ def categorize_channels_and_map_with_id(
# and on the message import side as well, since # and on the message import side as well, since
# those appear to be mapped via rocketchat channel # those appear to be mapped via rocketchat channel
# IDs and not all of that information is resolved # IDs and not all of that information is resolved
# via the huddle_id_to_huddle_map. # via the direct_message_group_id_to_direct_message_group_map.
# #
# For now, just throw an exception here rather # For now, just throw an exception here rather
# than during the import process. # than during the import process.
raise NotImplementedError( raise NotImplementedError(
"Mapping multiple huddles with messages to one is not fully implemented yet" "Mapping multiple direct message groups with messages to one is not fully implemented yet"
) )
else: else:
huddle_id_to_huddle_map[channel["_id"]] = channel direct_message_group_id_to_direct_message_group_map[channel["_id"]] = channel
direct_message_group_hashed_channels[direct_message_group_members] = channel direct_message_group_hashed_channels[direct_message_group_members] = channel
else: else:
direct_id_to_direct_map[channel["_id"]] = channel direct_id_to_direct_map[channel["_id"]] = channel
@ -1054,7 +1061,7 @@ def do_convert_data(rocketchat_data_dir: str, output_dir: str) -> None:
subscriber_handler = SubscriberHandler() subscriber_handler = SubscriberHandler()
user_id_mapper = IdMapper[str]() user_id_mapper = IdMapper[str]()
stream_id_mapper = IdMapper[str]() stream_id_mapper = IdMapper[str]()
huddle_id_mapper = IdMapper[str]() direct_message_group_id_mapper = IdMapper[str]()
thread_id_mapper = IdMapper[str]() thread_id_mapper = IdMapper[str]()
process_users( process_users(
@ -1069,7 +1076,7 @@ def do_convert_data(rocketchat_data_dir: str, output_dir: str) -> None:
team_id_to_team_map: dict[str, dict[str, Any]] = {} team_id_to_team_map: dict[str, dict[str, Any]] = {}
dsc_id_to_dsc_map: dict[str, dict[str, Any]] = {} dsc_id_to_dsc_map: dict[str, dict[str, Any]] = {}
direct_id_to_direct_map: dict[str, dict[str, Any]] = {} direct_id_to_direct_map: dict[str, dict[str, Any]] = {}
huddle_id_to_huddle_map: dict[str, dict[str, Any]] = {} direct_message_group_id_to_direct_message_group_map: dict[str, dict[str, Any]] = {}
livechat_id_to_livechat_map: dict[str, dict[str, Any]] = {} livechat_id_to_livechat_map: dict[str, dict[str, Any]] = {}
categorize_channels_and_map_with_id( categorize_channels_and_map_with_id(
@ -1078,7 +1085,7 @@ def do_convert_data(rocketchat_data_dir: str, output_dir: str) -> None:
team_id_to_team_map=team_id_to_team_map, team_id_to_team_map=team_id_to_team_map,
dsc_id_to_dsc_map=dsc_id_to_dsc_map, dsc_id_to_dsc_map=dsc_id_to_dsc_map,
direct_id_to_direct_map=direct_id_to_direct_map, direct_id_to_direct_map=direct_id_to_direct_map,
huddle_id_to_huddle_map=huddle_id_to_huddle_map, direct_message_group_id_to_direct_message_group_map=direct_message_group_id_to_direct_message_group_map,
livechat_id_to_livechat_map=livechat_id_to_livechat_map, livechat_id_to_livechat_map=livechat_id_to_livechat_map,
) )
@ -1101,8 +1108,8 @@ def do_convert_data(rocketchat_data_dir: str, output_dir: str) -> None:
) )
zerver_direct_message_group = convert_direct_message_group_data( zerver_direct_message_group = convert_direct_message_group_data(
huddle_id_to_huddle_map=huddle_id_to_huddle_map, direct_message_group_id_to_direct_message_group_map=direct_message_group_id_to_direct_message_group_map,
huddle_id_mapper=huddle_id_mapper, direct_message_group_id_mapper=direct_message_group_id_mapper,
user_id_mapper=user_id_mapper, user_id_mapper=user_id_mapper,
subscriber_handler=subscriber_handler, subscriber_handler=subscriber_handler,
) )
@ -1150,13 +1157,13 @@ def do_convert_data(rocketchat_data_dir: str, output_dir: str) -> None:
) )
stream_id_to_recipient_id: dict[int, int] = {} stream_id_to_recipient_id: dict[int, int] = {}
huddle_id_to_recipient_id: dict[int, int] = {} direct_message_group_id_to_recipient_id: dict[int, int] = {}
user_id_to_recipient_id: dict[int, int] = {} user_id_to_recipient_id: dict[int, int] = {}
map_receiver_id_to_recipient_id( map_receiver_id_to_recipient_id(
zerver_recipient=zerver_recipient, zerver_recipient=zerver_recipient,
stream_id_to_recipient_id=stream_id_to_recipient_id, stream_id_to_recipient_id=stream_id_to_recipient_id,
huddle_id_to_recipient_id=huddle_id_to_recipient_id, direct_message_group_id_to_recipient_id=direct_message_group_id_to_recipient_id,
user_id_to_recipient_id=user_id_to_recipient_id, user_id_to_recipient_id=user_id_to_recipient_id,
) )
@ -1168,7 +1175,7 @@ def do_convert_data(rocketchat_data_dir: str, output_dir: str) -> None:
messages=rocketchat_data["message"], messages=rocketchat_data["message"],
dsc_id_to_dsc_map=dsc_id_to_dsc_map, dsc_id_to_dsc_map=dsc_id_to_dsc_map,
direct_id_to_direct_map=direct_id_to_direct_map, direct_id_to_direct_map=direct_id_to_direct_map,
huddle_id_to_huddle_map=huddle_id_to_huddle_map, direct_message_group_id_to_direct_message_group_map=direct_message_group_id_to_direct_message_group_map,
livechat_id_to_livechat_map=livechat_id_to_livechat_map, livechat_id_to_livechat_map=livechat_id_to_livechat_map,
channel_messages=channel_messages, channel_messages=channel_messages,
private_messages=private_messages, private_messages=private_messages,
@ -1193,13 +1200,13 @@ def do_convert_data(rocketchat_data_dir: str, output_dir: str) -> None:
user_id_to_recipient_id=user_id_to_recipient_id, user_id_to_recipient_id=user_id_to_recipient_id,
stream_id_mapper=stream_id_mapper, stream_id_mapper=stream_id_mapper,
stream_id_to_recipient_id=stream_id_to_recipient_id, stream_id_to_recipient_id=stream_id_to_recipient_id,
huddle_id_mapper=huddle_id_mapper, direct_message_group_id_mapper=direct_message_group_id_mapper,
huddle_id_to_recipient_id=huddle_id_to_recipient_id, direct_message_group_id_to_recipient_id=direct_message_group_id_to_recipient_id,
thread_id_mapper=thread_id_mapper, thread_id_mapper=thread_id_mapper,
room_id_to_room_map=room_id_to_room_map, room_id_to_room_map=room_id_to_room_map,
dsc_id_to_dsc_map=dsc_id_to_dsc_map, dsc_id_to_dsc_map=dsc_id_to_dsc_map,
direct_id_to_direct_map=direct_id_to_direct_map, direct_id_to_direct_map=direct_id_to_direct_map,
huddle_id_to_huddle_map=huddle_id_to_huddle_map, direct_message_group_id_to_direct_message_group_map=direct_message_group_id_to_direct_message_group_map,
zerver_realmemoji=zerver_realmemoji, zerver_realmemoji=zerver_realmemoji,
total_reactions=total_reactions, total_reactions=total_reactions,
uploads_list=uploads_list, uploads_list=uploads_list,
@ -1219,13 +1226,13 @@ def do_convert_data(rocketchat_data_dir: str, output_dir: str) -> None:
user_id_to_recipient_id=user_id_to_recipient_id, user_id_to_recipient_id=user_id_to_recipient_id,
stream_id_mapper=stream_id_mapper, stream_id_mapper=stream_id_mapper,
stream_id_to_recipient_id=stream_id_to_recipient_id, stream_id_to_recipient_id=stream_id_to_recipient_id,
huddle_id_mapper=huddle_id_mapper, direct_message_group_id_mapper=direct_message_group_id_mapper,
huddle_id_to_recipient_id=huddle_id_to_recipient_id, direct_message_group_id_to_recipient_id=direct_message_group_id_to_recipient_id,
thread_id_mapper=thread_id_mapper, thread_id_mapper=thread_id_mapper,
room_id_to_room_map=room_id_to_room_map, room_id_to_room_map=room_id_to_room_map,
dsc_id_to_dsc_map=dsc_id_to_dsc_map, dsc_id_to_dsc_map=dsc_id_to_dsc_map,
direct_id_to_direct_map=direct_id_to_direct_map, direct_id_to_direct_map=direct_id_to_direct_map,
huddle_id_to_huddle_map=huddle_id_to_huddle_map, direct_message_group_id_to_direct_message_group_map=direct_message_group_id_to_direct_message_group_map,
zerver_realmemoji=zerver_realmemoji, zerver_realmemoji=zerver_realmemoji,
total_reactions=total_reactions, total_reactions=total_reactions,
uploads_list=uploads_list, uploads_list=uploads_list,

View File

@ -151,7 +151,7 @@ def bulk_fetch_user_display_recipients(
direct_message_group_recipient_ids = [ direct_message_group_recipient_ids = [
get_recipient_id(tup) for tup in direct_message_group_tuples get_recipient_id(tup) for tup in direct_message_group_tuples
] ]
huddle_recipient_id_to_user_ids = bulk_get_direct_message_group_user_ids( user_ids_in_direct_message_groups = bulk_get_direct_message_group_user_ids(
direct_message_group_recipient_ids direct_message_group_recipient_ids
) )
@ -161,7 +161,7 @@ def bulk_fetch_user_display_recipients(
} }
for recipient_id in direct_message_group_recipient_ids: for recipient_id in direct_message_group_recipient_ids:
direct_message_group_user_ids = huddle_recipient_id_to_user_ids[recipient_id] direct_message_group_user_ids = user_ids_in_direct_message_groups[recipient_id]
user_ids_to_fetch |= direct_message_group_user_ids user_ids_to_fetch |= direct_message_group_user_ids
# Fetch the needed user dictionaries. # Fetch the needed user dictionaries.
@ -174,7 +174,7 @@ def bulk_fetch_user_display_recipients(
result[recipient_id] = display_recipients result[recipient_id] = display_recipients
for recipient_id in direct_message_group_recipient_ids: for recipient_id in direct_message_group_recipient_ids:
user_ids = sorted(huddle_recipient_id_to_user_ids[recipient_id]) user_ids = sorted(user_ids_in_direct_message_groups[recipient_id])
display_recipients = [user_display_recipients[user_id] for user_id in user_ids] display_recipients = [user_display_recipients[user_id] for user_id in user_ids]
result[recipient_id] = display_recipients result[recipient_id] = display_recipients

View File

@ -1134,39 +1134,48 @@ def custom_fetch_direct_message_groups(response: TableData, context: Context) ->
r["id"] for r in response["zerver_userprofile"] + response["zerver_userprofile_mirrordummy"] r["id"] for r in response["zerver_userprofile"] + response["zerver_userprofile_mirrordummy"]
} }
# First we get all huddles involving someone in the realm. # First we get all direct message groups involving someone in the realm.
realm_huddle_subs = Subscription.objects.select_related("recipient").filter( realm_direct_message_group_subs = Subscription.objects.select_related("recipient").filter(
recipient__type=Recipient.DIRECT_MESSAGE_GROUP, user_profile__in=user_profile_ids recipient__type=Recipient.DIRECT_MESSAGE_GROUP, user_profile__in=user_profile_ids
) )
realm_huddle_recipient_ids = {sub.recipient_id for sub in realm_huddle_subs} realm_direct_message_group_recipient_ids = {
sub.recipient_id for sub in realm_direct_message_group_subs
}
# Mark all Direct Message groups whose recipient ID contains a cross-realm user. # Mark all Direct Message groups whose recipient ID contains a cross-realm user.
unsafe_huddle_recipient_ids = set() unsafe_direct_message_group_recipient_ids = set()
for sub in Subscription.objects.select_related("user_profile").filter( for sub in Subscription.objects.select_related("user_profile").filter(
recipient__in=realm_huddle_recipient_ids recipient__in=realm_direct_message_group_recipient_ids
): ):
if sub.user_profile.realm_id != realm.id: if sub.user_profile.realm_id != realm.id:
# In almost every case the other realm will be zulip.com # In almost every case the other realm will be zulip.com
unsafe_huddle_recipient_ids.add(sub.recipient_id) unsafe_direct_message_group_recipient_ids.add(sub.recipient_id)
# Now filter down to just those huddles that are entirely within the realm. # Now filter down to just those direct message groups that are
# entirely within the realm.
# #
# This is important for ensuring that the User objects needed # This is important for ensuring that the User objects needed
# to import it on the other end exist (since we're only # to import it on the other end exist (since we're only
# exporting the users from this realm), at the cost of losing # exporting the users from this realm), at the cost of losing
# some of these cross-realm messages. # some of these cross-realm messages.
huddle_subs = [ direct_message_group_subs = [
sub for sub in realm_huddle_subs if sub.recipient_id not in unsafe_huddle_recipient_ids sub
for sub in realm_direct_message_group_subs
if sub.recipient_id not in unsafe_direct_message_group_recipient_ids
] ]
huddle_recipient_ids = {sub.recipient_id for sub in huddle_subs} direct_message_group_recipient_ids = {sub.recipient_id for sub in direct_message_group_subs}
huddle_ids = {sub.recipient.type_id for sub in huddle_subs} direct_message_group_ids = {sub.recipient.type_id for sub in direct_message_group_subs}
huddle_subscription_dicts = make_raw(huddle_subs) direct_message_group_subscription_dicts = make_raw(direct_message_group_subs)
huddle_recipients = make_raw(Recipient.objects.filter(id__in=huddle_recipient_ids)) direct_message_group_recipients = make_raw(
Recipient.objects.filter(id__in=direct_message_group_recipient_ids)
)
response["_huddle_recipient"] = huddle_recipients response["_huddle_recipient"] = direct_message_group_recipients
response["_huddle_subscription"] = huddle_subscription_dicts response["_huddle_subscription"] = direct_message_group_subscription_dicts
response["zerver_huddle"] = make_raw(DirectMessageGroup.objects.filter(id__in=huddle_ids)) response["zerver_huddle"] = make_raw(
DirectMessageGroup.objects.filter(id__in=direct_message_group_ids)
)
def custom_fetch_scheduled_messages(response: TableData, context: Context) -> None: def custom_fetch_scheduled_messages(response: TableData, context: Context) -> None:

View File

@ -605,7 +605,7 @@ class NarrowBuilder:
except (JsonableError, ValidationError): except (JsonableError, ValidationError):
raise BadNarrowOperatorError("unknown user in " + str(operand)) raise BadNarrowOperatorError("unknown user in " + str(operand))
except DirectMessageGroup.DoesNotExist: except DirectMessageGroup.DoesNotExist:
# Group DM where huddle doesn't exist # Group DM where direct message group doesn't exist
return query.where(maybe_negate(false())) return query.where(maybe_negate(false()))
# Group direct message # Group direct message

View File

@ -719,7 +719,7 @@ def get_user_ids_who_can_access_user(target_user: UserProfile) -> list[int]:
def get_subscribers_of_target_user_subscriptions( def get_subscribers_of_target_user_subscriptions(
target_users: list[UserProfile], include_deactivated_users_for_huddles: bool = False target_users: list[UserProfile], include_deactivated_users_for_dm_groups: bool = False
) -> dict[int, set[int]]: ) -> dict[int, set[int]]:
target_user_ids = [user.id for user in target_users] target_user_ids = [user.id for user in target_users]
target_user_subscriptions = ( target_user_subscriptions = (
@ -747,7 +747,7 @@ def get_subscribers_of_target_user_subscriptions(
active=True, active=True,
) )
if include_deactivated_users_for_huddles: if include_deactivated_users_for_dm_groups:
subs_in_target_user_subscriptions_query = subs_in_target_user_subscriptions_query.filter( subs_in_target_user_subscriptions_query = subs_in_target_user_subscriptions_query.filter(
Q(recipient__type=Recipient.STREAM, is_user_active=True) Q(recipient__type=Recipient.STREAM, is_user_active=True)
| Q(recipient__type=Recipient.DIRECT_MESSAGE_GROUP) | Q(recipient__type=Recipient.DIRECT_MESSAGE_GROUP)
@ -916,7 +916,7 @@ def get_accessible_user_ids(
realm: Realm, user_profile: UserProfile, include_deactivated_users: bool = False realm: Realm, user_profile: UserProfile, include_deactivated_users: bool = False
) -> list[int]: ) -> list[int]:
subscribers_dict_of_target_user_subscriptions = get_subscribers_of_target_user_subscriptions( subscribers_dict_of_target_user_subscriptions = get_subscribers_of_target_user_subscriptions(
[user_profile], include_deactivated_users_for_huddles=include_deactivated_users [user_profile], include_deactivated_users_for_dm_groups=include_deactivated_users
) )
users_involved_in_dms_dict = get_users_involved_in_dms_with_target_users( users_involved_in_dms_dict = get_users_involved_in_dms_with_target_users(
[user_profile], realm, include_deactivated_users=include_deactivated_users [user_profile], realm, include_deactivated_users=include_deactivated_users

View File

@ -150,7 +150,7 @@ class Message(AbstractMessage):
# A detail worth noting: # A detail worth noting:
# * "direct" was introduced in 2023 with the goal of # * "direct" was introduced in 2023 with the goal of
# deprecating the original "private" and becoming the # deprecating the original "private" and becoming the
# preferred way to indicate a personal or huddle # preferred way to indicate a personal or direct_message_group
# Recipient type via the API. # Recipient type via the API.
API_RECIPIENT_TYPES = ["direct", "private", "stream", "channel"] API_RECIPIENT_TYPES = ["direct", "private", "stream", "channel"]

View File

@ -43,7 +43,7 @@ class Recipient(models.Model):
id = models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID") id = models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")
type_id = models.IntegerField(db_index=True) type_id = models.IntegerField(db_index=True)
type = models.PositiveSmallIntegerField(db_index=True) type = models.PositiveSmallIntegerField(db_index=True)
# Valid types are {personal, stream, huddle} # Valid types are {personal, stream, direct_message_group}
# The type for 1:1 direct messages. # The type for 1:1 direct messages.
PERSONAL = 1 PERSONAL = 1
@ -56,7 +56,11 @@ class Recipient(models.Model):
unique_together = ("type", "type_id") unique_together = ("type", "type_id")
# N.B. If we used Django's choice=... we would get this for free (kinda) # N.B. If we used Django's choice=... we would get this for free (kinda)
_type_names = {PERSONAL: "personal", STREAM: "stream", DIRECT_MESSAGE_GROUP: "huddle"} _type_names = {
PERSONAL: "personal",
STREAM: "stream",
DIRECT_MESSAGE_GROUP: "direct_message_group",
}
@override @override
def __str__(self) -> str: def __str__(self) -> str:
@ -91,12 +95,13 @@ def get_direct_message_group_user_ids(recipient: Recipient) -> ValuesQuerySet["S
def bulk_get_direct_message_group_user_ids(recipient_ids: list[int]) -> dict[int, set[int]]: def bulk_get_direct_message_group_user_ids(recipient_ids: list[int]) -> dict[int, set[int]]:
""" """
Takes a list of huddle-type recipient_ids, returns a dict Takes a list of direct_message_group type recipient_ids, returns
mapping recipient id to list of user ids in the huddle. a dictmapping recipient id to list of user ids in the direct
message group.
We rely on our caller to pass us recipient_ids that correspond We rely on our caller to pass us recipient_ids that correspond
to huddles, but technically this function is valid for any type to direct_message_group, but technically this function is valid
of subscription. for any typeof subscription.
""" """
from zerver.models import Subscription from zerver.models import Subscription

View File

@ -72,7 +72,7 @@ class MissedMessageEmailAddress(models.Model):
class NotificationTriggers: class NotificationTriggers:
# "direct_message" is for 1:1 direct messages as well as huddles # "direct_message" is for 1:1 and group direct messages
DIRECT_MESSAGE = "direct_message" DIRECT_MESSAGE = "direct_message"
MENTION = "mentioned" MENTION = "mentioned"
TOPIC_WILDCARD_MENTION = "topic_wildcard_mentioned" TOPIC_WILDCARD_MENTION = "topic_wildcard_mentioned"

View File

@ -345,7 +345,7 @@ class MatterMostImporter(ZulipTestCase):
user_handler = UserHandler() user_handler = UserHandler()
subscriber_handler = SubscriberHandler() subscriber_handler = SubscriberHandler()
huddle_id_mapper = IdMapper[frozenset[str]]() direct_message_group_id_mapper = IdMapper[frozenset[str]]()
user_id_mapper = IdMapper[str]() user_id_mapper = IdMapper[str]()
team_name = "gryffindor" team_name = "gryffindor"
@ -361,7 +361,7 @@ class MatterMostImporter(ZulipTestCase):
direct_message_group_data=mattermost_data["direct_channel"], direct_message_group_data=mattermost_data["direct_channel"],
user_data_map=username_to_user, user_data_map=username_to_user,
subscriber_handler=subscriber_handler, subscriber_handler=subscriber_handler,
huddle_id_mapper=huddle_id_mapper, direct_message_group_id_mapper=direct_message_group_id_mapper,
user_id_mapper=user_id_mapper, user_id_mapper=user_id_mapper,
realm_id=3, realm_id=3,
team_name=team_name, team_name=team_name,
@ -370,10 +370,12 @@ class MatterMostImporter(ZulipTestCase):
self.assert_length(zerver_huddle, 1) self.assert_length(zerver_huddle, 1)
direct_message_group_members = frozenset(mattermost_data["direct_channel"][1]["members"]) direct_message_group_members = frozenset(mattermost_data["direct_channel"][1]["members"])
self.assertTrue(huddle_id_mapper.has(direct_message_group_members)) self.assertTrue(direct_message_group_id_mapper.has(direct_message_group_members))
self.assertEqual( self.assertEqual(
subscriber_handler.get_users( subscriber_handler.get_users(
direct_message_group_id=huddle_id_mapper.get(direct_message_group_members) direct_message_group_id=direct_message_group_id_mapper.get(
direct_message_group_members
)
), ),
{1, 2, 3}, {1, 2, 3},
) )

View File

@ -188,7 +188,7 @@ class RocketChatImporter(ZulipTestCase):
team_id_to_team_map: dict[str, dict[str, Any]] = {} team_id_to_team_map: dict[str, dict[str, Any]] = {}
dsc_id_to_dsc_map: dict[str, dict[str, Any]] = {} dsc_id_to_dsc_map: dict[str, dict[str, Any]] = {}
direct_id_to_direct_map: dict[str, dict[str, Any]] = {} direct_id_to_direct_map: dict[str, dict[str, Any]] = {}
huddle_id_to_huddle_map: dict[str, dict[str, Any]] = {} direct_message_group_id_to_direct_message_group_map: dict[str, dict[str, Any]] = {}
livechat_id_to_livechat_map: dict[str, dict[str, Any]] = {} livechat_id_to_livechat_map: dict[str, dict[str, Any]] = {}
with self.assertLogs(level="INFO"): with self.assertLogs(level="INFO"):
@ -198,7 +198,7 @@ class RocketChatImporter(ZulipTestCase):
team_id_to_team_map=team_id_to_team_map, team_id_to_team_map=team_id_to_team_map,
dsc_id_to_dsc_map=dsc_id_to_dsc_map, dsc_id_to_dsc_map=dsc_id_to_dsc_map,
direct_id_to_direct_map=direct_id_to_direct_map, direct_id_to_direct_map=direct_id_to_direct_map,
huddle_id_to_huddle_map=huddle_id_to_huddle_map, direct_message_group_id_to_direct_message_group_map=direct_message_group_id_to_direct_message_group_map,
livechat_id_to_livechat_map=livechat_id_to_livechat_map, livechat_id_to_livechat_map=livechat_id_to_livechat_map,
) )
@ -208,7 +208,7 @@ class RocketChatImporter(ZulipTestCase):
self.assert_length(team_id_to_team_map, 1) self.assert_length(team_id_to_team_map, 1)
self.assert_length(dsc_id_to_dsc_map, 5) self.assert_length(dsc_id_to_dsc_map, 5)
self.assert_length(direct_id_to_direct_map, 2) self.assert_length(direct_id_to_direct_map, 2)
self.assert_length(huddle_id_to_huddle_map, 1) self.assert_length(direct_message_group_id_to_direct_message_group_map, 1)
self.assert_length(livechat_id_to_livechat_map, 2) self.assert_length(livechat_id_to_livechat_map, 2)
room_id = rocketchat_data["room"][0]["_id"] room_id = rocketchat_data["room"][0]["_id"]
@ -228,9 +228,10 @@ class RocketChatImporter(ZulipTestCase):
self.assertEqual(direct_id_to_direct_map[direct_id], rocketchat_data["room"][4]) self.assertEqual(direct_id_to_direct_map[direct_id], rocketchat_data["room"][4])
direct_message_group_id = rocketchat_data["room"][12]["_id"] direct_message_group_id = rocketchat_data["room"][12]["_id"]
self.assertIn(direct_message_group_id, huddle_id_to_huddle_map) self.assertIn(direct_message_group_id, direct_message_group_id_to_direct_message_group_map)
self.assertEqual( self.assertEqual(
huddle_id_to_huddle_map[direct_message_group_id], rocketchat_data["room"][12] direct_message_group_id_to_direct_message_group_map[direct_message_group_id],
rocketchat_data["room"][12],
) )
livechat_id = rocketchat_data["room"][14]["_id"] livechat_id = rocketchat_data["room"][14]["_id"]
@ -248,7 +249,7 @@ class RocketChatImporter(ZulipTestCase):
team_id_to_team_map: dict[str, dict[str, Any]] = {} team_id_to_team_map: dict[str, dict[str, Any]] = {}
dsc_id_to_dsc_map: dict[str, dict[str, Any]] = {} dsc_id_to_dsc_map: dict[str, dict[str, Any]] = {}
direct_id_to_direct_map: dict[str, dict[str, Any]] = {} direct_id_to_direct_map: dict[str, dict[str, Any]] = {}
huddle_id_to_huddle_map: dict[str, dict[str, Any]] = {} direct_message_group_id_to_direct_message_group_map: dict[str, dict[str, Any]] = {}
livechat_id_to_livechat_map: dict[str, dict[str, Any]] = {} livechat_id_to_livechat_map: dict[str, dict[str, Any]] = {}
with self.assertLogs(level="INFO"): with self.assertLogs(level="INFO"):
@ -258,7 +259,7 @@ class RocketChatImporter(ZulipTestCase):
team_id_to_team_map=team_id_to_team_map, team_id_to_team_map=team_id_to_team_map,
dsc_id_to_dsc_map=dsc_id_to_dsc_map, dsc_id_to_dsc_map=dsc_id_to_dsc_map,
direct_id_to_direct_map=direct_id_to_direct_map, direct_id_to_direct_map=direct_id_to_direct_map,
huddle_id_to_huddle_map=huddle_id_to_huddle_map, direct_message_group_id_to_direct_message_group_map=direct_message_group_id_to_direct_message_group_map,
livechat_id_to_livechat_map=livechat_id_to_livechat_map, livechat_id_to_livechat_map=livechat_id_to_livechat_map,
) )
@ -333,7 +334,7 @@ class RocketChatImporter(ZulipTestCase):
team_id_to_team_map: dict[str, dict[str, Any]] = {} team_id_to_team_map: dict[str, dict[str, Any]] = {}
dsc_id_to_dsc_map: dict[str, dict[str, Any]] = {} dsc_id_to_dsc_map: dict[str, dict[str, Any]] = {}
direct_id_to_direct_map: dict[str, dict[str, Any]] = {} direct_id_to_direct_map: dict[str, dict[str, Any]] = {}
huddle_id_to_huddle_map: dict[str, dict[str, Any]] = {} direct_message_group_id_to_direct_message_group_map: dict[str, dict[str, Any]] = {}
livechat_id_to_livechat_map: dict[str, dict[str, Any]] = {} livechat_id_to_livechat_map: dict[str, dict[str, Any]] = {}
with self.assertLogs(level="INFO"): with self.assertLogs(level="INFO"):
@ -343,7 +344,7 @@ class RocketChatImporter(ZulipTestCase):
team_id_to_team_map=team_id_to_team_map, team_id_to_team_map=team_id_to_team_map,
dsc_id_to_dsc_map=dsc_id_to_dsc_map, dsc_id_to_dsc_map=dsc_id_to_dsc_map,
direct_id_to_direct_map=direct_id_to_direct_map, direct_id_to_direct_map=direct_id_to_direct_map,
huddle_id_to_huddle_map=huddle_id_to_huddle_map, direct_message_group_id_to_direct_message_group_map=direct_message_group_id_to_direct_message_group_map,
livechat_id_to_livechat_map=livechat_id_to_livechat_map, livechat_id_to_livechat_map=livechat_id_to_livechat_map,
) )
@ -424,7 +425,7 @@ class RocketChatImporter(ZulipTestCase):
user_handler = UserHandler() user_handler = UserHandler()
subscriber_handler = SubscriberHandler() subscriber_handler = SubscriberHandler()
user_id_mapper = IdMapper[str]() user_id_mapper = IdMapper[str]()
huddle_id_mapper = IdMapper[str]() direct_message_group_id_mapper = IdMapper[str]()
user_id_to_user_map = map_user_id_to_user(rocketchat_data["user"]) user_id_to_user_map = map_user_id_to_user(rocketchat_data["user"])
@ -440,7 +441,7 @@ class RocketChatImporter(ZulipTestCase):
team_id_to_team_map: dict[str, dict[str, Any]] = {} team_id_to_team_map: dict[str, dict[str, Any]] = {}
dsc_id_to_dsc_map: dict[str, dict[str, Any]] = {} dsc_id_to_dsc_map: dict[str, dict[str, Any]] = {}
direct_id_to_direct_map: dict[str, dict[str, Any]] = {} direct_id_to_direct_map: dict[str, dict[str, Any]] = {}
huddle_id_to_huddle_map: dict[str, dict[str, Any]] = {} direct_message_group_id_to_direct_message_group_map: dict[str, dict[str, Any]] = {}
livechat_id_to_livechat_map: dict[str, dict[str, Any]] = {} livechat_id_to_livechat_map: dict[str, dict[str, Any]] = {}
with self.assertLogs(level="INFO"): with self.assertLogs(level="INFO"):
@ -450,23 +451,23 @@ class RocketChatImporter(ZulipTestCase):
team_id_to_team_map=team_id_to_team_map, team_id_to_team_map=team_id_to_team_map,
dsc_id_to_dsc_map=dsc_id_to_dsc_map, dsc_id_to_dsc_map=dsc_id_to_dsc_map,
direct_id_to_direct_map=direct_id_to_direct_map, direct_id_to_direct_map=direct_id_to_direct_map,
huddle_id_to_huddle_map=huddle_id_to_huddle_map, direct_message_group_id_to_direct_message_group_map=direct_message_group_id_to_direct_message_group_map,
livechat_id_to_livechat_map=livechat_id_to_livechat_map, livechat_id_to_livechat_map=livechat_id_to_livechat_map,
) )
zerver_direct_message_group = convert_direct_message_group_data( zerver_direct_message_group = convert_direct_message_group_data(
huddle_id_to_huddle_map=huddle_id_to_huddle_map, direct_message_group_id_to_direct_message_group_map=direct_message_group_id_to_direct_message_group_map,
huddle_id_mapper=huddle_id_mapper, direct_message_group_id_mapper=direct_message_group_id_mapper,
user_id_mapper=user_id_mapper, user_id_mapper=user_id_mapper,
subscriber_handler=subscriber_handler, subscriber_handler=subscriber_handler,
) )
self.assert_length(zerver_direct_message_group, 1) self.assert_length(zerver_direct_message_group, 1)
rc_huddle_id = rocketchat_data["room"][12]["_id"] rc_direct_message_group_id = rocketchat_data["room"][12]["_id"]
self.assertTrue(huddle_id_mapper.has(rc_huddle_id)) self.assertTrue(direct_message_group_id_mapper.has(rc_direct_message_group_id))
direct_message_group_id = huddle_id_mapper.get(rc_huddle_id) direct_message_group_id = direct_message_group_id_mapper.get(rc_direct_message_group_id)
self.assertEqual( self.assertEqual(
subscriber_handler.get_users(direct_message_group_id=direct_message_group_id), {3, 4, 5} subscriber_handler.get_users(direct_message_group_id=direct_message_group_id), {3, 4, 5}
) )
@ -527,7 +528,7 @@ class RocketChatImporter(ZulipTestCase):
subscriber_handler = SubscriberHandler() subscriber_handler = SubscriberHandler()
user_id_mapper = IdMapper[str]() user_id_mapper = IdMapper[str]()
stream_id_mapper = IdMapper[str]() stream_id_mapper = IdMapper[str]()
huddle_id_mapper = IdMapper[str]() direct_message_group_id_mapper = IdMapper[str]()
user_id_to_user_map = map_user_id_to_user(rocketchat_data["user"]) user_id_to_user_map = map_user_id_to_user(rocketchat_data["user"])
@ -543,7 +544,7 @@ class RocketChatImporter(ZulipTestCase):
team_id_to_team_map: dict[str, dict[str, Any]] = {} team_id_to_team_map: dict[str, dict[str, Any]] = {}
dsc_id_to_dsc_map: dict[str, dict[str, Any]] = {} dsc_id_to_dsc_map: dict[str, dict[str, Any]] = {}
direct_id_to_direct_map: dict[str, dict[str, Any]] = {} direct_id_to_direct_map: dict[str, dict[str, Any]] = {}
huddle_id_to_huddle_map: dict[str, dict[str, Any]] = {} direct_message_group_id_to_direct_message_group_map: dict[str, dict[str, Any]] = {}
livechat_id_to_livechat_map: dict[str, dict[str, Any]] = {} livechat_id_to_livechat_map: dict[str, dict[str, Any]] = {}
with self.assertLogs(level="INFO"): with self.assertLogs(level="INFO"):
@ -553,7 +554,7 @@ class RocketChatImporter(ZulipTestCase):
team_id_to_team_map=team_id_to_team_map, team_id_to_team_map=team_id_to_team_map,
dsc_id_to_dsc_map=dsc_id_to_dsc_map, dsc_id_to_dsc_map=dsc_id_to_dsc_map,
direct_id_to_direct_map=direct_id_to_direct_map, direct_id_to_direct_map=direct_id_to_direct_map,
huddle_id_to_huddle_map=huddle_id_to_huddle_map, direct_message_group_id_to_direct_message_group_map=direct_message_group_id_to_direct_message_group_map,
livechat_id_to_livechat_map=livechat_id_to_livechat_map, livechat_id_to_livechat_map=livechat_id_to_livechat_map,
) )
@ -565,8 +566,8 @@ class RocketChatImporter(ZulipTestCase):
) )
zerver_direct_message_group = convert_direct_message_group_data( zerver_direct_message_group = convert_direct_message_group_data(
huddle_id_to_huddle_map=huddle_id_to_huddle_map, direct_message_group_id_to_direct_message_group_map=direct_message_group_id_to_direct_message_group_map,
huddle_id_mapper=huddle_id_mapper, direct_message_group_id_mapper=direct_message_group_id_mapper,
user_id_mapper=user_id_mapper, user_id_mapper=user_id_mapper,
subscriber_handler=subscriber_handler, subscriber_handler=subscriber_handler,
) )
@ -581,20 +582,20 @@ class RocketChatImporter(ZulipTestCase):
stream_id_to_recipient_id: dict[int, int] = {} stream_id_to_recipient_id: dict[int, int] = {}
user_id_to_recipient_id: dict[int, int] = {} user_id_to_recipient_id: dict[int, int] = {}
huddle_id_to_recipient_id: dict[int, int] = {} direct_message_group_id_to_recipient_id: dict[int, int] = {}
map_receiver_id_to_recipient_id( map_receiver_id_to_recipient_id(
zerver_recipient=zerver_recipient, zerver_recipient=zerver_recipient,
stream_id_to_recipient_id=stream_id_to_recipient_id, stream_id_to_recipient_id=stream_id_to_recipient_id,
user_id_to_recipient_id=user_id_to_recipient_id, user_id_to_recipient_id=user_id_to_recipient_id,
huddle_id_to_recipient_id=huddle_id_to_recipient_id, direct_message_group_id_to_recipient_id=direct_message_group_id_to_recipient_id,
) )
# 6 for streams and 6 for users. # 6 for streams and 6 for users.
self.assert_length(zerver_recipient, 13) self.assert_length(zerver_recipient, 13)
self.assert_length(stream_id_to_recipient_id, 6) self.assert_length(stream_id_to_recipient_id, 6)
self.assert_length(user_id_to_recipient_id, 6) self.assert_length(user_id_to_recipient_id, 6)
self.assert_length(huddle_id_to_recipient_id, 1) self.assert_length(direct_message_group_id_to_recipient_id, 1)
# First user recipients are built, followed by stream recipients in `build_recipients`. # First user recipients are built, followed by stream recipients in `build_recipients`.
self.assertEqual( self.assertEqual(
@ -612,7 +613,8 @@ class RocketChatImporter(ZulipTestCase):
) )
self.assertEqual( self.assertEqual(
huddle_id_to_recipient_id[zerver_recipient[12]["type_id"]], zerver_recipient[12]["id"] direct_message_group_id_to_recipient_id[zerver_recipient[12]["type_id"]],
zerver_recipient[12]["id"],
) )
def test_separate_channel_private_and_livechat_messages(self) -> None: def test_separate_channel_private_and_livechat_messages(self) -> None:
@ -623,7 +625,7 @@ class RocketChatImporter(ZulipTestCase):
team_id_to_team_map: dict[str, dict[str, Any]] = {} team_id_to_team_map: dict[str, dict[str, Any]] = {}
dsc_id_to_dsc_map: dict[str, dict[str, Any]] = {} dsc_id_to_dsc_map: dict[str, dict[str, Any]] = {}
direct_id_to_direct_map: dict[str, dict[str, Any]] = {} direct_id_to_direct_map: dict[str, dict[str, Any]] = {}
huddle_id_to_huddle_map: dict[str, dict[str, Any]] = {} direct_message_group_id_to_direct_message_group_map: dict[str, dict[str, Any]] = {}
livechat_id_to_livechat_map: dict[str, dict[str, Any]] = {} livechat_id_to_livechat_map: dict[str, dict[str, Any]] = {}
with self.assertLogs(level="INFO"): with self.assertLogs(level="INFO"):
@ -633,7 +635,7 @@ class RocketChatImporter(ZulipTestCase):
team_id_to_team_map=team_id_to_team_map, team_id_to_team_map=team_id_to_team_map,
dsc_id_to_dsc_map=dsc_id_to_dsc_map, dsc_id_to_dsc_map=dsc_id_to_dsc_map,
direct_id_to_direct_map=direct_id_to_direct_map, direct_id_to_direct_map=direct_id_to_direct_map,
huddle_id_to_huddle_map=huddle_id_to_huddle_map, direct_message_group_id_to_direct_message_group_map=direct_message_group_id_to_direct_message_group_map,
livechat_id_to_livechat_map=livechat_id_to_livechat_map, livechat_id_to_livechat_map=livechat_id_to_livechat_map,
) )
@ -645,7 +647,7 @@ class RocketChatImporter(ZulipTestCase):
messages=rocketchat_data["message"], messages=rocketchat_data["message"],
dsc_id_to_dsc_map=dsc_id_to_dsc_map, dsc_id_to_dsc_map=dsc_id_to_dsc_map,
direct_id_to_direct_map=direct_id_to_direct_map, direct_id_to_direct_map=direct_id_to_direct_map,
huddle_id_to_huddle_map=huddle_id_to_huddle_map, direct_message_group_id_to_direct_message_group_map=direct_message_group_id_to_direct_message_group_map,
livechat_id_to_livechat_map=livechat_id_to_livechat_map, livechat_id_to_livechat_map=livechat_id_to_livechat_map,
channel_messages=channel_messages, channel_messages=channel_messages,
private_messages=private_messages, private_messages=private_messages,
@ -705,7 +707,7 @@ class RocketChatImporter(ZulipTestCase):
messages=rocketchat_data["message"], messages=rocketchat_data["message"],
dsc_id_to_dsc_map=dsc_id_to_dsc_map, dsc_id_to_dsc_map=dsc_id_to_dsc_map,
direct_id_to_direct_map=direct_id_to_direct_map, direct_id_to_direct_map=direct_id_to_direct_map,
huddle_id_to_huddle_map=huddle_id_to_huddle_map, direct_message_group_id_to_direct_message_group_map=direct_message_group_id_to_direct_message_group_map,
livechat_id_to_livechat_map=livechat_id_to_livechat_map, livechat_id_to_livechat_map=livechat_id_to_livechat_map,
channel_messages=channel_messages, channel_messages=channel_messages,
private_messages=private_messages, private_messages=private_messages,
@ -890,7 +892,7 @@ class RocketChatImporter(ZulipTestCase):
self.assertEqual( self.assertEqual(
info_log.output, info_log.output,
[ [
"INFO:root:Huddle channel found. UIDs: ['LdBZ7kPxtKESyHPEe', 'M2sXGqoQRJQwQoXY2', 'os6N2Xg2JkNMCSW9Z']", "INFO:root:Direct message group channel found. UIDs: ['LdBZ7kPxtKESyHPEe', 'M2sXGqoQRJQwQoXY2', 'os6N2Xg2JkNMCSW9Z']",
"INFO:root:Starting to process custom emoji", "INFO:root:Starting to process custom emoji",
"INFO:root:Done processing emoji", "INFO:root:Done processing emoji",
"INFO:root:skipping direct messages discussion mention: Discussion with Hermione", "INFO:root:skipping direct messages discussion mention: Discussion with Hermione",

View File

@ -250,11 +250,11 @@ class Command(ZulipBaseCommand):
parser.add_argument("--max-topics", type=int, help="The number of maximum topics to create") parser.add_argument("--max-topics", type=int, help="The number of maximum topics to create")
parser.add_argument( parser.add_argument(
"--huddles", "--direct-message-groups",
dest="num_huddles", dest="num_direct_message_groups",
type=int, type=int,
default=3, default=3,
help="The number of huddles to create.", help="The number of direct message groups to create.",
) )
parser.add_argument( parser.add_argument(
@ -268,10 +268,10 @@ class Command(ZulipBaseCommand):
parser.add_argument("--threads", type=int, default=1, help="The number of threads to use.") parser.add_argument("--threads", type=int, default=1, help="The number of threads to use.")
parser.add_argument( parser.add_argument(
"--percent-huddles", "--percent-direct-message-groups",
type=float, type=float,
default=15, default=15,
help="The percent of messages to be huddles.", help="The percent of messages to be direct message groups.",
) )
parser.add_argument( parser.add_argument(
@ -307,7 +307,7 @@ class Command(ZulipBaseCommand):
# Suppress spammy output from the push notifications logger # Suppress spammy output from the push notifications logger
push_notifications_logger.disabled = True push_notifications_logger.disabled = True
if options["percent_huddles"] + options["percent_personals"] > 100: if options["percent_direct_message_groups"] + options["percent_personals"] > 100:
self.stderr.write("Error! More than 100% of messages allocated.\n") self.stderr.write("Error! More than 100% of messages allocated.\n")
return return
@ -937,8 +937,8 @@ class Command(ZulipBaseCommand):
user_profiles_ids = [user_profile.id for user_profile in user_profiles] user_profiles_ids = [user_profile.id for user_profile in user_profiles]
# Create several initial huddles # Create several initial direct message groups
for i in range(options["num_huddles"]): for i in range(options["num_direct_message_groups"]):
get_or_create_direct_message_group( get_or_create_direct_message_group(
random.sample(user_profiles_ids, random.randint(3, 4)) random.sample(user_profiles_ids, random.randint(3, 4))
) )
@ -1167,7 +1167,7 @@ def get_recipient_by_id(rid: int) -> Recipient:
# Create some test messages, including: # Create some test messages, including:
# - multiple streams # - multiple streams
# - multiple subjects per stream # - multiple subjects per stream
# - multiple huddles # - multiple direct message groups
# - multiple personal conversations # - multiple personal conversations
# - multiple messages per subject # - multiple messages per subject
# - both single and multi-line content # - both single and multi-line content
@ -1193,13 +1193,15 @@ def generate_and_send_messages(
recipient.id recipient.id
for recipient in Recipient.objects.filter(type=Recipient.STREAM, type_id__in=stream_ids) for recipient in Recipient.objects.filter(type=Recipient.STREAM, type_id__in=stream_ids)
] ]
recipient_huddles: list[int] = [ recipient_direct_message_groups: list[int] = [
h.id for h in Recipient.objects.filter(type=Recipient.DIRECT_MESSAGE_GROUP) h.id for h in Recipient.objects.filter(type=Recipient.DIRECT_MESSAGE_GROUP)
] ]
huddle_members: dict[int, list[int]] = {} direct_message_group_members: dict[int, list[int]] = {}
for h in recipient_huddles: for h in recipient_direct_message_groups:
huddle_members[h] = [s.user_profile.id for s in Subscription.objects.filter(recipient_id=h)] direct_message_group_members[h] = [
s.user_profile.id for s in Subscription.objects.filter(recipient_id=h)
]
# Generate different topics for each stream # Generate different topics for each stream
possible_topic_names = {} possible_topic_names = {}
@ -1242,12 +1244,14 @@ def generate_and_send_messages(
message.recipient = get_recipient_by_id(recipient_id) message.recipient = get_recipient_by_id(recipient_id)
elif message_type == Recipient.DIRECT_MESSAGE_GROUP: elif message_type == Recipient.DIRECT_MESSAGE_GROUP:
message.recipient = get_recipient_by_id(recipient_id) message.recipient = get_recipient_by_id(recipient_id)
elif randkey <= random_max * options["percent_huddles"] / 100.0: elif randkey <= random_max * options["percent_direct_message_groups"] / 100.0:
message_type = Recipient.DIRECT_MESSAGE_GROUP message_type = Recipient.DIRECT_MESSAGE_GROUP
message.recipient = get_recipient_by_id(random.choice(recipient_huddles)) message.recipient = get_recipient_by_id(random.choice(recipient_direct_message_groups))
elif ( elif (
randkey randkey
<= random_max * (options["percent_huddles"] + options["percent_personals"]) / 100.0 <= random_max
* (options["percent_direct_message_groups"] + options["percent_personals"])
/ 100.0
): ):
message_type = Recipient.PERSONAL message_type = Recipient.PERSONAL
personals_pair = random.choice(personals_pairs) personals_pair = random.choice(personals_pairs)
@ -1257,7 +1261,7 @@ def generate_and_send_messages(
message.recipient = get_recipient_by_id(random.choice(recipient_streams)) message.recipient = get_recipient_by_id(random.choice(recipient_streams))
if message_type == Recipient.DIRECT_MESSAGE_GROUP: if message_type == Recipient.DIRECT_MESSAGE_GROUP:
sender_id = random.choice(huddle_members[message.recipient.id]) sender_id = random.choice(direct_message_group_members[message.recipient.id])
message.sender = get_user_profile_by_id(sender_id) message.sender = get_user_profile_by_id(sender_id)
elif message_type == Recipient.PERSONAL: elif message_type == Recipient.PERSONAL:
message.recipient = Recipient.objects.get( message.recipient = Recipient.objects.get(