diff --git a/zerver/lib/subscription_info.py b/zerver/lib/subscription_info.py index c21290b868..f704608c7f 100644 --- a/zerver/lib/subscription_info.py +++ b/zerver/lib/subscription_info.py @@ -17,7 +17,7 @@ from zerver.lib.stream_subscription import ( ) from zerver.lib.stream_traffic import get_average_weekly_stream_traffic, get_streams_traffic from zerver.lib.streams import get_web_public_streams_queryset, subscribed_to_stream -from zerver.lib.timestamp import datetime_to_timestamp, timestamp_to_datetime +from zerver.lib.timestamp import datetime_to_timestamp from zerver.lib.types import ( APIStreamDict, NeverSubscribedStreamDict, @@ -112,55 +112,69 @@ def get_web_public_subs(realm: Realm) -> SubscriptionInfo: def build_unsubscribed_sub_from_stream_dict( user: UserProfile, sub_dict: RawSubscriptionDict, stream_dict: APIStreamDict ) -> SubscriptionStreamDict: - # This function is only called from `apply_event` code. - raw_stream_dict = RawStreamDict( - can_remove_subscribers_group_id=stream_dict["can_remove_subscribers_group"], - creator_id=stream_dict["creator_id"], - date_created=timestamp_to_datetime(stream_dict["date_created"]), - deactivated=stream_dict["is_archived"], - description=stream_dict["description"], - first_message_id=stream_dict["first_message_id"], - history_public_to_subscribers=stream_dict["history_public_to_subscribers"], - invite_only=stream_dict["invite_only"], - is_web_public=stream_dict["is_web_public"], - message_retention_days=stream_dict["message_retention_days"], - name=stream_dict["name"], - rendered_description=stream_dict["rendered_description"], - id=stream_dict["stream_id"], - stream_post_policy=stream_dict["stream_post_policy"], - ) - - # We pass recent_traffic as None and avoid extra database query since we - # already have the traffic data from stream_dict sent with creation event. - subscription_stream_dict = build_stream_dict_for_sub( - user, sub_dict, raw_stream_dict, recent_traffic=None - ) - subscription_stream_dict["stream_weekly_traffic"] = stream_dict["stream_weekly_traffic"] + subscription_stream_dict = build_stream_dict_for_sub(user, sub_dict, stream_dict) return subscription_stream_dict +def build_stream_api_dict( + raw_stream_dict: RawStreamDict, recent_traffic: dict[int, int] | None +) -> APIStreamDict: + # Add a few computed fields not directly from the data models. + if recent_traffic is not None: + stream_weekly_traffic = get_average_weekly_stream_traffic( + raw_stream_dict["id"], raw_stream_dict["date_created"], recent_traffic + ) + else: + stream_weekly_traffic = None + + # Backwards-compatibility for clients that haven't been + # updated for the is_announcement_only -> stream_post_policy + # migration. + is_announcement_only = raw_stream_dict["stream_post_policy"] == Stream.STREAM_POST_POLICY_ADMINS + + return APIStreamDict( + is_archived=raw_stream_dict["deactivated"], + can_remove_subscribers_group=raw_stream_dict["can_remove_subscribers_group_id"], + creator_id=raw_stream_dict["creator_id"], + date_created=datetime_to_timestamp(raw_stream_dict["date_created"]), + description=raw_stream_dict["description"], + first_message_id=raw_stream_dict["first_message_id"], + history_public_to_subscribers=raw_stream_dict["history_public_to_subscribers"], + invite_only=raw_stream_dict["invite_only"], + is_web_public=raw_stream_dict["is_web_public"], + message_retention_days=raw_stream_dict["message_retention_days"], + name=raw_stream_dict["name"], + rendered_description=raw_stream_dict["rendered_description"], + stream_id=raw_stream_dict["id"], + stream_post_policy=raw_stream_dict["stream_post_policy"], + stream_weekly_traffic=stream_weekly_traffic, + is_announcement_only=is_announcement_only, + ) + + def build_stream_dict_for_sub( user: UserProfile, sub_dict: RawSubscriptionDict, - raw_stream_dict: RawStreamDict, - recent_traffic: dict[int, int] | None, + stream_dict: APIStreamDict, ) -> SubscriptionStreamDict: # Handle Stream.API_FIELDS - is_archived = raw_stream_dict["deactivated"] - can_remove_subscribers_group_id = raw_stream_dict["can_remove_subscribers_group_id"] - creator_id = raw_stream_dict["creator_id"] - date_created = datetime_to_timestamp(raw_stream_dict["date_created"]) - description = raw_stream_dict["description"] - first_message_id = raw_stream_dict["first_message_id"] - history_public_to_subscribers = raw_stream_dict["history_public_to_subscribers"] - invite_only = raw_stream_dict["invite_only"] - is_web_public = raw_stream_dict["is_web_public"] - message_retention_days = raw_stream_dict["message_retention_days"] - name = raw_stream_dict["name"] - rendered_description = raw_stream_dict["rendered_description"] - stream_id = raw_stream_dict["id"] - stream_post_policy = raw_stream_dict["stream_post_policy"] + is_archived = stream_dict["is_archived"] + can_remove_subscribers_group = stream_dict["can_remove_subscribers_group"] + creator_id = stream_dict["creator_id"] + date_created = stream_dict["date_created"] + description = stream_dict["description"] + first_message_id = stream_dict["first_message_id"] + history_public_to_subscribers = stream_dict["history_public_to_subscribers"] + invite_only = stream_dict["invite_only"] + is_web_public = stream_dict["is_web_public"] + message_retention_days = stream_dict["message_retention_days"] + name = stream_dict["name"] + rendered_description = stream_dict["rendered_description"] + stream_id = stream_dict["stream_id"] + stream_post_policy = stream_dict["stream_post_policy"] + stream_weekly_traffic = stream_dict["stream_weekly_traffic"] + is_announcement_only = stream_dict["is_announcement_only"] # Handle Subscription.API_FIELDS. color = sub_dict["color"] @@ -176,24 +190,11 @@ def build_stream_dict_for_sub( # updated for the in_home_view => is_muted API migration. in_home_view = not is_muted - # Backwards-compatibility for clients that haven't been - # updated for the is_announcement_only -> stream_post_policy - # migration. - is_announcement_only = raw_stream_dict["stream_post_policy"] == Stream.STREAM_POST_POLICY_ADMINS - - # Add a few computed fields not directly from the data models. - if recent_traffic is not None: - stream_weekly_traffic = get_average_weekly_stream_traffic( - raw_stream_dict["id"], raw_stream_dict["date_created"], recent_traffic - ) - else: - stream_weekly_traffic = None - # Our caller may add a subscribers field. return SubscriptionStreamDict( is_archived=is_archived, audible_notifications=audible_notifications, - can_remove_subscribers_group=can_remove_subscribers_group_id, + can_remove_subscribers_group=can_remove_subscribers_group, color=color, creator_id=creator_id, date_created=date_created, @@ -504,11 +505,11 @@ def gather_subscriptions_helper( stream_id = get_stream_id(sub_dict) sub_unsub_stream_ids.add(stream_id) raw_stream_dict = all_streams_map[stream_id] + stream_api_dict = build_stream_api_dict(raw_stream_dict, recent_traffic) stream_dict = build_stream_dict_for_sub( user=user_profile, sub_dict=sub_dict, - raw_stream_dict=raw_stream_dict, - recent_traffic=recent_traffic, + stream_dict=stream_api_dict, ) # is_active is represented in this structure by which list we include it in.