From 3483783a282867dcafd06dbad5275157f69b7285 Mon Sep 17 00:00:00 2001 From: lian Date: Fri, 12 May 2017 18:16:59 +0800 Subject: [PATCH] add create user avatar api --- seahub/api2/urls.py | 2 +- seahub/api2/views.py | 50 ++++++++++++++++++++++++++++++++++++---- tests/api/test_avatar.py | 19 +++++++++++---- 3 files changed, 61 insertions(+), 10 deletions(-) diff --git a/seahub/api2/urls.py b/seahub/api2/urls.py index fa09710578..33284ac17c 100644 --- a/seahub/api2/urls.py +++ b/seahub/api2/urls.py @@ -90,7 +90,7 @@ urlpatterns = patterns('', url(r'^repo_history_changes/(?P[-0-9a-f]{36})/$', RepoHistoryChange.as_view()), url(r'^unseen_messages/$', UnseenMessagesCountView.as_view()), - url(r'^avatars/user/(?P\S+@[a-zA-Z0-9._-]+\.[a-zA-Z0-9._-]+)/resized/(?P[0-9]+)/$', UserAvatarView.as_view()), + url(r'^avatars/user/(?P\S+@[a-zA-Z0-9._-]+\.[a-zA-Z0-9._-]+)/resized/(?P[0-9]+)/$', UserAvatarView.as_view(), name="api2-user-avatar"), url(r'^avatars/group/(?P\d+)/resized/(?P[0-9]+)/$', GroupAvatarView.as_view()), url(r'^groups/$', Groups.as_view()), diff --git a/seahub/api2/views.py b/seahub/api2/views.py index 9ea7d0b1f7..bc2269157d 100644 --- a/seahub/api2/views.py +++ b/seahub/api2/views.py @@ -42,9 +42,13 @@ from .utils import get_diff_details, \ from seahub.api2.base import APIView from seahub.api2.models import TokenV2, DESKTOP_PLATFORMS +from seahub.avatar.models import Avatar +from seahub.avatar.signals import avatar_updated from seahub.avatar.templatetags.avatar_tags import api_avatar_url, avatar -from seahub.avatar.templatetags.group_avatar_tags import api_grp_avatar_url, \ - grp_avatar +from seahub.avatar.templatetags.group_avatar_tags import api_grp_avatar_url, grp_avatar +from seahub.avatar.settings import (AVATAR_MAX_AVATARS_PER_USER, + AVATAR_MAX_SIZE, AVATAR_ALLOWED_FILE_EXTS) + from seahub.base.accounts import User from seahub.base.models import UserStarredFiles, DeviceToken from seahub.base.templatetags.seahub_tags import email2nickname, \ @@ -3844,9 +3848,9 @@ class GroupRepo(APIView): content_type=json_content_type) class UserAvatarView(APIView): - authentication_classes = (TokenAuthentication, ) + authentication_classes = (TokenAuthentication, SessionAuthentication) permission_classes = (IsAuthenticated,) - throttle_classes = (UserRateThrottle, ) + throttle_classes = (UserRateThrottle,) def get(self, request, user, size, format=None): url, is_default, date_uploaded = api_avatar_url(user, int(size)) @@ -3856,6 +3860,44 @@ class UserAvatarView(APIView): "mtime": get_timestamp(date_uploaded) } return Response(ret) + def post(self, request, user, size, format=None): + + image_file = request.FILES.get('avatar', None) + if not image_file: + error_msg = 'avatar invalid.' + return api_error(status.HTTP_400_BAD_REQUEST, error_msg) + + (root, ext) = os.path.splitext(image_file.name.lower()) + if AVATAR_ALLOWED_FILE_EXTS and ext not in AVATAR_ALLOWED_FILE_EXTS: + error_msg = _(u"%(ext)s is an invalid file extension. Authorized extensions are : %(valid_exts_list)s") % {'ext' : ext, 'valid_exts_list' : ", ".join(AVATAR_ALLOWED_FILE_EXTS)} + return api_error(status.HTTP_400_BAD_REQUEST, error_msg) + + if image_file.size > AVATAR_MAX_SIZE: + error_msg = _(u"Your file is too big (%(size)s), the maximum allowed size is %(max_valid_size)s") % { 'size' : filesizeformat(image_file.size), 'max_valid_size' : filesizeformat(AVATAR_MAX_SIZE)} + return api_error(status.HTTP_400_BAD_REQUEST, error_msg) + + username = request.user.username + count = Avatar.objects.filter(emailuser=username).count() + if AVATAR_MAX_AVATARS_PER_USER > 1 and count >= AVATAR_MAX_AVATARS_PER_USER: + error_msg = _(u"You already have %(nb_avatars)d avatars, and the maximum allowed is %(nb_max_avatars)d.") % { 'nb_avatars' : count, 'nb_max_avatars' : AVATAR_MAX_AVATARS_PER_USER} + return api_error(status.HTTP_400_BAD_REQUEST, error_msg) + + avatar = Avatar( + emailuser = username, + primary = True, + ) + avatar.avatar.save(image_file.name, image_file) + avatar.save() + avatar_updated.send(sender=Avatar, user=request.user, avatar=avatar) + + url, is_default, date_uploaded = api_avatar_url(request.user, int(size)) + ret = { + "url": request.build_absolute_uri(url), + "mtime": get_timestamp(date_uploaded) + } + + return Response(ret) + class GroupAvatarView(APIView): authentication_classes = (TokenAuthentication, ) permission_classes = (IsAuthenticated,) diff --git a/tests/api/test_avatar.py b/tests/api/test_avatar.py index 4cda2996e5..c06e414179 100644 --- a/tests/api/test_avatar.py +++ b/tests/api/test_avatar.py @@ -1,18 +1,27 @@ -import unittest - +import os from tests.api.apitestbase import ApiTestBase from tests.api.urls import AVATAR_BASE_URL, GROUPS_URL -from tests.common.utils import randstring, apiurl, urljoin +from tests.common.utils import randstring, urljoin class AvatarApiTest(ApiTestBase): - def test_user_avatar(self): + + def test_get_user_avatar(self): avatar_url = urljoin(AVATAR_BASE_URL, 'user', self.username, '/resized/80/') info = self.get(avatar_url).json() self.assertIsNotNone(info['url']) self.assertIsNotNone(info['is_default']) self.assertIsNotNone(info['mtime']) - def test_group_avatar(self): + def test_create_user_avatar(self): + avatar_url = urljoin(AVATAR_BASE_URL, 'user', self.username, '/resized/80/') + avatar_file = os.path.join(os.getcwd(), 'media/img/seafile-logo.png') + + with open(avatar_file) as f: + json_resp = self.post(avatar_url, files={'avatar': f}).json() + + assert 'media/avatars' in json_resp['url'] + + def test_get_group_avatar(self): gname = randstring(16) data = {'group_name': gname} res = self.put(GROUPS_URL, data=data)