diff --git a/settings/common.py b/settings/common.py index 07ac5e41..95fad2bd 100644 --- a/settings/common.py +++ b/settings/common.py @@ -311,12 +311,14 @@ SOUTH_MIGRATION_MODULES = { } DEFAULT_AVATAR_SIZE = 80 # 80x80 pixels +DEFAULT_BIG_AVATAR_SIZE = 300 # 300x300 pixels DEFAULT_AVATAR_URL = '' THUMBNAIL_ALIASES = { '': { 'avatar': {'size': (DEFAULT_AVATAR_SIZE, DEFAULT_AVATAR_SIZE), 'crop': True}, + 'big-avatar': {'size': (DEFAULT_BIG_AVATAR_SIZE, DEFAULT_BIG_AVATAR_SIZE), 'crop': True}, }, } diff --git a/taiga/users/api.py b/taiga/users/api.py index 46808f2c..76481141 100644 --- a/taiga/users/api.py +++ b/taiga/users/api.py @@ -153,6 +153,23 @@ class UsersViewSet(ModelCrudViewSet): request.user.save(update_fields=["password"]) return Response(status=status.HTTP_204_NO_CONTENT) + @list_route(methods=["POST"]) + def change_avatar(self, request): + """ + Change avatar to current logged user. + """ + self.check_permissions(request, "change_avatar", None) + + avatar = request.FILES['avatar'] + + if not avatar: + raise exc.WrongArguments(_("Incomplete arguments")) + + request.user.photo = avatar + request.user.save(update_fields=["photo"]) + user_data = serializers.UserSerializer(request.user).data + return Response(user_data, status=status.HTTP_200_OK) + @detail_route(methods=["GET"]) def starred(self, request, pk=None): user = self.get_object() diff --git a/taiga/users/permissions.py b/taiga/users/permissions.py index f3c2d921..f10a31da 100644 --- a/taiga/users/permissions.py +++ b/taiga/users/permissions.py @@ -35,4 +35,5 @@ class UserPermission(ResourcePermission): password_recovery_perms = AllowAny() change_password_from_recovery_perms = AllowAny() change_password_perms = IsAuthenticated() + change_avatar_perms = IsAuthenticated() starred_perms = AllowAny() diff --git a/taiga/users/serializers.py b/taiga/users/serializers.py index 1128d274..70b2879f 100644 --- a/taiga/users/serializers.py +++ b/taiga/users/serializers.py @@ -19,18 +19,19 @@ from django.utils.translation import ugettext_lazy as _ from rest_framework import serializers from .models import User -from .services import get_photo_or_gravatar_url +from .services import get_photo_or_gravatar_url, get_big_photo_or_gravatar_url class UserSerializer(serializers.ModelSerializer): full_name_display = serializers.SerializerMethodField("get_full_name_display") photo = serializers.SerializerMethodField("get_photo") + big_photo = serializers.SerializerMethodField("get_big_photo") class Meta: model = User fields = ('id', 'username', 'full_name', 'full_name_display', 'email', 'github_id', 'color', 'bio', 'default_language', 'default_timezone', - 'is_active', 'photo') + 'is_active', 'photo', 'big_photo') def get_full_name_display(self, obj): return obj.get_full_name() if obj else "" @@ -38,6 +39,9 @@ class UserSerializer(serializers.ModelSerializer): def get_photo(self, user): return get_photo_or_gravatar_url(user) + def get_big_photo(self, user): + return get_big_photo_or_gravatar_url(user) + class RecoverySerializer(serializers.Serializer): token = serializers.CharField(max_length=200) diff --git a/taiga/users/services.py b/taiga/users/services.py index 3394718b..ce670e94 100644 --- a/taiga/users/services.py +++ b/taiga/users/services.py @@ -20,6 +20,7 @@ This model contains a domain logic for users application. from django.db.models.loading import get_model from django.db.models import Q +from django.conf import settings from easy_thumbnails.files import get_thumbnailer @@ -62,3 +63,16 @@ def get_photo_or_gravatar_url(user): if user: return get_photo_url(user.photo) if user.photo else get_gravatar_url(user.email) return "" + + +def get_big_photo_url(photo): + """Get a big photo absolute url and the photo automatically cropped.""" + url = get_thumbnailer(photo)['big-avatar'].url + return get_absolute_url(url) + + +def get_big_photo_or_gravatar_url(user): + """Get the user's big photo/gravatar url.""" + if user: + return get_big_photo_url(user.photo) if user.photo else get_gravatar_url(user.email, size=settings.DEFAULT_BIG_AVATAR_SIZE) + return ""