diff --git a/server/szurubooru/func/files.py b/server/szurubooru/func/files.py index f520932..a010187 100644 --- a/server/szurubooru/func/files.py +++ b/server/szurubooru/func/files.py @@ -12,6 +12,9 @@ def delete(path): def has(path): return os.path.exists(_get_full_path(path)) +def move(source_path, target_path): + return os.rename(_get_full_path(source_path), _get_full_path(target_path)) + def get(path): full_path = _get_full_path(path) if not os.path.exists(full_path): diff --git a/server/szurubooru/func/users.py b/server/szurubooru/func/users.py index a85adae..f625ebf 100644 --- a/server/szurubooru/func/users.py +++ b/server/szurubooru/func/users.py @@ -12,6 +12,9 @@ class InvalidPasswordError(errors.ValidationError): pass class InvalidRankError(errors.ValidationError): pass class InvalidAvatarError(errors.ValidationError): pass +def _get_avatar_path(name): + return 'avatars/' + name.lower() + '.png' + def _get_avatar_url(user): if user.avatar_style == user.AVATAR_GRAVATAR: return 'http://gravatar.com/avatar/%s?d=retro&s=%d' % ( @@ -121,6 +124,8 @@ def update_user_name(user, name): if not re.match(name_regex, name): raise InvalidUserNameError( 'User name %r must satisfy regex %r.' % (name, name_regex)) + if user.name and files.has(_get_avatar_path(user.name)): + files.move(_get_avatar_path(user.name), _get_avatar_path(name)) user.name = name def update_user_password(user, password): diff --git a/server/szurubooru/tests/api/test_user_creating.py b/server/szurubooru/tests/api/test_user_creating.py index e70f660..b2211f5 100644 --- a/server/szurubooru/tests/api/test_user_creating.py +++ b/server/szurubooru/tests/api/test_user_creating.py @@ -9,7 +9,7 @@ EMPTY_PIXEL = \ b'\x01\x00\x01\x00\x00\x02\x02\x4c\x01\x00\x3b' @pytest.fixture -def test_ctx(config_injector, context_factory, user_factory): +def test_ctx(tmpdir, config_injector, context_factory, user_factory): config_injector({ 'secret': '', 'user_name_regex': '[^!]{3,}', @@ -17,6 +17,8 @@ def test_ctx(config_injector, context_factory, user_factory): 'default_rank': db.User.RANK_REGULAR, 'thumbnails': {'avatar_width': 200, 'avatar_height': 200}, 'privileges': {'users:create': 'anonymous'}, + 'data_dir': str(tmpdir.mkdir('data')), + 'data_url': 'http://example.com/data/', }) ret = util.dotdict() ret.context_factory = context_factory @@ -170,9 +172,7 @@ def test_trying_to_omit_mandatory_field(test_ctx, field): user=test_ctx.user_factory(rank=db.User.RANK_REGULAR))) @pytest.mark.parametrize('field', ['rank', 'email', 'avatarStyle']) -def test_omitting_optional_field(test_ctx, tmpdir, field): - config.config['data_dir'] = str(tmpdir.mkdir('data')) - config.config['data_url'] = 'http://example.com/data/' +def test_omitting_optional_field(test_ctx, field): input = { 'name': 'chewie', 'email': 'asd@asd.asd', @@ -213,9 +213,7 @@ def test_admin_creating_mod_account(test_ctx): result = test_ctx.api.post(context) assert result['rank'] == 'moderator' -def test_uploading_avatar(test_ctx, tmpdir): - config.config['data_dir'] = str(tmpdir.mkdir('data')) - config.config['data_url'] = 'http://example.com/data/' +def test_uploading_avatar(test_ctx): response = test_ctx.api.post( test_ctx.context_factory( input={ diff --git a/server/szurubooru/tests/api/test_user_updating.py b/server/szurubooru/tests/api/test_user_updating.py index 2cb449f..d553928 100644 --- a/server/szurubooru/tests/api/test_user_updating.py +++ b/server/szurubooru/tests/api/test_user_updating.py @@ -9,7 +9,7 @@ EMPTY_PIXEL = \ b'\x01\x00\x01\x00\x00\x02\x02\x4c\x01\x00\x3b' @pytest.fixture -def test_ctx(config_injector, context_factory, user_factory): +def test_ctx(tmpdir, config_injector, context_factory, user_factory): config_injector({ 'secret': '', 'user_name_regex': '^[^!]{3,}$', @@ -27,6 +27,8 @@ def test_ctx(config_injector, context_factory, user_factory): 'users:edit:any:rank': db.User.RANK_ADMINISTRATOR, 'users:edit:any:avatar': db.User.RANK_ADMINISTRATOR, }, + 'data_dir': str(tmpdir.mkdir('data')), + 'data_url': 'http://example.com/data/', }) ret = util.dotdict() ret.context_factory = context_factory @@ -100,9 +102,7 @@ def test_trying_to_pass_invalid_input(test_ctx, input, expected_exception): @pytest.mark.parametrize( 'field', ['name', 'email', 'password', 'rank', 'avatarStyle']) -def test_omitting_optional_field(test_ctx, tmpdir, field): - config.config['data_dir'] = str(tmpdir.mkdir('data')) - config.config['data_url'] = 'http://example.com/data/' +def test_omitting_optional_field(test_ctx, field): user = test_ctx.user_factory(name='u1', rank=db.User.RANK_ADMINISTRATOR) db.session.add(user) input = { @@ -191,9 +191,7 @@ def test_mods_trying_to_become_admin(test_ctx): with pytest.raises(errors.AuthError): test_ctx.api.put(context, user2.name) -def test_uploading_avatar(test_ctx, tmpdir): - config.config['data_dir'] = str(tmpdir.mkdir('data')) - config.config['data_url'] = 'http://example.com/data/' +def test_uploading_avatar(test_ctx): user = test_ctx.user_factory(name='u1', rank=db.User.RANK_MODERATOR) db.session.add(user) response = test_ctx.api.put(