mirror of
				https://github.com/zulip/zulip.git
				synced 2025-11-04 05:53:43 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			95 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			95 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
# -*- coding: utf-8 -*-
 | 
						|
# Generated by Django 1.10.5 on 2017-02-27 17:03
 | 
						|
 | 
						|
import os
 | 
						|
from typing import Text
 | 
						|
 | 
						|
from boto.s3.connection import S3Connection
 | 
						|
from django.conf import settings
 | 
						|
from django.db import migrations
 | 
						|
from django.db.backends.postgresql_psycopg2.schema import DatabaseSchemaEditor
 | 
						|
from django.db.migrations.state import StateApps
 | 
						|
 | 
						|
from zerver.lib.avatar_hash import user_avatar_hash, user_avatar_path
 | 
						|
 | 
						|
def mkdirs(path: Text) -> None:
 | 
						|
    dirname = os.path.dirname(path)
 | 
						|
    if not os.path.isdir(dirname):
 | 
						|
        os.makedirs(dirname)
 | 
						|
 | 
						|
class MissingAvatarException(Exception):
 | 
						|
    pass
 | 
						|
 | 
						|
def move_local_file(type: Text, path_src: Text, path_dst: Text) -> None:
 | 
						|
    src_file_path = os.path.join(settings.LOCAL_UPLOADS_DIR, type, path_src)
 | 
						|
    dst_file_path = os.path.join(settings.LOCAL_UPLOADS_DIR, type, path_dst)
 | 
						|
    if os.path.exists(dst_file_path):
 | 
						|
        return
 | 
						|
    if not os.path.exists(src_file_path):
 | 
						|
        # This is likely caused by a user having previously changed their email
 | 
						|
        raise MissingAvatarException()
 | 
						|
    mkdirs(dst_file_path)
 | 
						|
    os.rename(src_file_path, dst_file_path)
 | 
						|
 | 
						|
def move_avatars_to_be_uid_based(apps: StateApps, schema_editor: DatabaseSchemaEditor) -> None:
 | 
						|
    user_profile_model = apps.get_model('zerver', 'UserProfile')
 | 
						|
    if settings.LOCAL_UPLOADS_DIR is not None:
 | 
						|
        for user_profile in user_profile_model.objects.filter(avatar_source="U"):
 | 
						|
            src_file_name = user_avatar_hash(user_profile.email)
 | 
						|
            dst_file_name = user_avatar_path(user_profile)
 | 
						|
            try:
 | 
						|
                move_local_file('avatars', src_file_name + '.original', dst_file_name + '.original')
 | 
						|
                move_local_file('avatars', src_file_name + '-medium.png', dst_file_name + '-medium.png')
 | 
						|
                move_local_file('avatars', src_file_name + '.png', dst_file_name + '.png')
 | 
						|
            except MissingAvatarException:
 | 
						|
                # If the user's avatar is missing, it's probably
 | 
						|
                # because they previously changed their email address.
 | 
						|
                # So set them to have a gravatar instead.
 | 
						|
                user_profile.avatar_source = "G"
 | 
						|
                user_profile.save(update_fields=["avatar_source"])
 | 
						|
    else:
 | 
						|
        conn = S3Connection(settings.S3_KEY, settings.S3_SECRET_KEY)
 | 
						|
        bucket_name = settings.S3_AVATAR_BUCKET
 | 
						|
        bucket = conn.get_bucket(bucket_name, validate=False)
 | 
						|
        for user_profile in user_profile_model.objects.filter(avatar_source="U"):
 | 
						|
            uid_hash_path = user_avatar_path(user_profile)
 | 
						|
            email_hash_path = user_avatar_hash(user_profile.email)
 | 
						|
            if bucket.get_key(uid_hash_path):
 | 
						|
                continue
 | 
						|
            if not bucket.get_key(email_hash_path):
 | 
						|
                # This is likely caused by a user having previously changed their email
 | 
						|
                # If the user's avatar is missing, it's probably
 | 
						|
                # because they previously changed their email address.
 | 
						|
                # So set them to have a gravatar instead.
 | 
						|
                user_profile.avatar_source = "G"
 | 
						|
                user_profile.save(update_fields=["avatar_source"])
 | 
						|
                continue
 | 
						|
 | 
						|
            bucket.copy_key(uid_hash_path + ".original",
 | 
						|
                            bucket_name,
 | 
						|
                            email_hash_path + ".original")
 | 
						|
            bucket.copy_key(uid_hash_path + "-medium.png",
 | 
						|
                            bucket_name,
 | 
						|
                            email_hash_path + "-medium.png")
 | 
						|
            bucket.copy_key(uid_hash_path,
 | 
						|
                            bucket_name,
 | 
						|
                            email_hash_path)
 | 
						|
 | 
						|
        # From an error handling sanity perspective, it's best to
 | 
						|
        # start deleting after everything is copied, so that recovery
 | 
						|
        # from failures is easy (just rerun one loop or the other).
 | 
						|
        for user_profile in user_profile_model.objects.filter(avatar_source="U"):
 | 
						|
            bucket.delete_key(user_avatar_hash(user_profile.email) + ".original")
 | 
						|
            bucket.delete_key(user_avatar_hash(user_profile.email) + "-medium.png")
 | 
						|
            bucket.delete_key(user_avatar_hash(user_profile.email))
 | 
						|
 | 
						|
class Migration(migrations.Migration):
 | 
						|
 | 
						|
    dependencies = [
 | 
						|
        ('zerver', '0059_userprofile_quota'),
 | 
						|
    ]
 | 
						|
 | 
						|
    operations = [
 | 
						|
        migrations.RunPython(move_avatars_to_be_uid_based)
 | 
						|
    ]
 |