mirror of
https://git.linux-kernel.at/oliver/ivatar.git
synced 2025-11-17 13:38:03 +00:00
Return resized img, if/as requested and now also return default image (not yet as specified by the url parameters!
This commit is contained in:
@@ -1059,7 +1059,7 @@ class Tester(TestCase): # pylint: disable=too-many-public-methods
|
|||||||
self.user.photo_set.first(),
|
self.user.photo_set.first(),
|
||||||
'set_photo did not work!?')
|
'set_photo did not work!?')
|
||||||
|
|
||||||
def test_avatar_url_mail(self, do_upload_and_confirm=True):
|
def test_avatar_url_mail(self, do_upload_and_confirm=True, size=(80, 80)):
|
||||||
'''
|
'''
|
||||||
Test fetching avatar via mail
|
Test fetching avatar via mail
|
||||||
'''
|
'''
|
||||||
@@ -1068,18 +1068,21 @@ class Tester(TestCase): # pylint: disable=too-many-public-methods
|
|||||||
self.test_confirm_email()
|
self.test_confirm_email()
|
||||||
urlobj = urlsplit(
|
urlobj = urlsplit(
|
||||||
libravatar_url(
|
libravatar_url(
|
||||||
email=self.user.confirmedemail_set.first().email)
|
email=self.user.confirmedemail_set.first().email,
|
||||||
|
size=size[0],
|
||||||
)
|
)
|
||||||
url = urlobj.path
|
)
|
||||||
|
url = '%s?%s' % (urlobj.path, urlobj.query)
|
||||||
response = self.client.get(url, follow=True)
|
response = self.client.get(url, follow=True)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
response.status_code,
|
response.status_code,
|
||||||
200,
|
200,
|
||||||
'unable to fetch avatar?')
|
'unable to fetch avatar?')
|
||||||
|
photodata = Image.open(BytesIO(response.content))
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
response.content,
|
photodata.size,
|
||||||
self.user.photo_set.first().data,
|
size,
|
||||||
'Why is this not the same data?')
|
'Why is this not the correct size?')
|
||||||
|
|
||||||
def test_avatar_url_openid(self):
|
def test_avatar_url_openid(self):
|
||||||
'''
|
'''
|
||||||
@@ -1088,18 +1091,21 @@ class Tester(TestCase): # pylint: disable=too-many-public-methods
|
|||||||
self.test_assign_photo_to_openid()
|
self.test_assign_photo_to_openid()
|
||||||
urlobj = urlsplit(
|
urlobj = urlsplit(
|
||||||
libravatar_url(
|
libravatar_url(
|
||||||
openid=self.user.confirmedopenid_set.first().openid)
|
openid=self.user.confirmedopenid_set.first().openid,
|
||||||
|
size=80,
|
||||||
)
|
)
|
||||||
url = urlobj.path
|
)
|
||||||
|
url = '%s?%s' % (urlobj.path, urlobj.query)
|
||||||
response = self.client.get(url, follow=True)
|
response = self.client.get(url, follow=True)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
response.status_code,
|
response.status_code,
|
||||||
200,
|
200,
|
||||||
'unable to fetch avatar?')
|
'unable to fetch avatar?')
|
||||||
|
photodata = Image.open(BytesIO(response.content))
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
response.content,
|
photodata.size,
|
||||||
self.user.photo_set.first().data,
|
(80, 80),
|
||||||
'Why is this not the same data?')
|
'Why is this not the correct size?')
|
||||||
|
|
||||||
def test_avatar_url_inexisting_mail_digest(self): # pylint: disable=invalid-name
|
def test_avatar_url_inexisting_mail_digest(self): # pylint: disable=invalid-name
|
||||||
'''
|
'''
|
||||||
@@ -1109,14 +1115,20 @@ class Tester(TestCase): # pylint: disable=too-many-public-methods
|
|||||||
self.test_confirm_email()
|
self.test_confirm_email()
|
||||||
urlobj = urlsplit(
|
urlobj = urlsplit(
|
||||||
libravatar_url(
|
libravatar_url(
|
||||||
email=self.user.confirmedemail_set.first().email)
|
email=self.user.confirmedemail_set.first().email,
|
||||||
|
size=80,
|
||||||
|
)
|
||||||
)
|
)
|
||||||
# Simply delete it, then it digest is 'correct', but
|
# Simply delete it, then it digest is 'correct', but
|
||||||
# the hash is no longer there
|
# the hash is no longer there
|
||||||
self.user.confirmedemail_set.first().delete()
|
self.user.confirmedemail_set.first().delete()
|
||||||
url = urlobj.path
|
url = '%s?%s' % (urlobj.path, urlobj.query)
|
||||||
self.assertRaises(Exception, lambda:
|
response = self.client.get(url, follow=True)
|
||||||
self.client.get(url, follow=True))
|
self.assertEqual(
|
||||||
|
response['Content-Type'],
|
||||||
|
'image/png',
|
||||||
|
'Content type wrong!?')
|
||||||
|
# Eventually one should check if the data is the same
|
||||||
|
|
||||||
def test_crop_photo(self):
|
def test_crop_photo(self):
|
||||||
'''
|
'''
|
||||||
@@ -1135,6 +1147,6 @@ class Tester(TestCase): # pylint: disable=too-many-public-methods
|
|||||||
response.status_code,
|
response.status_code,
|
||||||
200,
|
200,
|
||||||
'unable to crop?')
|
'unable to crop?')
|
||||||
self.test_avatar_url_mail(do_upload_and_confirm=False)
|
self.test_avatar_url_mail(do_upload_and_confirm=False, size=(20, 20))
|
||||||
img = Image.open(BytesIO(self.user.photo_set.first().data))
|
img = Image.open(BytesIO(self.user.photo_set.first().data))
|
||||||
self.assertEqual(img.size, (20, 20), 'cropped to 20x20, but resulting image isn\'t 20x20!?')
|
self.assertEqual(img.size, (20, 20), 'cropped to 20x20, but resulting image isn\'t 20x20!?')
|
||||||
|
|||||||
@@ -531,7 +531,7 @@ class CropPhotoView(TemplateView):
|
|||||||
model = Photo
|
model = Photo
|
||||||
|
|
||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
photo = self.model.objects.get(pk=kwargs['pk'], user=request.user)
|
photo = self.model.objects.get(pk=kwargs['pk'], user=request.user) # pylint: disable=no-member
|
||||||
email = request.GET.get('email')
|
email = request.GET.get('email')
|
||||||
openid = request.GET.get('openid')
|
openid = request.GET.get('openid')
|
||||||
return render(self.request, self.template_name, {
|
return render(self.request, self.template_name, {
|
||||||
@@ -541,7 +541,7 @@ class CropPhotoView(TemplateView):
|
|||||||
})
|
})
|
||||||
|
|
||||||
def post(self, request, *args, **kwargs):
|
def post(self, request, *args, **kwargs):
|
||||||
photo = self.model.objects.get(pk=kwargs['pk'], user=request.user)
|
photo = self.model.objects.get(pk=kwargs['pk'], user=request.user) # pylint: disable=no-member
|
||||||
dimensions = {
|
dimensions = {
|
||||||
'x': int(request.POST['x']),
|
'x': int(request.POST['x']),
|
||||||
'y': int(request.POST['y']),
|
'y': int(request.POST['y']),
|
||||||
|
|||||||
@@ -1,29 +1,42 @@
|
|||||||
'''
|
'''
|
||||||
views under /
|
views under /
|
||||||
'''
|
'''
|
||||||
import io
|
from io import BytesIO
|
||||||
|
from os import path
|
||||||
|
from PIL import Image
|
||||||
from django.views.generic.base import TemplateView
|
from django.views.generic.base import TemplateView
|
||||||
from django.http import HttpResponse
|
from django.http import HttpResponse
|
||||||
from . ivataraccount.models import ConfirmedEmail, ConfirmedOpenId
|
|
||||||
from django.core.exceptions import ObjectDoesNotExist
|
from django.core.exceptions import ObjectDoesNotExist
|
||||||
|
from ivatar.settings import AVATAR_MAX_SIZE, JPEG_QUALITY
|
||||||
|
from . ivataraccount.models import ConfirmedEmail, ConfirmedOpenId
|
||||||
|
from . ivataraccount.models import pil_format
|
||||||
|
|
||||||
|
|
||||||
class AvatarImageView(TemplateView):
|
class AvatarImageView(TemplateView):
|
||||||
'''
|
'''
|
||||||
View to return (binary) image, based for OpenID/Email (both by digest)
|
View to return (binary) image, based on OpenID/Email (both by digest)
|
||||||
'''
|
'''
|
||||||
|
# TODO: Do cache resize images!! Memcached?
|
||||||
|
|
||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
'''
|
'''
|
||||||
Override get from parent class
|
Override get from parent class
|
||||||
'''
|
'''
|
||||||
model = ConfirmedEmail
|
model = ConfirmedEmail
|
||||||
|
size = 80
|
||||||
|
imgformat = 'png'
|
||||||
|
obj = None
|
||||||
|
if 's' in request.GET:
|
||||||
|
size = request.GET['s']
|
||||||
|
size = int(size)
|
||||||
|
if size > int(AVATAR_MAX_SIZE):
|
||||||
|
size = int(AVATAR_MAX_SIZE)
|
||||||
if len(kwargs['digest']) == 32:
|
if len(kwargs['digest']) == 32:
|
||||||
# Fetch by digest from mail
|
# Fetch by digest from mail
|
||||||
pass
|
pass
|
||||||
elif len(kwargs['digest']) == 64:
|
elif len(kwargs['digest']) == 64:
|
||||||
if ConfirmedOpenId.objects.filter(
|
if ConfirmedOpenId.objects.filter( # pylint: disable=no-member
|
||||||
digest=kwargs['digest']).count(): # pylint: disable=no-member
|
digest=kwargs['digest']).count():
|
||||||
# Fetch by digest from OpenID
|
# Fetch by digest from OpenID
|
||||||
model = ConfirmedOpenId
|
model = ConfirmedOpenId
|
||||||
else: # pragma: no cover
|
else: # pragma: no cover
|
||||||
@@ -36,15 +49,26 @@ class AvatarImageView(TemplateView):
|
|||||||
try:
|
try:
|
||||||
obj = model.objects.get(digest_sha256=kwargs['digest'])
|
obj = model.objects.get(digest_sha256=kwargs['digest'])
|
||||||
except ObjectDoesNotExist:
|
except ObjectDoesNotExist:
|
||||||
# TODO: Use default!?
|
pass
|
||||||
raise Exception('Mail/openid ("%s") does not exist"' %
|
|
||||||
kwargs['digest'])
|
if not obj or not obj.photo:
|
||||||
if not obj.photo:
|
static_img = path.join('static', 'img', 'mm', '%s%s' % (str(size), '.png'))
|
||||||
# That is hacky, but achieves what we want :-)
|
if path.isfile(static_img):
|
||||||
attr = getattr(obj, 'email', obj.openid)
|
photodata = Image.open(static_img)
|
||||||
# TODO: Use default!?
|
else:
|
||||||
raise Exception('No photo assigned to "%s"' % attr)
|
# TODO: Resize it!?
|
||||||
|
static_img = path.join('static', 'img', 'mm', '512.png')
|
||||||
|
else:
|
||||||
|
imgformat = obj.photo.format
|
||||||
|
photodata = Image.open(BytesIO(obj.photo.data))
|
||||||
|
|
||||||
|
photodata.thumbnail((size, size), Image.ANTIALIAS)
|
||||||
|
data = BytesIO()
|
||||||
|
photodata.save(data, pil_format(imgformat), quality=JPEG_QUALITY)
|
||||||
|
data.seek(0)
|
||||||
|
|
||||||
return HttpResponse(
|
return HttpResponse(
|
||||||
io.BytesIO(obj.photo.data),
|
data,
|
||||||
content_type='image/%s' % obj.photo.format)
|
content_type='image/%s' % imgformat)
|
||||||
|
# One eventually also wants to check if the DATA is correct,
|
||||||
|
# not only the size
|
||||||
|
|||||||
Reference in New Issue
Block a user