mirror of
https://github.com/zulip/zulip.git
synced 2025-11-06 06:53:25 +00:00
@@ -49,6 +49,7 @@ from zerver.models import (
|
||||
Attachment,
|
||||
BotConfigData,
|
||||
BotStorageData,
|
||||
ChannelFolder,
|
||||
Client,
|
||||
CustomProfileField,
|
||||
CustomProfileFieldValue,
|
||||
@@ -147,6 +148,7 @@ ALL_ZULIP_TABLES = {
|
||||
"zerver_botconfigdata",
|
||||
"zerver_botstoragedata",
|
||||
"zerver_channelemailaddress",
|
||||
"zerver_channelfolder",
|
||||
"zerver_client",
|
||||
"zerver_customprofilefield",
|
||||
"zerver_customprofilefieldvalue",
|
||||
@@ -327,6 +329,7 @@ DATE_FIELDS: dict[TableName, list[Field]] = {
|
||||
"analytics_streamcount": ["end_time"],
|
||||
"analytics_usercount": ["end_time"],
|
||||
"zerver_attachment": ["create_time"],
|
||||
"zerver_channelfolder": ["date_created"],
|
||||
"zerver_message": ["last_edit_time", "date_sent"],
|
||||
"zerver_muteduser": ["date_muted"],
|
||||
"zerver_realmauditlog": ["event_time"],
|
||||
@@ -1081,6 +1084,13 @@ def get_realm_config() -> Config:
|
||||
custom_process_results=custom_process_subscription_in_realm_config,
|
||||
)
|
||||
|
||||
Config(
|
||||
table="zerver_channelfolder",
|
||||
model=ChannelFolder,
|
||||
normal_parent=realm_config,
|
||||
include_rows="realm_id__in",
|
||||
)
|
||||
|
||||
add_user_profile_child_configs(user_profile_config)
|
||||
|
||||
return realm_config
|
||||
|
||||
@@ -62,6 +62,7 @@ from zerver.models import (
|
||||
Attachment,
|
||||
BotConfigData,
|
||||
BotStorageData,
|
||||
ChannelFolder,
|
||||
Client,
|
||||
CustomProfileField,
|
||||
CustomProfileFieldValue,
|
||||
@@ -169,6 +170,7 @@ ID_MAP: dict[str, dict[int, int]] = {
|
||||
"scheduledmessage": {},
|
||||
"onboardingusermessage": {},
|
||||
"savedsnippet": {},
|
||||
"channelfolder": {},
|
||||
}
|
||||
|
||||
id_map_to_list: dict[str, dict[int, list[int]]] = {
|
||||
@@ -1231,6 +1233,8 @@ def do_import_realm(import_dir: Path, subdomain: str, processes: int = 1) -> Rea
|
||||
update_model_ids(UserGroup, data, "usergroup")
|
||||
if "zerver_presencesequence" in data:
|
||||
update_model_ids(PresenceSequence, data, "presencesequence")
|
||||
if "zerver_channelfolder" in data:
|
||||
update_model_ids(ChannelFolder, data, "channelfolder")
|
||||
|
||||
# Now we prepare to import the Realm table
|
||||
re_map_foreign_keys(data, "zerver_realm", "moderation_request_channel", related_table="stream")
|
||||
@@ -1386,6 +1390,12 @@ def do_import_realm(import_dir: Path, subdomain: str, processes: int = 1) -> Rea
|
||||
stream.creator_id = stream_id_to_creator_id[stream.id]
|
||||
Stream.objects.bulk_update(streams, ["creator_id"])
|
||||
|
||||
if "zerver_channelfolder" in data:
|
||||
fix_datetime_fields(data, "zerver_channelfolder")
|
||||
re_map_foreign_keys(data, "zerver_channelfolder", "realm", related_table="realm")
|
||||
re_map_foreign_keys(data, "zerver_channelfolder", "creator", related_table="user_profile")
|
||||
bulk_import_model(data, ChannelFolder)
|
||||
|
||||
if "zerver_namedusergroup" in data:
|
||||
# UserProfiles have been loaded, so now we're ready to set .creator_id
|
||||
# for groups based on the mapping we saved earlier.
|
||||
|
||||
48
zerver/migrations/0706_channelfolder.py
Normal file
48
zerver/migrations/0706_channelfolder.py
Normal file
@@ -0,0 +1,48 @@
|
||||
# Generated by Django 5.1.8 on 2025-05-02 09:27
|
||||
|
||||
import django.db.models.deletion
|
||||
import django.utils.timezone
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
("zerver", "0705_stream_subscriber_count_data_migration"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name="ChannelFolder",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.BigAutoField(
|
||||
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
||||
),
|
||||
),
|
||||
("name", models.CharField(max_length=100)),
|
||||
("description", models.CharField(default="", max_length=1024)),
|
||||
("rendered_description", models.TextField(default="")),
|
||||
("date_created", models.DateTimeField(default=django.utils.timezone.now)),
|
||||
("is_archived", models.BooleanField(default=False)),
|
||||
(
|
||||
"creator",
|
||||
models.ForeignKey(
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.SET_NULL,
|
||||
to=settings.AUTH_USER_MODEL,
|
||||
),
|
||||
),
|
||||
(
|
||||
"realm",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE, to="zerver.realm"
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"unique_together": {("realm", "name")},
|
||||
},
|
||||
),
|
||||
]
|
||||
@@ -3,6 +3,7 @@ from zerver.models.alert_words import AlertWord as AlertWord
|
||||
from zerver.models.bots import BotConfigData as BotConfigData
|
||||
from zerver.models.bots import BotStorageData as BotStorageData
|
||||
from zerver.models.bots import Service as Service
|
||||
from zerver.models.channel_folders import ChannelFolder as ChannelFolder
|
||||
from zerver.models.clients import Client as Client
|
||||
from zerver.models.custom_profile_fields import CustomProfileField as CustomProfileField
|
||||
from zerver.models.custom_profile_fields import CustomProfileFieldValue as CustomProfileFieldValue
|
||||
|
||||
22
zerver/models/channel_folders.py
Normal file
22
zerver/models/channel_folders.py
Normal file
@@ -0,0 +1,22 @@
|
||||
from django.db import models
|
||||
from django.utils.timezone import now as timezone_now
|
||||
|
||||
from zerver.models.realms import Realm
|
||||
from zerver.models.users import UserProfile
|
||||
|
||||
|
||||
class ChannelFolder(models.Model):
|
||||
MAX_NAME_LENGTH = 100
|
||||
MAX_DESCRIPTION_LENGTH = 1024
|
||||
|
||||
realm = models.ForeignKey(Realm, on_delete=models.CASCADE)
|
||||
name = models.CharField(max_length=MAX_NAME_LENGTH)
|
||||
description = models.CharField(max_length=MAX_DESCRIPTION_LENGTH, default="")
|
||||
rendered_description = models.TextField(default="")
|
||||
|
||||
date_created = models.DateTimeField(default=timezone_now)
|
||||
creator = models.ForeignKey(UserProfile, null=True, on_delete=models.SET_NULL)
|
||||
is_archived = models.BooleanField(default=False)
|
||||
|
||||
class Meta:
|
||||
unique_together = ("realm", "name")
|
||||
@@ -76,6 +76,7 @@ from zerver.models import (
|
||||
Attachment,
|
||||
BotConfigData,
|
||||
BotStorageData,
|
||||
ChannelFolder,
|
||||
CustomProfileField,
|
||||
CustomProfileFieldValue,
|
||||
DirectMessageGroup,
|
||||
@@ -1618,6 +1619,13 @@ class RealmImportExportTest(ExportFile):
|
||||
flags=OnboardingUserMessage.flags.starred,
|
||||
)
|
||||
|
||||
ChannelFolder.objects.create(
|
||||
realm=original_realm,
|
||||
name="Frontend",
|
||||
description="Frontend channels",
|
||||
creator=self.example_user("iago"),
|
||||
)
|
||||
|
||||
# We want to have an extra, malformed RealmEmoji with no .author
|
||||
# to test that upon import that gets fixed.
|
||||
with get_test_image_file("img.png") as img_file:
|
||||
@@ -2249,6 +2257,10 @@ class RealmImportExportTest(ExportFile):
|
||||
)
|
||||
return tups
|
||||
|
||||
@getter
|
||||
def get_channel_folders(r: Realm) -> set[str]:
|
||||
return set(ChannelFolder.objects.filter(realm=r).values_list("name", flat=True))
|
||||
|
||||
return getters
|
||||
|
||||
def test_import_realm_with_invalid_email_addresses_fails_validation(self) -> None:
|
||||
|
||||
Reference in New Issue
Block a user