import: Ensure presence of basic avatar images for HipChat.

Our HipChat conversion tool didn't properly handle basic avatar
images, resulting in only the medium-size avatar images being imported
properly.  This fixes that bug by asking the import tool to do the
thumbnailing for the basic avatar image (from the .original file) as
well as the medium avatar image.
This commit is contained in:
Tim Abbott
2018-11-26 17:28:34 -08:00
parent e8f2d6f32b
commit c995e8e2ae
3 changed files with 40 additions and 0 deletions

View File

@@ -471,6 +471,8 @@ def write_avatar_png(avatar_folder: str,
s3_path=image_path, s3_path=image_path,
realm_id=realm_id, realm_id=realm_id,
user_profile_id=user_id, user_profile_id=user_id,
# We only write the .original file; ask the importer to do the thumbnailing.
importer_should_thumbnail=True,
) )
return metadata return metadata

View File

@@ -633,6 +633,8 @@ def import_uploads(import_dir: Path, processing_avatars: bool=False,
# same realm ID from a previous iteration). # same realm ID from a previous iteration).
os.remove(medium_file_path) os.remove(medium_file_path)
upload_backend.ensure_medium_avatar_image(user_profile=user_profile) upload_backend.ensure_medium_avatar_image(user_profile=user_profile)
if record.get("importer_should_thumbnail"):
upload_backend.ensure_basic_avatar_image(user_profile=user_profile)
# Importing data suffers from a difficult ordering problem because of # Importing data suffers from a difficult ordering problem because of
# models that reference each other circularly. Here is a correct order. # models that reference each other circularly. Here is a correct order.

View File

@@ -194,6 +194,9 @@ class ZulipUploadBackend:
def ensure_medium_avatar_image(self, user_profile: UserProfile) -> None: def ensure_medium_avatar_image(self, user_profile: UserProfile) -> None:
raise NotImplementedError() raise NotImplementedError()
def ensure_basic_avatar_image(self, user_profile: UserProfile) -> None:
raise NotImplementedError()
def upload_realm_icon_image(self, icon_file: File, user_profile: UserProfile) -> None: def upload_realm_icon_image(self, icon_file: File, user_profile: UserProfile) -> None:
raise NotImplementedError() raise NotImplementedError()
@@ -491,6 +494,26 @@ class S3UploadBackend(ZulipUploadBackend):
resized_medium resized_medium
) )
def ensure_basic_avatar_image(self, user_profile: UserProfile) -> None: # nocoverage
# TODO: Refactor this to share code with ensure_medium_avatar_image
file_path = user_avatar_path(user_profile)
s3_file_name = file_path
bucket_name = settings.S3_AVATAR_BUCKET
conn = S3Connection(settings.S3_KEY, settings.S3_SECRET_KEY)
bucket = get_bucket(conn, bucket_name)
key = bucket.get_key(file_path)
image_data = key.get_contents_as_string()
resized_avatar = resize_avatar(image_data) # type: ignore # image_data is `bytes`, boto subs are wrong
upload_image_to_s3(
bucket_name,
s3_file_name + ".png",
"image/png",
user_profile,
resized_avatar
)
def upload_emoji_image(self, emoji_file: File, emoji_file_name: str, def upload_emoji_image(self, emoji_file: File, emoji_file_name: str,
user_profile: UserProfile) -> None: user_profile: UserProfile) -> None:
content_type = guess_type(emoji_file.name)[0] content_type = guess_type(emoji_file.name)[0]
@@ -653,6 +676,19 @@ class LocalUploadBackend(ZulipUploadBackend):
resized_medium = resize_avatar(image_data, MEDIUM_AVATAR_SIZE) resized_medium = resize_avatar(image_data, MEDIUM_AVATAR_SIZE)
write_local_file('avatars', file_path + '-medium.png', resized_medium) write_local_file('avatars', file_path + '-medium.png', resized_medium)
def ensure_basic_avatar_image(self, user_profile: UserProfile) -> None: # nocoverage
# TODO: Refactor this to share code with ensure_medium_avatar_image
file_path = user_avatar_path(user_profile)
output_path = os.path.join(settings.LOCAL_UPLOADS_DIR, "avatars", file_path + ".png")
if os.path.isfile(output_path):
return
image_path = os.path.join(settings.LOCAL_UPLOADS_DIR, "avatars", file_path + ".original")
image_data = open(image_path, "rb").read()
resized_avatar = resize_avatar(image_data)
write_local_file('avatars', file_path + '.png', resized_avatar)
def upload_emoji_image(self, emoji_file: File, emoji_file_name: str, def upload_emoji_image(self, emoji_file: File, emoji_file_name: str,
user_profile: UserProfile) -> None: user_profile: UserProfile) -> None:
emoji_path = RealmEmoji.PATH_ID_TEMPLATE.format( emoji_path = RealmEmoji.PATH_ID_TEMPLATE.format(