Added a view to retrieve profile photos, in order to support Meetecho's need for such, at /person/{email}/photo. The default is to supply images with 80px width. Image scaling is available using the same query argument as Gravatar: ?size=200 or ?s=200 for 200-pixel wide images.

- Legacy-Id: 18483
This commit is contained in:
Henrik Levkowetz 2020-09-10 21:41:01 +00:00
parent 60a1e0fe3d
commit 07be1f8516
3 changed files with 49 additions and 2 deletions

View file

@ -4,8 +4,10 @@
import datetime
from io import StringIO, BytesIO
from PIL import Image
from pyquery import PyQuery
from io import StringIO
from django.http import HttpRequest
from django.urls import reverse as urlreverse
@ -71,6 +73,25 @@ class PersonTests(TestCase):
r = self.client.get(photo_url)
self.assertEqual(r.status_code, 200)
def test_person_photo(self):
person = PersonFactory(with_bio=True)
self.assertTrue(person.photo is not None)
self.assertTrue(person.photo.name is not None)
url = urlreverse("ietf.person.views.photo", kwargs={ "email_or_name": person.email()})
r = self.client.get(url)
self.assertEqual(r['Content-Type'], 'image/jpg')
self.assertEqual(r.status_code, 200)
img = Image.open(BytesIO(r.content))
self.assertEqual(img.width, 80)
r = self.client.get(url+'?size=200')
self.assertEqual(r['Content-Type'], 'image/jpg')
self.assertEqual(r.status_code, 200)
img = Image.open(BytesIO(r.content))
self.assertEqual(img.width, 200)
def test_name_methods(self):
person = PersonFactory(name="Dr. Jens F. Möller", )

View file

@ -6,4 +6,5 @@ urlpatterns = [
url(r'^search/(?P<model_name>(person|email))/$', views.ajax_select2_search),
url(r'^(?P<personid>[a-z0-9]+).json$', ajax.person_json),
url(r'^(?P<email_or_name>[^/]+)$', views.profile),
url(r'^(?P<email_or_name>[^/]+)/photo/?$', views.photo),
]

View file

@ -3,7 +3,8 @@
import datetime
from io import StringIO
from io import StringIO, BytesIO
from PIL import Image
from django.contrib import messages
from django.db.models import Q
@ -78,6 +79,30 @@ def profile(request, email_or_name):
return render(request, 'person/profile.html', {'persons': persons, 'today':datetime.date.today()})
def photo(request, email_or_name):
if '@' in email_or_name:
persons = [ get_object_or_404(Email, address=email_or_name).person, ]
else:
aliases = Alias.objects.filter(name=email_or_name)
persons = list(set([ a.person for a in aliases ]))
if not persons:
raise Http404("No such person")
if len(persons) > 1:
return HttpResponse(r"\r\n".join([p.email() for p in persons]), status=300)
person = persons[0]
if not person.photo:
raise Http404("No photo found")
size = request.GET.get('s') or request.GET.get('size', '80')
if not size.isdigit():
return HttpResponse("Size must be integer", status=400)
size = int(size)
img = Image.open(person.photo)
img = img.resize((size, img.height*size//img.width))
bytes = BytesIO()
img.save(bytes, format='JPEG')
return HttpResponse(bytes.getvalue(), content_type='image/jpg')
@role_required("Secretariat")
def merge(request):
form = MergeForm()