Files
zulip/zerver/actions/data_import.py
Aman Agrawal 4cca5652e3 slack_import: Pipe file processing error message to the user.
When the slack import fails due to invalid zip file being uploaded,
we take user back to the file upload page with an appropriate
error message.
2025-06-16 10:46:25 -07:00

95 lines
3.8 KiB
Python

import logging
import shutil
import tempfile
from typing import Any
from django.conf import settings
from confirmation import settings as confirmation_settings
from zerver.actions.realm_settings import do_delete_all_realm_attachments
from zerver.actions.users import do_change_user_role
from zerver.context_processors import is_realm_import_enabled
from zerver.data_import.slack import do_convert_zipfile
from zerver.lib.exceptions import SlackImportInvalidFileError
from zerver.lib.import_realm import do_import_realm
from zerver.lib.upload import save_attachment_contents
from zerver.models.prereg_users import PreregistrationRealm
from zerver.models.realms import Realm
from zerver.models.users import UserProfile, get_user_by_delivery_email
logger = logging.getLogger(__name__)
def import_slack_data(event: dict[str, Any]) -> None:
# This is only possible if data imports were enqueued before the
# setting was turned off.
assert is_realm_import_enabled()
preregistration_realm = PreregistrationRealm.objects.get(id=event["preregistration_realm_id"])
string_id = preregistration_realm.string_id
output_dir = tempfile.mkdtemp(
prefix=f"import-{preregistration_realm.id}-converted-",
dir=settings.IMPORT_TMPFILE_DIRECTORY,
)
try:
with tempfile.NamedTemporaryFile(
prefix=f"import-{preregistration_realm.id}-slack-",
suffix=".zip",
dir=settings.IMPORT_TMPFILE_DIRECTORY,
) as fh:
save_attachment_contents(event["filename"], fh)
fh.flush()
do_convert_zipfile(
fh.name,
output_dir,
event["slack_access_token"],
)
realm = do_import_realm(output_dir, string_id)
realm.org_type = preregistration_realm.org_type
realm.default_language = preregistration_realm.default_language
realm.save()
# Try finding the user who imported this realm and make them owner.
try:
importing_user = get_user_by_delivery_email(preregistration_realm.email, realm)
assert (
importing_user.is_active
and not importing_user.is_bot
and not importing_user.is_mirror_dummy
)
if importing_user.role != UserProfile.ROLE_REALM_OWNER:
do_change_user_role(
importing_user, UserProfile.ROLE_REALM_OWNER, acting_user=importing_user
)
preregistration_realm.status = confirmation_settings.STATUS_USED
except UserProfile.DoesNotExist:
# If the email address that the importing user
# validated with Zulip does not appear in the data
# export, we will prompt them which account is theirs.
preregistration_realm.data_import_metadata["need_select_realm_owner"] = True
preregistration_realm.created_realm = realm
preregistration_realm.data_import_metadata["is_import_work_queued"] = False
preregistration_realm.save()
except Exception as e:
logger.exception(e)
try:
# Clean up the realm if the import failed
preregistration_realm.created_realm = None
preregistration_realm.data_import_metadata["is_import_work_queued"] = False
if type(e) is SlackImportInvalidFileError:
# Store the error to be displayed to the user.
preregistration_realm.data_import_metadata["invalid_file_error_message"] = str(e)
preregistration_realm.save()
realm = Realm.objects.get(string_id=string_id)
do_delete_all_realm_attachments(realm)
realm.delete()
except Realm.DoesNotExist:
pass
raise
finally:
shutil.rmtree(output_dir)