mirror of
https://github.com/zulip/zulip.git
synced 2026-07-03 21:10:12 +08:00
data_import: Import attachments from Rocket.Chat.
This commit is contained in:
parent
65e28907cb
commit
aed4e48da7
@ -1,7 +1,9 @@
|
|||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
import random
|
||||||
|
import secrets
|
||||||
import subprocess
|
import subprocess
|
||||||
from typing import Any, Dict, List, Set
|
from typing import Any, Dict, List, Set, Tuple
|
||||||
|
|
||||||
import bson
|
import bson
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
@ -10,6 +12,7 @@ from django.forms.models import model_to_dict
|
|||||||
from zerver.data_import.import_util import (
|
from zerver.data_import.import_util import (
|
||||||
SubscriberHandler,
|
SubscriberHandler,
|
||||||
ZerverFieldsT,
|
ZerverFieldsT,
|
||||||
|
build_attachment,
|
||||||
build_huddle,
|
build_huddle,
|
||||||
build_huddle_subscriptions,
|
build_huddle_subscriptions,
|
||||||
build_message,
|
build_message,
|
||||||
@ -28,6 +31,8 @@ from zerver.data_import.import_util import (
|
|||||||
from zerver.data_import.sequencer import NEXT_ID, IdMapper
|
from zerver.data_import.sequencer import NEXT_ID, IdMapper
|
||||||
from zerver.data_import.user_handler import UserHandler
|
from zerver.data_import.user_handler import UserHandler
|
||||||
from zerver.lib.emoji import name_to_codepoint
|
from zerver.lib.emoji import name_to_codepoint
|
||||||
|
from zerver.lib.markdown import IMAGE_EXTENSIONS
|
||||||
|
from zerver.lib.upload import sanitize_name
|
||||||
from zerver.lib.utils import process_list_in_batches
|
from zerver.lib.utils import process_list_in_batches
|
||||||
from zerver.models import Reaction, RealmEmoji, Recipient, UserProfile
|
from zerver.models import Reaction, RealmEmoji, Recipient, UserProfile
|
||||||
|
|
||||||
@ -344,6 +349,74 @@ def build_reactions(
|
|||||||
total_reactions.append(reaction_dict)
|
total_reactions.append(reaction_dict)
|
||||||
|
|
||||||
|
|
||||||
|
def process_message_attachment(
|
||||||
|
upload: Dict[str, Any],
|
||||||
|
realm_id: int,
|
||||||
|
message_id: int,
|
||||||
|
user_id: int,
|
||||||
|
user_handler: UserHandler,
|
||||||
|
zerver_attachment: List[ZerverFieldsT],
|
||||||
|
uploads_list: List[ZerverFieldsT],
|
||||||
|
upload_id_to_upload_data_map: Dict[str, Dict[str, Any]],
|
||||||
|
output_dir: str,
|
||||||
|
) -> Tuple[str, bool]:
|
||||||
|
upload_file_data = upload_id_to_upload_data_map[upload["_id"]]
|
||||||
|
file_name = upload["name"]
|
||||||
|
file_ext = f'.{upload["type"].split("/")[-1]}'
|
||||||
|
|
||||||
|
has_image = False
|
||||||
|
if file_ext.lower() in IMAGE_EXTENSIONS:
|
||||||
|
has_image = True
|
||||||
|
|
||||||
|
s3_path = "/".join(
|
||||||
|
[
|
||||||
|
str(realm_id),
|
||||||
|
format(random.randint(0, 255), "x"),
|
||||||
|
secrets.token_urlsafe(18),
|
||||||
|
sanitize_name(file_name),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
# Build the attachment from chunks and save it to s3_path.
|
||||||
|
file_out_path = os.path.join(output_dir, "uploads", s3_path)
|
||||||
|
os.makedirs(os.path.dirname(file_out_path), exist_ok=True)
|
||||||
|
with open(file_out_path, "wb") as upload_file:
|
||||||
|
upload_file.write(b"".join(upload_file_data["chunk"]))
|
||||||
|
|
||||||
|
attachment_content = (
|
||||||
|
f'{upload_file_data["description"]}\n\n[{file_name}](/user_uploads/{s3_path})'
|
||||||
|
)
|
||||||
|
|
||||||
|
fileinfo = {
|
||||||
|
"name": file_name,
|
||||||
|
"size": upload_file_data["size"],
|
||||||
|
"created": float(upload_file_data["_updatedAt"].timestamp()),
|
||||||
|
}
|
||||||
|
|
||||||
|
upload = dict(
|
||||||
|
path=s3_path,
|
||||||
|
realm_id=realm_id,
|
||||||
|
content_type=upload["type"],
|
||||||
|
user_profile_id=user_id,
|
||||||
|
last_modified=fileinfo["created"],
|
||||||
|
user_profile_email=user_handler.get_user(user_id=user_id)["email"],
|
||||||
|
s3_path=s3_path,
|
||||||
|
size=fileinfo["size"],
|
||||||
|
)
|
||||||
|
uploads_list.append(upload)
|
||||||
|
|
||||||
|
build_attachment(
|
||||||
|
realm_id=realm_id,
|
||||||
|
message_ids={message_id},
|
||||||
|
user_id=user_id,
|
||||||
|
fileinfo=fileinfo,
|
||||||
|
s3_path=s3_path,
|
||||||
|
zerver_attachment=zerver_attachment,
|
||||||
|
)
|
||||||
|
|
||||||
|
return attachment_content, has_image
|
||||||
|
|
||||||
|
|
||||||
def process_raw_message_batch(
|
def process_raw_message_batch(
|
||||||
realm_id: int,
|
realm_id: int,
|
||||||
raw_messages: List[Dict[str, Any]],
|
raw_messages: List[Dict[str, Any]],
|
||||||
@ -353,6 +426,9 @@ def process_raw_message_batch(
|
|||||||
output_dir: str,
|
output_dir: str,
|
||||||
zerver_realmemoji: List[ZerverFieldsT],
|
zerver_realmemoji: List[ZerverFieldsT],
|
||||||
total_reactions: List[ZerverFieldsT],
|
total_reactions: List[ZerverFieldsT],
|
||||||
|
uploads_list: List[ZerverFieldsT],
|
||||||
|
zerver_attachment: List[ZerverFieldsT],
|
||||||
|
upload_id_to_upload_data_map: Dict[str, Dict[str, Any]],
|
||||||
) -> None:
|
) -> None:
|
||||||
def fix_mentions(content: str, mention_user_ids: Set[int]) -> str:
|
def fix_mentions(content: str, mention_user_ids: Set[int]) -> str:
|
||||||
for user_id in mention_user_ids:
|
for user_id in mention_user_ids:
|
||||||
@ -390,6 +466,28 @@ def process_raw_message_batch(
|
|||||||
|
|
||||||
rendered_content = None
|
rendered_content = None
|
||||||
|
|
||||||
|
has_attachment = False
|
||||||
|
has_image = False
|
||||||
|
has_link = raw_message["has_link"]
|
||||||
|
|
||||||
|
if "file" in raw_message:
|
||||||
|
has_attachment = True
|
||||||
|
has_link = True
|
||||||
|
|
||||||
|
attachment_content, has_image = process_message_attachment(
|
||||||
|
upload=raw_message["file"],
|
||||||
|
realm_id=realm_id,
|
||||||
|
message_id=message_id,
|
||||||
|
user_id=sender_user_id,
|
||||||
|
user_handler=user_handler,
|
||||||
|
uploads_list=uploads_list,
|
||||||
|
zerver_attachment=zerver_attachment,
|
||||||
|
upload_id_to_upload_data_map=upload_id_to_upload_data_map,
|
||||||
|
output_dir=output_dir,
|
||||||
|
)
|
||||||
|
|
||||||
|
content += attachment_content
|
||||||
|
|
||||||
topic_name = raw_message["topic_name"]
|
topic_name = raw_message["topic_name"]
|
||||||
|
|
||||||
message = build_message(
|
message = build_message(
|
||||||
@ -400,7 +498,9 @@ def process_raw_message_batch(
|
|||||||
rendered_content=rendered_content,
|
rendered_content=rendered_content,
|
||||||
topic_name=topic_name,
|
topic_name=topic_name,
|
||||||
user_id=sender_user_id,
|
user_id=sender_user_id,
|
||||||
has_attachment=False,
|
has_image=has_image,
|
||||||
|
has_link=has_link,
|
||||||
|
has_attachment=has_attachment,
|
||||||
)
|
)
|
||||||
zerver_message.append(message)
|
zerver_message.append(message)
|
||||||
build_reactions(
|
build_reactions(
|
||||||
@ -445,6 +545,9 @@ def process_messages(
|
|||||||
huddle_id_to_huddle_map: Dict[str, Dict[str, Any]],
|
huddle_id_to_huddle_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],
|
||||||
|
zerver_attachment: List[ZerverFieldsT],
|
||||||
|
upload_id_to_upload_data_map: Dict[str, Dict[str, Any]],
|
||||||
output_dir: str,
|
output_dir: str,
|
||||||
) -> None:
|
) -> None:
|
||||||
def list_reactions(reactions: Dict[str, Dict[str, Any]]) -> List[Dict[str, Any]]:
|
def list_reactions(reactions: Dict[str, Dict[str, Any]]) -> List[Dict[str, Any]]:
|
||||||
@ -477,6 +580,7 @@ def process_messages(
|
|||||||
content=content,
|
content=content,
|
||||||
date_sent=int(message["ts"].timestamp()),
|
date_sent=int(message["ts"].timestamp()),
|
||||||
reactions=reactions,
|
reactions=reactions,
|
||||||
|
has_link=True if message.get("urls") else False,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Add recipient_id and topic to message_dict
|
# Add recipient_id and topic to message_dict
|
||||||
@ -518,6 +622,10 @@ def process_messages(
|
|||||||
mention_user_ids.add(user_id)
|
mention_user_ids.add(user_id)
|
||||||
message_dict["mention_user_ids"] = mention_user_ids
|
message_dict["mention_user_ids"] = mention_user_ids
|
||||||
|
|
||||||
|
# Add uploaded file (attachment) to message_dict
|
||||||
|
if message.get("file"):
|
||||||
|
message_dict["file"] = message["file"]
|
||||||
|
|
||||||
return message_dict
|
return message_dict
|
||||||
|
|
||||||
raw_messages: List[Dict[str, Any]] = []
|
raw_messages: List[Dict[str, Any]] = []
|
||||||
@ -538,6 +646,9 @@ def process_messages(
|
|||||||
output_dir=output_dir,
|
output_dir=output_dir,
|
||||||
zerver_realmemoji=zerver_realmemoji,
|
zerver_realmemoji=zerver_realmemoji,
|
||||||
total_reactions=total_reactions,
|
total_reactions=total_reactions,
|
||||||
|
uploads_list=uploads_list,
|
||||||
|
zerver_attachment=zerver_attachment,
|
||||||
|
upload_id_to_upload_data_map=upload_id_to_upload_data_map,
|
||||||
)
|
)
|
||||||
|
|
||||||
chunk_size = 1000
|
chunk_size = 1000
|
||||||
@ -549,6 +660,20 @@ def process_messages(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def map_upload_id_to_upload_data(
|
||||||
|
upload_data: Dict[str, List[Dict[str, Any]]],
|
||||||
|
) -> Dict[str, Dict[str, Any]]:
|
||||||
|
upload_id_to_upload_data_map: Dict[str, Dict[str, Any]] = {}
|
||||||
|
|
||||||
|
for upload in upload_data["upload"]:
|
||||||
|
upload_id_to_upload_data_map[upload["_id"]] = {**upload, "chunk": []}
|
||||||
|
|
||||||
|
for chunk in upload_data["chunk"]:
|
||||||
|
upload_id_to_upload_data_map[chunk["files_id"]]["chunk"].append(chunk["data"])
|
||||||
|
|
||||||
|
return upload_id_to_upload_data_map
|
||||||
|
|
||||||
|
|
||||||
def separate_channel_and_private_messages(
|
def separate_channel_and_private_messages(
|
||||||
messages: List[Dict[str, Any]],
|
messages: List[Dict[str, Any]],
|
||||||
direct_id_to_direct_map: Dict[str, Dict[str, Any]],
|
direct_id_to_direct_map: Dict[str, Dict[str, Any]],
|
||||||
@ -630,6 +755,7 @@ def rocketchat_data_to_dict(rocketchat_data_dir: str) -> Dict[str, Any]:
|
|||||||
rocketchat_data["room"] = []
|
rocketchat_data["room"] = []
|
||||||
rocketchat_data["message"] = []
|
rocketchat_data["message"] = []
|
||||||
rocketchat_data["custom_emoji"] = {"emoji": [], "file": [], "chunk": []}
|
rocketchat_data["custom_emoji"] = {"emoji": [], "file": [], "chunk": []}
|
||||||
|
rocketchat_data["upload"] = {"upload": [], "file": [], "chunk": []}
|
||||||
|
|
||||||
# Get instance
|
# Get instance
|
||||||
with open(os.path.join(rocketchat_data_dir, "instances.bson"), "rb") as fcache:
|
with open(os.path.join(rocketchat_data_dir, "instances.bson"), "rb") as fcache:
|
||||||
@ -673,6 +799,21 @@ def rocketchat_data_to_dict(rocketchat_data_dir: str) -> Dict[str, Any]:
|
|||||||
with open(os.path.join(rocketchat_data_dir, "custom_emoji.chunks.bson"), "rb") as fcache:
|
with open(os.path.join(rocketchat_data_dir, "custom_emoji.chunks.bson"), "rb") as fcache:
|
||||||
rocketchat_data["custom_emoji"]["chunk"] = bson.decode_all(fcache.read())
|
rocketchat_data["custom_emoji"]["chunk"] = bson.decode_all(fcache.read())
|
||||||
|
|
||||||
|
# Get uploads
|
||||||
|
with open(os.path.join(rocketchat_data_dir, "rocketchat_uploads.bson"), "rb") as fcache:
|
||||||
|
rocketchat_data["upload"]["upload"] = bson.decode_all(fcache.read())
|
||||||
|
|
||||||
|
if rocketchat_data["upload"]["upload"]:
|
||||||
|
with open(
|
||||||
|
os.path.join(rocketchat_data_dir, "rocketchat_uploads.files.bson"), "rb"
|
||||||
|
) as fcache:
|
||||||
|
rocketchat_data["upload"]["file"] = bson.decode_all(fcache.read())
|
||||||
|
|
||||||
|
with open(
|
||||||
|
os.path.join(rocketchat_data_dir, "rocketchat_uploads.chunks.bson"), "rb"
|
||||||
|
) as fcache:
|
||||||
|
rocketchat_data["upload"]["chunk"] = bson.decode_all(fcache.read())
|
||||||
|
|
||||||
return rocketchat_data
|
return rocketchat_data
|
||||||
|
|
||||||
|
|
||||||
@ -807,6 +948,10 @@ def do_convert_data(rocketchat_data_dir: str, output_dir: str) -> None:
|
|||||||
)
|
)
|
||||||
|
|
||||||
total_reactions: List[ZerverFieldsT] = []
|
total_reactions: List[ZerverFieldsT] = []
|
||||||
|
uploads_list: List[ZerverFieldsT] = []
|
||||||
|
zerver_attachment: List[ZerverFieldsT] = []
|
||||||
|
|
||||||
|
upload_id_to_upload_data_map = map_upload_id_to_upload_data(rocketchat_data["upload"])
|
||||||
|
|
||||||
# Process channel messages
|
# Process channel messages
|
||||||
process_messages(
|
process_messages(
|
||||||
@ -827,6 +972,9 @@ def do_convert_data(rocketchat_data_dir: str, output_dir: str) -> None:
|
|||||||
huddle_id_to_huddle_map=huddle_id_to_huddle_map,
|
huddle_id_to_huddle_map=huddle_id_to_huddle_map,
|
||||||
zerver_realmemoji=zerver_realmemoji,
|
zerver_realmemoji=zerver_realmemoji,
|
||||||
total_reactions=total_reactions,
|
total_reactions=total_reactions,
|
||||||
|
uploads_list=uploads_list,
|
||||||
|
zerver_attachment=zerver_attachment,
|
||||||
|
upload_id_to_upload_data_map=upload_id_to_upload_data_map,
|
||||||
output_dir=output_dir,
|
output_dir=output_dir,
|
||||||
)
|
)
|
||||||
# Process private messages
|
# Process private messages
|
||||||
@ -848,6 +996,9 @@ def do_convert_data(rocketchat_data_dir: str, output_dir: str) -> None:
|
|||||||
huddle_id_to_huddle_map=huddle_id_to_huddle_map,
|
huddle_id_to_huddle_map=huddle_id_to_huddle_map,
|
||||||
zerver_realmemoji=zerver_realmemoji,
|
zerver_realmemoji=zerver_realmemoji,
|
||||||
total_reactions=total_reactions,
|
total_reactions=total_reactions,
|
||||||
|
uploads_list=uploads_list,
|
||||||
|
zerver_attachment=zerver_attachment,
|
||||||
|
upload_id_to_upload_data_map=upload_id_to_upload_data_map,
|
||||||
output_dir=output_dir,
|
output_dir=output_dir,
|
||||||
)
|
)
|
||||||
realm["zerver_reaction"] = total_reactions
|
realm["zerver_reaction"] = total_reactions
|
||||||
@ -857,12 +1008,11 @@ def do_convert_data(rocketchat_data_dir: str, output_dir: str) -> None:
|
|||||||
create_converted_data_files(realm, output_dir, "/realm.json")
|
create_converted_data_files(realm, output_dir, "/realm.json")
|
||||||
# TODO: Add support for importing avatars
|
# TODO: Add support for importing avatars
|
||||||
create_converted_data_files([], output_dir, "/avatars/records.json")
|
create_converted_data_files([], output_dir, "/avatars/records.json")
|
||||||
# TODO: Add support for importing uploads
|
|
||||||
create_converted_data_files([], output_dir, "/uploads/records.json")
|
|
||||||
|
|
||||||
# TODO: Add support for importing attachments
|
# Import attachments
|
||||||
attachment: Dict[str, List[Any]] = {"zerver_attachment": []}
|
attachment: Dict[str, List[Any]] = {"zerver_attachment": zerver_attachment}
|
||||||
create_converted_data_files(attachment, output_dir, "/attachment.json")
|
create_converted_data_files(attachment, output_dir, "/attachment.json")
|
||||||
|
create_converted_data_files(uploads_list, output_dir, "/uploads/records.json")
|
||||||
|
|
||||||
logging.info("Start making tarball")
|
logging.info("Start making tarball")
|
||||||
subprocess.check_call(["tar", "-czf", output_dir + ".tar.gz", output_dir, "-P"])
|
subprocess.check_call(["tar", "-czf", output_dir + ".tar.gz", output_dir, "-P"])
|
||||||
|
|||||||
Binary file not shown.
BIN
zerver/tests/fixtures/rocketchat_fixtures/rocketchat_uploads.bson
vendored
Normal file
BIN
zerver/tests/fixtures/rocketchat_fixtures/rocketchat_uploads.bson
vendored
Normal file
Binary file not shown.
BIN
zerver/tests/fixtures/rocketchat_fixtures/rocketchat_uploads.chunks.bson
vendored
Normal file
BIN
zerver/tests/fixtures/rocketchat_fixtures/rocketchat_uploads.chunks.bson
vendored
Normal file
Binary file not shown.
BIN
zerver/tests/fixtures/rocketchat_fixtures/rocketchat_uploads.files.bson
vendored
Normal file
BIN
zerver/tests/fixtures/rocketchat_fixtures/rocketchat_uploads.files.bson
vendored
Normal file
Binary file not shown.
@ -14,8 +14,10 @@ from zerver.data_import.rocketchat import (
|
|||||||
convert_stream_subscription_data,
|
convert_stream_subscription_data,
|
||||||
do_convert_data,
|
do_convert_data,
|
||||||
map_receiver_id_to_recipient_id,
|
map_receiver_id_to_recipient_id,
|
||||||
|
map_upload_id_to_upload_data,
|
||||||
map_user_id_to_user,
|
map_user_id_to_user,
|
||||||
map_username_to_user_id,
|
map_username_to_user_id,
|
||||||
|
process_message_attachment,
|
||||||
process_users,
|
process_users,
|
||||||
rocketchat_data_to_dict,
|
rocketchat_data_to_dict,
|
||||||
separate_channel_and_private_messages,
|
separate_channel_and_private_messages,
|
||||||
@ -32,7 +34,7 @@ class RocketChatImporter(ZulipTestCase):
|
|||||||
def test_rocketchat_data_to_dict(self) -> None:
|
def test_rocketchat_data_to_dict(self) -> None:
|
||||||
fixture_dir_name = self.fixture_file_name("", "rocketchat_fixtures")
|
fixture_dir_name = self.fixture_file_name("", "rocketchat_fixtures")
|
||||||
rocketchat_data = rocketchat_data_to_dict(fixture_dir_name)
|
rocketchat_data = rocketchat_data_to_dict(fixture_dir_name)
|
||||||
self.assert_length(rocketchat_data, 6)
|
self.assert_length(rocketchat_data, 7)
|
||||||
|
|
||||||
self.assert_length(rocketchat_data["user"], 6)
|
self.assert_length(rocketchat_data["user"], 6)
|
||||||
self.assertEqual(rocketchat_data["user"][2]["username"], "harry.potter")
|
self.assertEqual(rocketchat_data["user"][2]["username"], "harry.potter")
|
||||||
@ -42,7 +44,7 @@ class RocketChatImporter(ZulipTestCase):
|
|||||||
self.assertEqual(rocketchat_data["room"][0]["_id"], "GENERAL")
|
self.assertEqual(rocketchat_data["room"][0]["_id"], "GENERAL")
|
||||||
self.assertEqual(rocketchat_data["room"][0]["name"], "general")
|
self.assertEqual(rocketchat_data["room"][0]["name"], "general")
|
||||||
|
|
||||||
self.assert_length(rocketchat_data["message"], 58)
|
self.assert_length(rocketchat_data["message"], 63)
|
||||||
self.assertEqual(rocketchat_data["message"][1]["msg"], "Hey everyone, how's it going??")
|
self.assertEqual(rocketchat_data["message"][1]["msg"], "Hey everyone, how's it going??")
|
||||||
self.assertEqual(rocketchat_data["message"][1]["rid"], "GENERAL")
|
self.assertEqual(rocketchat_data["message"][1]["rid"], "GENERAL")
|
||||||
self.assertEqual(rocketchat_data["message"][1]["u"]["username"], "priyansh3133")
|
self.assertEqual(rocketchat_data["message"][1]["u"]["username"], "priyansh3133")
|
||||||
@ -50,6 +52,9 @@ class RocketChatImporter(ZulipTestCase):
|
|||||||
self.assert_length(rocketchat_data["custom_emoji"]["emoji"], 3)
|
self.assert_length(rocketchat_data["custom_emoji"]["emoji"], 3)
|
||||||
self.assertEqual(rocketchat_data["custom_emoji"]["emoji"][0]["name"], "tick")
|
self.assertEqual(rocketchat_data["custom_emoji"]["emoji"][0]["name"], "tick")
|
||||||
|
|
||||||
|
self.assert_length(rocketchat_data["upload"]["upload"], 4)
|
||||||
|
self.assertEqual(rocketchat_data["upload"]["upload"][0]["name"], "harry-ron.jpg")
|
||||||
|
|
||||||
def test_map_user_id_to_user(self) -> None:
|
def test_map_user_id_to_user(self) -> None:
|
||||||
fixture_dir_name = self.fixture_file_name("", "rocketchat_fixtures")
|
fixture_dir_name = self.fixture_file_name("", "rocketchat_fixtures")
|
||||||
rocketchat_data = rocketchat_data_to_dict(fixture_dir_name)
|
rocketchat_data = rocketchat_data_to_dict(fixture_dir_name)
|
||||||
@ -613,9 +618,9 @@ class RocketChatImporter(ZulipTestCase):
|
|||||||
private_messages=private_messages,
|
private_messages=private_messages,
|
||||||
)
|
)
|
||||||
|
|
||||||
self.assert_length(rocketchat_data["message"], 58)
|
self.assert_length(rocketchat_data["message"], 63)
|
||||||
self.assert_length(channel_messages, 53)
|
self.assert_length(channel_messages, 57)
|
||||||
self.assert_length(private_messages, 5)
|
self.assert_length(private_messages, 6)
|
||||||
|
|
||||||
self.assertIn(rocketchat_data["message"][0], channel_messages)
|
self.assertIn(rocketchat_data["message"][0], channel_messages)
|
||||||
self.assertIn(rocketchat_data["message"][1], channel_messages)
|
self.assertIn(rocketchat_data["message"][1], channel_messages)
|
||||||
@ -661,8 +666,22 @@ class RocketChatImporter(ZulipTestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# No new message added to channel or private messages
|
# No new message added to channel or private messages
|
||||||
self.assert_length(channel_messages, 53)
|
self.assert_length(channel_messages, 57)
|
||||||
self.assert_length(private_messages, 5)
|
self.assert_length(private_messages, 6)
|
||||||
|
|
||||||
|
def test_map_upload_id_to_upload_data(self) -> None:
|
||||||
|
fixture_dir_name = self.fixture_file_name("", "rocketchat_fixtures")
|
||||||
|
rocketchat_data = rocketchat_data_to_dict(fixture_dir_name)
|
||||||
|
|
||||||
|
upload_id_to_upload_data_map = map_upload_id_to_upload_data(rocketchat_data["upload"])
|
||||||
|
|
||||||
|
self.assert_length(rocketchat_data["upload"]["upload"], 4)
|
||||||
|
self.assert_length(upload_id_to_upload_data_map, 4)
|
||||||
|
|
||||||
|
upload_id = rocketchat_data["upload"]["upload"][0]["_id"]
|
||||||
|
upload_name = rocketchat_data["upload"]["upload"][0]["name"]
|
||||||
|
self.assertEqual(upload_id_to_upload_data_map[upload_id]["name"], upload_name)
|
||||||
|
self.assert_length(upload_id_to_upload_data_map[upload_id]["chunk"], 1)
|
||||||
|
|
||||||
def test_build_reactions(self) -> None:
|
def test_build_reactions(self) -> None:
|
||||||
fixture_dir_name = self.fixture_file_name("", "rocketchat_fixtures")
|
fixture_dir_name = self.fixture_file_name("", "rocketchat_fixtures")
|
||||||
@ -734,6 +753,62 @@ class RocketChatImporter(ZulipTestCase):
|
|||||||
self.assert_length(self.get_set(total_reactions, "id"), 7)
|
self.assert_length(self.get_set(total_reactions, "id"), 7)
|
||||||
self.assert_length(self.get_set(total_reactions, "message"), 1)
|
self.assert_length(self.get_set(total_reactions, "message"), 1)
|
||||||
|
|
||||||
|
def test_process_message_attachment(self) -> None:
|
||||||
|
fixture_dir_name = self.fixture_file_name("", "rocketchat_fixtures")
|
||||||
|
rocketchat_data = rocketchat_data_to_dict(fixture_dir_name)
|
||||||
|
output_dir = self.make_import_output_dir("mattermost")
|
||||||
|
|
||||||
|
user_id_to_user_map = map_user_id_to_user(rocketchat_data["user"])
|
||||||
|
|
||||||
|
realm_id = 3
|
||||||
|
domain_name = "zulip.com"
|
||||||
|
|
||||||
|
user_handler = UserHandler()
|
||||||
|
user_id_mapper = IdMapper()
|
||||||
|
|
||||||
|
process_users(
|
||||||
|
user_id_to_user_map=user_id_to_user_map,
|
||||||
|
realm_id=realm_id,
|
||||||
|
domain_name=domain_name,
|
||||||
|
user_handler=user_handler,
|
||||||
|
user_id_mapper=user_id_mapper,
|
||||||
|
)
|
||||||
|
|
||||||
|
zerver_attachments: List[ZerverFieldsT] = []
|
||||||
|
uploads_list: List[ZerverFieldsT] = []
|
||||||
|
|
||||||
|
upload_id_to_upload_data_map = map_upload_id_to_upload_data(rocketchat_data["upload"])
|
||||||
|
|
||||||
|
message_with_attachment = rocketchat_data["message"][55]
|
||||||
|
|
||||||
|
process_message_attachment(
|
||||||
|
upload=message_with_attachment["file"],
|
||||||
|
realm_id=3,
|
||||||
|
message_id=1,
|
||||||
|
user_id=3,
|
||||||
|
user_handler=user_handler,
|
||||||
|
zerver_attachment=zerver_attachments,
|
||||||
|
uploads_list=uploads_list,
|
||||||
|
upload_id_to_upload_data_map=upload_id_to_upload_data_map,
|
||||||
|
output_dir=output_dir,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assert_length(zerver_attachments, 1)
|
||||||
|
self.assertEqual(zerver_attachments[0]["file_name"], "harry-ron.jpg")
|
||||||
|
self.assertEqual(zerver_attachments[0]["owner"], 3)
|
||||||
|
self.assertEqual(
|
||||||
|
user_handler.get_user(zerver_attachments[0]["owner"])["email"], "harrypotter@email.com"
|
||||||
|
)
|
||||||
|
# TODO: Assert this for False after fixing the file permissions in PMs
|
||||||
|
self.assertTrue(zerver_attachments[0]["is_realm_public"])
|
||||||
|
|
||||||
|
self.assert_length(uploads_list, 1)
|
||||||
|
self.assertEqual(uploads_list[0]["user_profile_email"], "harrypotter@email.com")
|
||||||
|
|
||||||
|
attachment_out_path = os.path.join(output_dir, "uploads", zerver_attachments[0]["path_id"])
|
||||||
|
self.assertTrue(os.path.exists(attachment_out_path))
|
||||||
|
self.assertTrue(os.path.isfile(attachment_out_path))
|
||||||
|
|
||||||
def read_file(self, team_output_dir: str, output_file: str) -> Any:
|
def read_file(self, team_output_dir: str, output_file: str) -> Any:
|
||||||
full_path = os.path.join(team_output_dir, output_file)
|
full_path = os.path.join(team_output_dir, output_file)
|
||||||
with open(full_path, "rb") as f:
|
with open(full_path, "rb") as f:
|
||||||
@ -760,6 +835,7 @@ class RocketChatImporter(ZulipTestCase):
|
|||||||
|
|
||||||
self.assertEqual(os.path.exists(os.path.join(output_dir, "avatars")), True)
|
self.assertEqual(os.path.exists(os.path.join(output_dir, "avatars")), True)
|
||||||
self.assertEqual(os.path.exists(os.path.join(output_dir, "emoji")), True)
|
self.assertEqual(os.path.exists(os.path.join(output_dir, "emoji")), True)
|
||||||
|
self.assertEqual(os.path.exists(os.path.join(output_dir, "uploads")), True)
|
||||||
self.assertEqual(os.path.exists(os.path.join(output_dir, "attachment.json")), True)
|
self.assertEqual(os.path.exists(os.path.join(output_dir, "attachment.json")), True)
|
||||||
|
|
||||||
realm = self.read_file(output_dir, "realm.json")
|
realm = self.read_file(output_dir, "realm.json")
|
||||||
@ -867,23 +943,41 @@ class RocketChatImporter(ZulipTestCase):
|
|||||||
for message in messages:
|
for message in messages:
|
||||||
self.assertIsNotNone(message.rendered_content)
|
self.assertIsNotNone(message.rendered_content)
|
||||||
# After removing user_joined, added_user, discussion_created, etc.
|
# After removing user_joined, added_user, discussion_created, etc.
|
||||||
# messages. (Total messages were 58.)
|
# messages. (Total messages were 63.)
|
||||||
self.assert_length(messages, 31)
|
self.assert_length(messages, 36)
|
||||||
|
|
||||||
stream_messages = messages.filter(recipient__type=Recipient.STREAM).order_by("date_sent")
|
stream_messages = messages.filter(recipient__type=Recipient.STREAM).order_by("date_sent")
|
||||||
stream_recipients = stream_messages.values_list("recipient", flat=True)
|
stream_recipients = stream_messages.values_list("recipient", flat=True)
|
||||||
self.assert_length(stream_messages, 26)
|
self.assert_length(stream_messages, 30)
|
||||||
self.assert_length(set(stream_recipients), 5)
|
self.assert_length(set(stream_recipients), 5)
|
||||||
self.assertEqual(stream_messages[0].sender.email, "priyansh3133@email.com")
|
self.assertEqual(stream_messages[0].sender.email, "priyansh3133@email.com")
|
||||||
self.assertEqual(stream_messages[0].content, "Hey everyone, how's it going??")
|
self.assertEqual(stream_messages[0].content, "Hey everyone, how's it going??")
|
||||||
|
|
||||||
|
self.assertEqual(stream_messages[23].sender.email, "harrypotter@email.com")
|
||||||
|
self.assertRegex(
|
||||||
|
stream_messages[23].content,
|
||||||
|
"Just a random pic!\n\n\\[harry-ron.jpg\\]\\(.*\\)",
|
||||||
|
)
|
||||||
|
self.assertTrue(stream_messages[23].has_attachment)
|
||||||
|
self.assertTrue(stream_messages[23].has_image)
|
||||||
|
self.assertTrue(stream_messages[23].has_link)
|
||||||
|
|
||||||
huddle_messages = messages.filter(recipient__type=Recipient.HUDDLE).order_by("date_sent")
|
huddle_messages = messages.filter(recipient__type=Recipient.HUDDLE).order_by("date_sent")
|
||||||
huddle_recipients = huddle_messages.values_list("recipient", flat=True)
|
huddle_recipients = huddle_messages.values_list("recipient", flat=True)
|
||||||
self.assert_length(huddle_messages, 2)
|
self.assert_length(huddle_messages, 3)
|
||||||
self.assert_length(set(huddle_recipients), 1)
|
self.assert_length(set(huddle_recipients), 1)
|
||||||
self.assertEqual(huddle_messages[0].sender.email, "hermionegranger@email.com")
|
self.assertEqual(huddle_messages[0].sender.email, "hermionegranger@email.com")
|
||||||
self.assertEqual(huddle_messages[0].content, "Hey people!")
|
self.assertEqual(huddle_messages[0].content, "Hey people!")
|
||||||
|
|
||||||
|
self.assertEqual(huddle_messages[2].sender.email, "harrypotter@email.com")
|
||||||
|
self.assertRegex(
|
||||||
|
huddle_messages[2].content,
|
||||||
|
"This year's curriculum is out.\n\n\\[Hogwarts Curriculum.pdf\\]\\(.*\\)",
|
||||||
|
)
|
||||||
|
self.assertTrue(huddle_messages[2].has_attachment)
|
||||||
|
self.assertFalse(huddle_messages[2].has_image)
|
||||||
|
self.assertTrue(huddle_messages[2].has_link)
|
||||||
|
|
||||||
personal_messages = messages.filter(recipient__type=Recipient.PERSONAL).order_by(
|
personal_messages = messages.filter(recipient__type=Recipient.PERSONAL).order_by(
|
||||||
"date_sent"
|
"date_sent"
|
||||||
)
|
)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user