* fix: 404 on CommunityList name collision * fix: 404 on ambiuous person for photo() view * test: update tests --------- Co-authored-by: Robert Sparks <rjsparks@nostrum.com>
146 lines
5 KiB
Python
146 lines
5 KiB
Python
# Copyright The IETF Trust 2012-2020, All Rights Reserved
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
from io import StringIO, BytesIO
|
|
from PIL import Image
|
|
|
|
from django.contrib import messages
|
|
from django.db.models import Q
|
|
from django.http import HttpResponse, Http404
|
|
from django.shortcuts import render, redirect
|
|
from django.utils import timezone
|
|
|
|
import debug # pyflakes:ignore
|
|
|
|
from ietf.ietfauth.utils import role_required
|
|
from ietf.person.models import Email, Person
|
|
from ietf.person.fields import select2_id_name_json
|
|
from ietf.person.forms import MergeForm
|
|
from ietf.person.utils import handle_users, merge_persons, lookup_persons
|
|
|
|
|
|
def ajax_select2_search(request, model_name):
|
|
if model_name == "email":
|
|
model = Email
|
|
else:
|
|
model = Person
|
|
|
|
q = [w.strip() for w in request.GET.get('q', '').split() if w.strip()]
|
|
|
|
if not q:
|
|
objs = model.objects.none()
|
|
else:
|
|
query = Q() # all objects returned if no other terms in the queryset
|
|
for t in q:
|
|
if model == Email:
|
|
query &= Q(person__alias__name__icontains=t) | Q(address__icontains=t)
|
|
elif model == Person:
|
|
if "@" in t: # allow searching email address if there's a @ in the search term
|
|
query &= Q(alias__name__icontains=t) | Q(email__address__icontains=t)
|
|
else:
|
|
query &= Q(alias__name__icontains=t)
|
|
|
|
objs = model.objects.filter(query)
|
|
|
|
# require an account at the Datatracker
|
|
only_users = request.GET.get("user") == "1"
|
|
all_emails = request.GET.get("a", "0") == "1"
|
|
|
|
if model == Email:
|
|
objs = objs.exclude(person=None).order_by('person__name')
|
|
if not all_emails:
|
|
objs = objs.filter(active=True)
|
|
if only_users:
|
|
objs = objs.exclude(person__user=None)
|
|
elif model == Person:
|
|
objs = objs.order_by("name")
|
|
if only_users:
|
|
objs = objs.exclude(user=None)
|
|
|
|
try:
|
|
page = int(request.GET.get("p", 1)) - 1
|
|
except ValueError:
|
|
page = 0
|
|
|
|
objs = objs.distinct()[page:page + 10]
|
|
|
|
return HttpResponse(select2_id_name_json(objs), content_type='application/json')
|
|
|
|
|
|
def profile(request, email_or_name):
|
|
persons = lookup_persons(email_or_name)
|
|
return render(request, 'person/profile.html', {'persons': persons, 'today': timezone.now()})
|
|
|
|
|
|
def photo(request, email_or_name):
|
|
persons = lookup_persons(email_or_name)
|
|
if len(persons) > 1:
|
|
raise Http404("No photo found")
|
|
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)
|
|
with Image.open(person.photo) as img:
|
|
img = img.resize((size, img.height*size//img.width))
|
|
bytes = BytesIO()
|
|
try:
|
|
img.save(bytes, format='JPEG')
|
|
return HttpResponse(bytes.getvalue(), content_type='image/jpg')
|
|
except OSError:
|
|
raise Http404
|
|
|
|
|
|
@role_required("Secretariat")
|
|
def merge(request):
|
|
form = MergeForm()
|
|
method = 'get'
|
|
change_details = ''
|
|
warn_messages = []
|
|
source = None
|
|
target = None
|
|
|
|
if request.method == "GET":
|
|
form = MergeForm()
|
|
if request.GET:
|
|
form = MergeForm(request.GET)
|
|
if form.is_valid():
|
|
source = form.cleaned_data.get('source')
|
|
target = form.cleaned_data.get('target')
|
|
if source.user and target.user:
|
|
warn_messages.append('WARNING: Both Person records have logins. Be sure to specify the record to keep in the Target field.')
|
|
if source.user.last_login and target.user.last_login and source.user.last_login > target.user.last_login:
|
|
warn_messages.append('WARNING: The most recently used login is being deleted!')
|
|
change_details = handle_users(source, target, check_only=True)
|
|
method = 'post'
|
|
else:
|
|
method = 'get'
|
|
|
|
if request.method == "POST":
|
|
form = MergeForm(request.POST)
|
|
if form.is_valid():
|
|
source = form.cleaned_data.get('source')
|
|
source_id = source.id
|
|
target = form.cleaned_data.get('target')
|
|
# Do merge with force
|
|
output = StringIO()
|
|
success, changes = merge_persons(request, source, target, file=output)
|
|
if success:
|
|
messages.success(request, 'Merged {} ({}) to {} ({}). {})'.format(
|
|
source.name, source_id, target.name, target.id, changes))
|
|
else:
|
|
messages.error(request, output)
|
|
return redirect('ietf.secr.rolodex.views.view', id=target.pk)
|
|
|
|
return render(request, 'person/merge.html', {
|
|
'form': form,
|
|
'method': method,
|
|
'change_details': change_details,
|
|
'source': source,
|
|
'target': target,
|
|
'warn_messages': warn_messages,
|
|
})
|