mirror of
https://github.com/zulip/zulip.git
synced 2025-11-03 21:43:21 +00:00
channel_folder: Add API to create a channel folder.
This commit also includes code to include channel_folders data in register response. Fixes part of #31972.
This commit is contained in:
60
zerver/lib/channel_folders.py
Normal file
60
zerver/lib/channel_folders.py
Normal file
@@ -0,0 +1,60 @@
|
||||
from typing import TypedDict
|
||||
|
||||
from django.utils.translation import gettext as _
|
||||
|
||||
from zerver.lib.exceptions import JsonableError
|
||||
from zerver.lib.markdown import markdown_convert
|
||||
from zerver.lib.string_validation import check_string_is_printable
|
||||
from zerver.lib.timestamp import datetime_to_timestamp
|
||||
from zerver.models import ChannelFolder, Realm, UserProfile
|
||||
|
||||
|
||||
class ChannelFolderDict(TypedDict):
|
||||
id: int
|
||||
name: str
|
||||
description: str
|
||||
rendered_description: str
|
||||
creator_id: int | None
|
||||
date_created: int
|
||||
is_archived: bool
|
||||
|
||||
|
||||
def check_channel_folder_name(name: str, realm: Realm) -> None:
|
||||
if name.strip() == "":
|
||||
raise JsonableError(_("Channel folder name can't be empty."))
|
||||
|
||||
invalid_character_pos = check_string_is_printable(name)
|
||||
if invalid_character_pos is not None:
|
||||
raise JsonableError(
|
||||
_("Invalid character in channel folder name, at position {position}.").format(
|
||||
position=invalid_character_pos
|
||||
)
|
||||
)
|
||||
|
||||
if ChannelFolder.objects.filter(name__iexact=name, realm=realm).exists():
|
||||
raise JsonableError(_("Channel folder '{name}' already exists").format(name=name))
|
||||
|
||||
|
||||
def render_channel_folder_description(text: str, realm: Realm, *, acting_user: UserProfile) -> str:
|
||||
return markdown_convert(
|
||||
text, message_realm=realm, no_previews=True, acting_user=acting_user
|
||||
).rendered_content
|
||||
|
||||
|
||||
def get_channel_folder_dict(channel_folder: ChannelFolder) -> ChannelFolderDict:
|
||||
date_created = datetime_to_timestamp(channel_folder.date_created)
|
||||
return ChannelFolderDict(
|
||||
id=channel_folder.id,
|
||||
name=channel_folder.name,
|
||||
description=channel_folder.description,
|
||||
rendered_description=channel_folder.rendered_description,
|
||||
date_created=date_created,
|
||||
creator_id=channel_folder.creator_id,
|
||||
is_archived=channel_folder.is_archived,
|
||||
)
|
||||
|
||||
|
||||
def get_channel_folders_in_realm(realm: Realm) -> list[ChannelFolderDict]:
|
||||
folders = ChannelFolder.objects.filter(realm=realm)
|
||||
channel_folders = [get_channel_folder_dict(channel_folder) for channel_folder in folders]
|
||||
return sorted(channel_folders, key=lambda folder: folder["id"])
|
||||
@@ -23,6 +23,7 @@ from zerver.lib.event_types import (
|
||||
EventAttachmentAdd,
|
||||
EventAttachmentRemove,
|
||||
EventAttachmentUpdate,
|
||||
EventChannelFolderAdd,
|
||||
EventCustomProfileFields,
|
||||
EventDefaultStreamGroups,
|
||||
EventDefaultStreams,
|
||||
@@ -161,6 +162,7 @@ check_alert_words = make_checker(EventAlertWords)
|
||||
check_attachment_add = make_checker(EventAttachmentAdd)
|
||||
check_attachment_remove = make_checker(EventAttachmentRemove)
|
||||
check_attachment_update = make_checker(EventAttachmentUpdate)
|
||||
check_channel_folder_add = make_checker(EventChannelFolderAdd)
|
||||
check_custom_profile_fields = make_checker(EventCustomProfileFields)
|
||||
check_default_stream_groups = make_checker(EventDefaultStreamGroups)
|
||||
check_default_streams = make_checker(EventDefaultStreams)
|
||||
|
||||
@@ -66,6 +66,22 @@ class EventAttachmentUpdate(BaseEvent):
|
||||
upload_space_used: int
|
||||
|
||||
|
||||
class ChannelFolderForEventChannelFolderAdd(BaseModel):
|
||||
id: int
|
||||
name: str
|
||||
description: str
|
||||
rendered_description: str
|
||||
date_created: int
|
||||
creator_id: int
|
||||
is_archived: bool
|
||||
|
||||
|
||||
class EventChannelFolderAdd(BaseEvent):
|
||||
type: Literal["channel_folder"]
|
||||
op: Literal["add"]
|
||||
channel_folder: ChannelFolderForEventChannelFolderAdd
|
||||
|
||||
|
||||
class DetailedCustomProfileCore(BaseModel):
|
||||
id: int
|
||||
type: int
|
||||
|
||||
@@ -19,6 +19,7 @@ from zerver.lib import emoji
|
||||
from zerver.lib.alert_words import user_alert_words
|
||||
from zerver.lib.avatar import avatar_url
|
||||
from zerver.lib.bot_config import load_bot_config_template
|
||||
from zerver.lib.channel_folders import get_channel_folders_in_realm
|
||||
from zerver.lib.compatibility import is_outdated_server
|
||||
from zerver.lib.default_streams import get_default_stream_ids_for_realm
|
||||
from zerver.lib.exceptions import JsonableError
|
||||
@@ -764,6 +765,11 @@ def fetch_initial_state_data(
|
||||
state["unsubscribed"] = sub_info.unsubscribed
|
||||
state["never_subscribed"] = sub_info.never_subscribed
|
||||
|
||||
if want("channel_folders") and user_profile is not None:
|
||||
# TODO: Spectators should get the channel folders that
|
||||
# contain atleast one web-public channel.
|
||||
state["channel_folders"] = get_channel_folders_in_realm(user_profile.realm)
|
||||
|
||||
if want("update_message_flags") and want("message"):
|
||||
# Keeping unread_msgs updated requires both message flag updates and
|
||||
# message updates. This is due to the fact that new messages will not
|
||||
@@ -1870,6 +1876,12 @@ def apply_event(
|
||||
else:
|
||||
fields = ["stream_id", "topic_name", "visibility_policy", "last_updated"]
|
||||
state["user_topics"].append({x: event[x] for x in fields})
|
||||
elif event["type"] == "channel_folder":
|
||||
if event["op"] == "add":
|
||||
state["channel_folders"].append(event["channel_folder"])
|
||||
state["channel_folders"].sort(key=lambda folder: folder["id"])
|
||||
else:
|
||||
raise AssertionError("Unexpected event type {type}/{op}".format(**event))
|
||||
elif event["type"] == "has_zoom_token":
|
||||
state["has_zoom_token"] = event["value"]
|
||||
elif event["type"] == "web_reload_client":
|
||||
|
||||
Reference in New Issue
Block a user