From 2c90114b9ddbd19d6a1bf67147d2fccdd22f8192 Mon Sep 17 00:00:00 2001 From: Danielle McLean Date: Fri, 8 Jun 2018 14:46:41 +1000 Subject: [PATCH 1/2] Add pickle support to the MSGPackModernSerializer - if a type can't be serialized to native MessagePack, then pickle it --- lemoncurry/msgpack.py | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/lemoncurry/msgpack.py b/lemoncurry/msgpack.py index 6328f2c..4a5fb57 100644 --- a/lemoncurry/msgpack.py +++ b/lemoncurry/msgpack.py @@ -1,11 +1,24 @@ import msgpack +import pickle from django_redis.serializers.base import BaseSerializer +def default(obj): + # Pickle anything that MessagePack can't handle itself. + return msgpack.ExtType(69, pickle.dumps(obj, protocol=4)) + + +def ext_hook(code, data): + # Unpickle if we pickled - otherwise do nothing. + if code == 69: + return pickle.loads(data) + return msgpack.ExtType(code, data) + + class MSGPackModernSerializer(BaseSerializer): def dumps(self, value): - return msgpack.packb(value, use_bin_type=True) + return msgpack.packb(value, default=default, use_bin_type=True) def loads(self, value): - return msgpack.unpackb(value, raw=False) + return msgpack.unpackb(value, ext_hook=ext_hook, raw=False) From e94a856a081cfe1c59e9288c96a1b5edcba3edca Mon Sep 17 00:00:00 2001 From: Danielle McLean Date: Fri, 8 Jun 2018 14:47:34 +1000 Subject: [PATCH 2/2] Add caching and smarter resizing to the Libravatar endpoint --- users/views.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/users/views.py b/users/views.py index 83ed965..addace3 100644 --- a/users/views.py +++ b/users/views.py @@ -1,4 +1,5 @@ from django.http import HttpResponse, HttpResponseRedirect +from django.views.decorators.cache import cache_page from PIL import Image from lemoncurry import utils @@ -12,6 +13,7 @@ def try_libravatar_org(hash, get): return HttpResponseRedirect(url) +@cache_page(60 * 15) def libravatar(request, hash): g = request.GET size = g.get('s', g.get('size', 80)) @@ -42,8 +44,12 @@ def libravatar(request, hash): return try_libravatar_org(hash, g) im = Image.open(user.avatar) - im_resized = im.resize((size, size)) + image_type = im.format + natural_size = min(im.size) - response = HttpResponse(content_type='image/'+im.format.lower()) - im_resized.save(response, im.format) + im = im.crop((0, 0, natural_size, natural_size)) + im = im.resize((size, size), resample=Image.HAMMING) + + response = HttpResponse(content_type='image/'+image_type.lower()) + im.save(response, image_type) return response