mirror of https://github.com/zulip/zulip.git
actions: Move part into zerver.lib.streams.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
parent
6168c0110a
commit
a29f1b39da
|
@ -379,7 +379,6 @@ python_rules = RuleList(
|
||||||
# This one in check_message is kinda terrible, since it's
|
# This one in check_message is kinda terrible, since it's
|
||||||
# how most instances are written, but better to exclude something than nothing
|
# how most instances are written, but better to exclude something than nothing
|
||||||
("zerver/lib/actions.py", "stream = get_stream(stream_name, realm)"),
|
("zerver/lib/actions.py", "stream = get_stream(stream_name, realm)"),
|
||||||
("zerver/lib/actions.py", 'return get_stream("signups", realm)'),
|
|
||||||
},
|
},
|
||||||
"description": "Please use access_stream_by_*() to fetch Stream objects",
|
"description": "Please use access_stream_by_*() to fetch Stream objects",
|
||||||
},
|
},
|
||||||
|
|
|
@ -26,7 +26,7 @@ import orjson
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
from django.db import IntegrityError, connection, transaction
|
from django.db import IntegrityError, connection, transaction
|
||||||
from django.db.models import Exists, F, OuterRef, Q
|
from django.db.models import F
|
||||||
from django.db.models.query import QuerySet
|
from django.db.models.query import QuerySet
|
||||||
from django.utils.html import escape
|
from django.utils.html import escape
|
||||||
from django.utils.timezone import now as timezone_now
|
from django.utils.timezone import now as timezone_now
|
||||||
|
@ -125,7 +125,6 @@ from zerver.lib.stream_subscription import (
|
||||||
get_active_subscriptions_for_stream_id,
|
get_active_subscriptions_for_stream_id,
|
||||||
get_bulk_stream_subscriber_info,
|
get_bulk_stream_subscriber_info,
|
||||||
get_stream_subscriptions_for_user,
|
get_stream_subscriptions_for_user,
|
||||||
get_subscribed_stream_ids_for_user,
|
|
||||||
get_subscriptions_for_send_message,
|
get_subscriptions_for_send_message,
|
||||||
get_used_colors_for_user_ids,
|
get_used_colors_for_user_ids,
|
||||||
num_subscribers_for_stream_id,
|
num_subscribers_for_stream_id,
|
||||||
|
@ -138,10 +137,11 @@ from zerver.lib.streams import (
|
||||||
access_stream_for_send_message,
|
access_stream_for_send_message,
|
||||||
can_access_stream_user_ids,
|
can_access_stream_user_ids,
|
||||||
check_stream_access_based_on_stream_post_policy,
|
check_stream_access_based_on_stream_post_policy,
|
||||||
create_stream_if_needed,
|
ensure_stream,
|
||||||
get_default_value_for_history_public_to_subscribers,
|
get_default_value_for_history_public_to_subscribers,
|
||||||
|
get_occupied_streams,
|
||||||
|
get_signups_stream,
|
||||||
get_stream_permission_policy_name,
|
get_stream_permission_policy_name,
|
||||||
get_web_public_streams_queryset,
|
|
||||||
render_stream_description,
|
render_stream_description,
|
||||||
send_stream_creation_event,
|
send_stream_creation_event,
|
||||||
subscribed_to_stream,
|
subscribed_to_stream,
|
||||||
|
@ -279,11 +279,6 @@ def subscriber_info(user_id: int) -> Dict[str, Any]:
|
||||||
return {"id": user_id, "flags": ["read"]}
|
return {"id": user_id, "flags": ["read"]}
|
||||||
|
|
||||||
|
|
||||||
def get_signups_stream(realm: Realm) -> Stream:
|
|
||||||
# This one-liner helps us work around a lint rule.
|
|
||||||
return get_stream("signups", realm)
|
|
||||||
|
|
||||||
|
|
||||||
def send_message_to_signup_notification_stream(
|
def send_message_to_signup_notification_stream(
|
||||||
sender: UserProfile, realm: Realm, message: str, topic_name: str = _("signups")
|
sender: UserProfile, realm: Realm, message: str, topic_name: str = _("signups")
|
||||||
) -> None:
|
) -> None:
|
||||||
|
@ -2442,23 +2437,6 @@ def do_remove_reaction(
|
||||||
notify_reaction_update(user_profile, message, reaction, "remove")
|
notify_reaction_update(user_profile, message, reaction, "remove")
|
||||||
|
|
||||||
|
|
||||||
def ensure_stream(
|
|
||||||
realm: Realm,
|
|
||||||
stream_name: str,
|
|
||||||
invite_only: bool = False,
|
|
||||||
stream_description: str = "",
|
|
||||||
*,
|
|
||||||
acting_user: Optional[UserProfile],
|
|
||||||
) -> Stream:
|
|
||||||
return create_stream_if_needed(
|
|
||||||
realm,
|
|
||||||
stream_name,
|
|
||||||
invite_only=invite_only,
|
|
||||||
stream_description=stream_description,
|
|
||||||
acting_user=acting_user,
|
|
||||||
)[0]
|
|
||||||
|
|
||||||
|
|
||||||
def already_sent_mirrored_message_id(message: Message) -> Optional[int]:
|
def already_sent_mirrored_message_id(message: Message) -> Optional[int]:
|
||||||
if message.recipient.type == Recipient.HUDDLE:
|
if message.recipient.type == Recipient.HUDDLE:
|
||||||
# For huddle messages, we use a 10-second window because the
|
# For huddle messages, we use a 10-second window because the
|
||||||
|
@ -7015,107 +6993,6 @@ def do_remove_realm_domain(
|
||||||
transaction.on_commit(lambda: send_event(realm, event, active_user_ids(realm.id)))
|
transaction.on_commit(lambda: send_event(realm, event, active_user_ids(realm.id)))
|
||||||
|
|
||||||
|
|
||||||
def get_occupied_streams(realm: Realm) -> QuerySet:
|
|
||||||
# TODO: Make a generic stub for QuerySet
|
|
||||||
"""Get streams with subscribers"""
|
|
||||||
exists_expression = Exists(
|
|
||||||
Subscription.objects.filter(
|
|
||||||
active=True,
|
|
||||||
is_user_active=True,
|
|
||||||
user_profile__realm=realm,
|
|
||||||
recipient_id=OuterRef("recipient_id"),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
occupied_streams = (
|
|
||||||
Stream.objects.filter(realm=realm, deactivated=False)
|
|
||||||
.annotate(occupied=exists_expression)
|
|
||||||
.filter(occupied=True)
|
|
||||||
)
|
|
||||||
return occupied_streams
|
|
||||||
|
|
||||||
|
|
||||||
def get_web_public_streams(realm: Realm) -> List[Dict[str, Any]]: # nocoverage
|
|
||||||
query = get_web_public_streams_queryset(realm)
|
|
||||||
streams = Stream.get_client_data(query)
|
|
||||||
return streams
|
|
||||||
|
|
||||||
|
|
||||||
def do_get_streams(
|
|
||||||
user_profile: UserProfile,
|
|
||||||
include_public: bool = True,
|
|
||||||
include_web_public: bool = False,
|
|
||||||
include_subscribed: bool = True,
|
|
||||||
include_all_active: bool = False,
|
|
||||||
include_default: bool = False,
|
|
||||||
include_owner_subscribed: bool = False,
|
|
||||||
) -> List[Dict[str, Any]]:
|
|
||||||
# This function is only used by API clients now.
|
|
||||||
|
|
||||||
if include_all_active and not user_profile.is_realm_admin:
|
|
||||||
raise JsonableError(_("User not authorized for this query"))
|
|
||||||
|
|
||||||
include_public = include_public and user_profile.can_access_public_streams()
|
|
||||||
|
|
||||||
# Start out with all active streams in the realm.
|
|
||||||
query = Stream.objects.filter(realm=user_profile.realm, deactivated=False)
|
|
||||||
|
|
||||||
if include_all_active:
|
|
||||||
streams = Stream.get_client_data(query)
|
|
||||||
else:
|
|
||||||
# We construct a query as the or (|) of the various sources
|
|
||||||
# this user requested streams from.
|
|
||||||
query_filter: Optional[Q] = None
|
|
||||||
|
|
||||||
def add_filter_option(option: Q) -> None:
|
|
||||||
nonlocal query_filter
|
|
||||||
if query_filter is None:
|
|
||||||
query_filter = option
|
|
||||||
else:
|
|
||||||
query_filter |= option
|
|
||||||
|
|
||||||
if include_subscribed:
|
|
||||||
subscribed_stream_ids = get_subscribed_stream_ids_for_user(user_profile)
|
|
||||||
recipient_check = Q(id__in=set(subscribed_stream_ids))
|
|
||||||
add_filter_option(recipient_check)
|
|
||||||
if include_public:
|
|
||||||
invite_only_check = Q(invite_only=False)
|
|
||||||
add_filter_option(invite_only_check)
|
|
||||||
if include_web_public:
|
|
||||||
# This should match get_web_public_streams_queryset
|
|
||||||
web_public_check = Q(
|
|
||||||
is_web_public=True,
|
|
||||||
invite_only=False,
|
|
||||||
history_public_to_subscribers=True,
|
|
||||||
deactivated=False,
|
|
||||||
)
|
|
||||||
add_filter_option(web_public_check)
|
|
||||||
if include_owner_subscribed and user_profile.is_bot:
|
|
||||||
bot_owner = user_profile.bot_owner
|
|
||||||
assert bot_owner is not None
|
|
||||||
owner_stream_ids = get_subscribed_stream_ids_for_user(bot_owner)
|
|
||||||
owner_subscribed_check = Q(id__in=set(owner_stream_ids))
|
|
||||||
add_filter_option(owner_subscribed_check)
|
|
||||||
|
|
||||||
if query_filter is not None:
|
|
||||||
query = query.filter(query_filter)
|
|
||||||
streams = Stream.get_client_data(query)
|
|
||||||
else:
|
|
||||||
# Don't bother going to the database with no valid sources
|
|
||||||
streams = []
|
|
||||||
|
|
||||||
streams.sort(key=lambda elt: elt["name"])
|
|
||||||
|
|
||||||
if include_default:
|
|
||||||
is_default = {}
|
|
||||||
default_streams = get_default_streams_for_realm(user_profile.realm_id)
|
|
||||||
for default_stream in default_streams:
|
|
||||||
is_default[default_stream.id] = True
|
|
||||||
for stream in streams:
|
|
||||||
stream["is_default"] = is_default.get(stream["stream_id"], False)
|
|
||||||
|
|
||||||
return streams
|
|
||||||
|
|
||||||
|
|
||||||
def notify_attachment_update(
|
def notify_attachment_update(
|
||||||
user_profile: UserProfile, op: str, attachment_dict: Dict[str, Any]
|
user_profile: UserProfile, op: str, attachment_dict: Dict[str, Any]
|
||||||
) -> None:
|
) -> None:
|
||||||
|
|
|
@ -13,12 +13,7 @@ from zerver.actions.default_streams import (
|
||||||
get_default_streams_for_realm,
|
get_default_streams_for_realm,
|
||||||
streams_to_dicts_sorted,
|
streams_to_dicts_sorted,
|
||||||
)
|
)
|
||||||
from zerver.lib.actions import (
|
from zerver.lib.actions import gather_subscriptions_helper, get_owned_bot_dicts
|
||||||
do_get_streams,
|
|
||||||
gather_subscriptions_helper,
|
|
||||||
get_owned_bot_dicts,
|
|
||||||
get_web_public_streams,
|
|
||||||
)
|
|
||||||
from zerver.lib.alert_words import user_alert_words
|
from zerver.lib.alert_words import user_alert_words
|
||||||
from zerver.lib.avatar import avatar_url
|
from zerver.lib.avatar import avatar_url
|
||||||
from zerver.lib.bot_config import load_bot_config_template
|
from zerver.lib.bot_config import load_bot_config_template
|
||||||
|
@ -46,6 +41,7 @@ from zerver.lib.realm_logo import get_realm_logo_source, get_realm_logo_url
|
||||||
from zerver.lib.soft_deactivation import reactivate_user_if_soft_deactivated
|
from zerver.lib.soft_deactivation import reactivate_user_if_soft_deactivated
|
||||||
from zerver.lib.sounds import get_available_notification_sounds
|
from zerver.lib.sounds import get_available_notification_sounds
|
||||||
from zerver.lib.stream_subscription import handle_stream_notifications_compatibility
|
from zerver.lib.stream_subscription import handle_stream_notifications_compatibility
|
||||||
|
from zerver.lib.streams import do_get_streams, get_web_public_streams
|
||||||
from zerver.lib.subscription_info import get_web_public_subs
|
from zerver.lib.subscription_info import get_web_public_subs
|
||||||
from zerver.lib.timestamp import datetime_to_timestamp
|
from zerver.lib.timestamp import datetime_to_timestamp
|
||||||
from zerver.lib.timezone import canonicalize_timezone
|
from zerver.lib.timezone import canonicalize_timezone
|
||||||
|
|
|
@ -1,18 +1,23 @@
|
||||||
from typing import Collection, List, Optional, Set, Tuple, Union
|
from typing import Any, Collection, Dict, List, Optional, Set, Tuple, Union
|
||||||
|
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
|
from django.db.models import Exists, OuterRef, Q
|
||||||
from django.db.models.query import QuerySet
|
from django.db.models.query import QuerySet
|
||||||
from django.utils.timezone import now as timezone_now
|
from django.utils.timezone import now as timezone_now
|
||||||
from django.utils.translation import gettext as _
|
from django.utils.translation import gettext as _
|
||||||
from typing_extensions import TypedDict
|
from typing_extensions import TypedDict
|
||||||
|
|
||||||
|
from zerver.actions.default_streams import get_default_streams_for_realm
|
||||||
from zerver.lib.exceptions import (
|
from zerver.lib.exceptions import (
|
||||||
JsonableError,
|
JsonableError,
|
||||||
OrganizationOwnerRequired,
|
OrganizationOwnerRequired,
|
||||||
StreamAdministratorRequired,
|
StreamAdministratorRequired,
|
||||||
)
|
)
|
||||||
from zerver.lib.markdown import markdown_convert
|
from zerver.lib.markdown import markdown_convert
|
||||||
from zerver.lib.stream_subscription import get_active_subscriptions_for_stream_id
|
from zerver.lib.stream_subscription import (
|
||||||
|
get_active_subscriptions_for_stream_id,
|
||||||
|
get_subscribed_stream_ids_for_user,
|
||||||
|
)
|
||||||
from zerver.lib.string_validation import check_stream_name
|
from zerver.lib.string_validation import check_stream_name
|
||||||
from zerver.models import (
|
from zerver.models import (
|
||||||
DefaultStreamGroup,
|
DefaultStreamGroup,
|
||||||
|
@ -738,3 +743,126 @@ def get_stream_by_narrow_operand_access_unchecked(operand: Union[str, int], real
|
||||||
if isinstance(operand, str):
|
if isinstance(operand, str):
|
||||||
return get_stream(operand, realm)
|
return get_stream(operand, realm)
|
||||||
return get_stream_by_id_in_realm(operand, realm)
|
return get_stream_by_id_in_realm(operand, realm)
|
||||||
|
|
||||||
|
|
||||||
|
def get_signups_stream(realm: Realm) -> Stream:
|
||||||
|
# This one-liner helps us work around a lint rule.
|
||||||
|
return get_stream("signups", realm)
|
||||||
|
|
||||||
|
|
||||||
|
def ensure_stream(
|
||||||
|
realm: Realm,
|
||||||
|
stream_name: str,
|
||||||
|
invite_only: bool = False,
|
||||||
|
stream_description: str = "",
|
||||||
|
*,
|
||||||
|
acting_user: Optional[UserProfile],
|
||||||
|
) -> Stream:
|
||||||
|
return create_stream_if_needed(
|
||||||
|
realm,
|
||||||
|
stream_name,
|
||||||
|
invite_only=invite_only,
|
||||||
|
stream_description=stream_description,
|
||||||
|
acting_user=acting_user,
|
||||||
|
)[0]
|
||||||
|
|
||||||
|
|
||||||
|
def get_occupied_streams(realm: Realm) -> QuerySet:
|
||||||
|
# TODO: Make a generic stub for QuerySet
|
||||||
|
"""Get streams with subscribers"""
|
||||||
|
exists_expression = Exists(
|
||||||
|
Subscription.objects.filter(
|
||||||
|
active=True,
|
||||||
|
is_user_active=True,
|
||||||
|
user_profile__realm=realm,
|
||||||
|
recipient_id=OuterRef("recipient_id"),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
occupied_streams = (
|
||||||
|
Stream.objects.filter(realm=realm, deactivated=False)
|
||||||
|
.annotate(occupied=exists_expression)
|
||||||
|
.filter(occupied=True)
|
||||||
|
)
|
||||||
|
return occupied_streams
|
||||||
|
|
||||||
|
|
||||||
|
def get_web_public_streams(realm: Realm) -> List[Dict[str, Any]]: # nocoverage
|
||||||
|
query = get_web_public_streams_queryset(realm)
|
||||||
|
streams = Stream.get_client_data(query)
|
||||||
|
return streams
|
||||||
|
|
||||||
|
|
||||||
|
def do_get_streams(
|
||||||
|
user_profile: UserProfile,
|
||||||
|
include_public: bool = True,
|
||||||
|
include_web_public: bool = False,
|
||||||
|
include_subscribed: bool = True,
|
||||||
|
include_all_active: bool = False,
|
||||||
|
include_default: bool = False,
|
||||||
|
include_owner_subscribed: bool = False,
|
||||||
|
) -> List[Dict[str, Any]]:
|
||||||
|
# This function is only used by API clients now.
|
||||||
|
|
||||||
|
if include_all_active and not user_profile.is_realm_admin:
|
||||||
|
raise JsonableError(_("User not authorized for this query"))
|
||||||
|
|
||||||
|
include_public = include_public and user_profile.can_access_public_streams()
|
||||||
|
|
||||||
|
# Start out with all active streams in the realm.
|
||||||
|
query = Stream.objects.filter(realm=user_profile.realm, deactivated=False)
|
||||||
|
|
||||||
|
if include_all_active:
|
||||||
|
streams = Stream.get_client_data(query)
|
||||||
|
else:
|
||||||
|
# We construct a query as the or (|) of the various sources
|
||||||
|
# this user requested streams from.
|
||||||
|
query_filter: Optional[Q] = None
|
||||||
|
|
||||||
|
def add_filter_option(option: Q) -> None:
|
||||||
|
nonlocal query_filter
|
||||||
|
if query_filter is None:
|
||||||
|
query_filter = option
|
||||||
|
else:
|
||||||
|
query_filter |= option
|
||||||
|
|
||||||
|
if include_subscribed:
|
||||||
|
subscribed_stream_ids = get_subscribed_stream_ids_for_user(user_profile)
|
||||||
|
recipient_check = Q(id__in=set(subscribed_stream_ids))
|
||||||
|
add_filter_option(recipient_check)
|
||||||
|
if include_public:
|
||||||
|
invite_only_check = Q(invite_only=False)
|
||||||
|
add_filter_option(invite_only_check)
|
||||||
|
if include_web_public:
|
||||||
|
# This should match get_web_public_streams_queryset
|
||||||
|
web_public_check = Q(
|
||||||
|
is_web_public=True,
|
||||||
|
invite_only=False,
|
||||||
|
history_public_to_subscribers=True,
|
||||||
|
deactivated=False,
|
||||||
|
)
|
||||||
|
add_filter_option(web_public_check)
|
||||||
|
if include_owner_subscribed and user_profile.is_bot:
|
||||||
|
bot_owner = user_profile.bot_owner
|
||||||
|
assert bot_owner is not None
|
||||||
|
owner_stream_ids = get_subscribed_stream_ids_for_user(bot_owner)
|
||||||
|
owner_subscribed_check = Q(id__in=set(owner_stream_ids))
|
||||||
|
add_filter_option(owner_subscribed_check)
|
||||||
|
|
||||||
|
if query_filter is not None:
|
||||||
|
query = query.filter(query_filter)
|
||||||
|
streams = Stream.get_client_data(query)
|
||||||
|
else:
|
||||||
|
# Don't bother going to the database with no valid sources
|
||||||
|
streams = []
|
||||||
|
|
||||||
|
streams.sort(key=lambda elt: elt["name"])
|
||||||
|
|
||||||
|
if include_default:
|
||||||
|
is_default = {}
|
||||||
|
default_streams = get_default_streams_for_realm(user_profile.realm_id)
|
||||||
|
for default_stream in default_streams:
|
||||||
|
is_default[default_stream.id] = True
|
||||||
|
for stream in streams:
|
||||||
|
stream["is_default"] = is_default.get(stream["stream_id"], False)
|
||||||
|
|
||||||
|
return streams
|
||||||
|
|
|
@ -2,8 +2,9 @@ from typing import Any
|
||||||
|
|
||||||
from django.core.management.base import CommandParser
|
from django.core.management.base import CommandParser
|
||||||
|
|
||||||
from zerver.lib.actions import bulk_add_subscriptions, ensure_stream
|
from zerver.lib.actions import bulk_add_subscriptions
|
||||||
from zerver.lib.management import ZulipBaseCommand
|
from zerver.lib.management import ZulipBaseCommand
|
||||||
|
from zerver.lib.streams import ensure_stream
|
||||||
|
|
||||||
|
|
||||||
class Command(ZulipBaseCommand):
|
class Command(ZulipBaseCommand):
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
from argparse import ArgumentParser
|
from argparse import ArgumentParser
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from zerver.lib.actions import ensure_stream
|
|
||||||
from zerver.lib.management import ZulipBaseCommand
|
from zerver.lib.management import ZulipBaseCommand
|
||||||
|
from zerver.lib.streams import ensure_stream
|
||||||
from zerver.models import DefaultStreamGroup
|
from zerver.models import DefaultStreamGroup
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,6 @@ from zerver.lib.actions import (
|
||||||
do_reactivate_realm,
|
do_reactivate_realm,
|
||||||
do_reactivate_user,
|
do_reactivate_user,
|
||||||
do_set_realm_property,
|
do_set_realm_property,
|
||||||
ensure_stream,
|
|
||||||
)
|
)
|
||||||
from zerver.lib.avatar import avatar_url
|
from zerver.lib.avatar import avatar_url
|
||||||
from zerver.lib.avatar_hash import user_avatar_path
|
from zerver.lib.avatar_hash import user_avatar_path
|
||||||
|
@ -66,6 +65,7 @@ from zerver.lib.initial_password import initial_password
|
||||||
from zerver.lib.mobile_auth_otp import otp_decrypt_api_key
|
from zerver.lib.mobile_auth_otp import otp_decrypt_api_key
|
||||||
from zerver.lib.rate_limiter import add_ratelimit_rule, remove_ratelimit_rule
|
from zerver.lib.rate_limiter import add_ratelimit_rule, remove_ratelimit_rule
|
||||||
from zerver.lib.storage import static_path
|
from zerver.lib.storage import static_path
|
||||||
|
from zerver.lib.streams import ensure_stream
|
||||||
from zerver.lib.test_classes import ZulipTestCase
|
from zerver.lib.test_classes import ZulipTestCase
|
||||||
from zerver.lib.test_helpers import (
|
from zerver.lib.test_helpers import (
|
||||||
create_s3_buckets,
|
create_s3_buckets,
|
||||||
|
|
|
@ -11,12 +11,7 @@ import orjson
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.http import HttpResponse
|
from django.http import HttpResponse
|
||||||
|
|
||||||
from zerver.lib.actions import (
|
from zerver.lib.actions import do_change_stream_post_policy, do_deactivate_realm, do_deactivate_user
|
||||||
do_change_stream_post_policy,
|
|
||||||
do_deactivate_realm,
|
|
||||||
do_deactivate_user,
|
|
||||||
ensure_stream,
|
|
||||||
)
|
|
||||||
from zerver.lib.email_mirror import (
|
from zerver.lib.email_mirror import (
|
||||||
create_missed_message_address,
|
create_missed_message_address,
|
||||||
filter_footer,
|
filter_footer,
|
||||||
|
@ -37,6 +32,7 @@ from zerver.lib.email_mirror_helpers import (
|
||||||
)
|
)
|
||||||
from zerver.lib.email_notifications import convert_html_to_markdown
|
from zerver.lib.email_notifications import convert_html_to_markdown
|
||||||
from zerver.lib.send_email import FromAddress
|
from zerver.lib.send_email import FromAddress
|
||||||
|
from zerver.lib.streams import ensure_stream
|
||||||
from zerver.lib.test_classes import ZulipTestCase
|
from zerver.lib.test_classes import ZulipTestCase
|
||||||
from zerver.lib.test_helpers import mock_queue_publish, most_recent_message, most_recent_usermessage
|
from zerver.lib.test_helpers import mock_queue_publish, most_recent_message, most_recent_usermessage
|
||||||
from zerver.models import (
|
from zerver.models import (
|
||||||
|
|
|
@ -34,9 +34,7 @@ from zerver.lib.actions import (
|
||||||
do_create_realm,
|
do_create_realm,
|
||||||
do_deactivate_stream,
|
do_deactivate_stream,
|
||||||
do_deactivate_user,
|
do_deactivate_user,
|
||||||
do_get_streams,
|
|
||||||
do_set_realm_property,
|
do_set_realm_property,
|
||||||
ensure_stream,
|
|
||||||
gather_subscriptions,
|
gather_subscriptions,
|
||||||
gather_subscriptions_helper,
|
gather_subscriptions_helper,
|
||||||
get_topic_messages,
|
get_topic_messages,
|
||||||
|
@ -63,6 +61,8 @@ from zerver.lib.streams import (
|
||||||
can_access_stream_user_ids,
|
can_access_stream_user_ids,
|
||||||
create_stream_if_needed,
|
create_stream_if_needed,
|
||||||
create_streams_if_needed,
|
create_streams_if_needed,
|
||||||
|
do_get_streams,
|
||||||
|
ensure_stream,
|
||||||
filter_stream_authorization,
|
filter_stream_authorization,
|
||||||
list_to_streams,
|
list_to_streams,
|
||||||
)
|
)
|
||||||
|
|
|
@ -6,7 +6,8 @@ import orjson
|
||||||
from django.utils.timezone import now as timezone_now
|
from django.utils.timezone import now as timezone_now
|
||||||
|
|
||||||
from zerver.actions.user_groups import promote_new_full_members
|
from zerver.actions.user_groups import promote_new_full_members
|
||||||
from zerver.lib.actions import do_set_realm_property, ensure_stream
|
from zerver.lib.actions import do_set_realm_property
|
||||||
|
from zerver.lib.streams import ensure_stream
|
||||||
from zerver.lib.test_classes import ZulipTestCase
|
from zerver.lib.test_classes import ZulipTestCase
|
||||||
from zerver.lib.test_helpers import most_recent_usermessage
|
from zerver.lib.test_helpers import most_recent_usermessage
|
||||||
from zerver.lib.user_groups import (
|
from zerver.lib.user_groups import (
|
||||||
|
|
|
@ -38,7 +38,6 @@ from zerver.lib.actions import (
|
||||||
do_change_subscription_property,
|
do_change_subscription_property,
|
||||||
do_deactivate_stream,
|
do_deactivate_stream,
|
||||||
do_delete_messages,
|
do_delete_messages,
|
||||||
do_get_streams,
|
|
||||||
do_rename_stream,
|
do_rename_stream,
|
||||||
do_send_messages,
|
do_send_messages,
|
||||||
gather_subscriptions,
|
gather_subscriptions,
|
||||||
|
@ -64,6 +63,7 @@ from zerver.lib.streams import (
|
||||||
access_stream_for_delete_or_update,
|
access_stream_for_delete_or_update,
|
||||||
access_web_public_stream,
|
access_web_public_stream,
|
||||||
check_stream_name_available,
|
check_stream_name_available,
|
||||||
|
do_get_streams,
|
||||||
filter_stream_authorization,
|
filter_stream_authorization,
|
||||||
get_stream_permission_policy_name,
|
get_stream_permission_policy_name,
|
||||||
list_to_streams,
|
list_to_streams,
|
||||||
|
|
|
@ -8,10 +8,10 @@ from zerver.lib.actions import (
|
||||||
do_change_avatar_fields,
|
do_change_avatar_fields,
|
||||||
do_create_user,
|
do_create_user,
|
||||||
do_send_messages,
|
do_send_messages,
|
||||||
ensure_stream,
|
|
||||||
internal_prep_stream_message,
|
internal_prep_stream_message,
|
||||||
)
|
)
|
||||||
from zerver.lib.emoji import emoji_name_to_emoji_code
|
from zerver.lib.emoji import emoji_name_to_emoji_code
|
||||||
|
from zerver.lib.streams import ensure_stream
|
||||||
from zerver.lib.upload import upload_avatar_image
|
from zerver.lib.upload import upload_avatar_image
|
||||||
from zerver.models import Message, UserProfile, get_realm
|
from zerver.models import Message, UserProfile, get_realm
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue