195 lines
5.9 KiB
Python
195 lines
5.9 KiB
Python
from urllib.parse import urljoin
|
|
|
|
from django.db.models import F, Q
|
|
from django.http import Http404, JsonResponse
|
|
from django.shortcuts import get_object_or_404
|
|
from django.utils.encoding import smart_text
|
|
from django.views.generic.list import BaseListView
|
|
from django.conf import settings
|
|
|
|
from chat_box.utils import encrypt_url
|
|
|
|
from judge.jinja2.gravatar import gravatar
|
|
from judge.models import Comment, Contest, Organization, Problem, Profile
|
|
|
|
|
|
def _get_user_queryset(term, org_id=None):
|
|
if org_id:
|
|
try:
|
|
qs = Organization.objects.get(id=org_id).members.all()
|
|
except Exception:
|
|
raise Http404()
|
|
else:
|
|
qs = Profile.objects
|
|
if term.endswith(" "):
|
|
qs = qs.filter(user__username=term.strip())
|
|
else:
|
|
qs = qs.filter(user__username__icontains=term)
|
|
return qs
|
|
|
|
|
|
class Select2View(BaseListView):
|
|
paginate_by = 20
|
|
|
|
def get(self, request, *args, **kwargs):
|
|
self.request = request
|
|
self.term = kwargs.get("term", request.GET.get("term", ""))
|
|
self.object_list = self.get_queryset()
|
|
context = self.get_context_data()
|
|
|
|
return JsonResponse(
|
|
{
|
|
"results": [
|
|
{
|
|
"text": smart_text(self.get_name(obj)),
|
|
"id": obj.pk,
|
|
}
|
|
for obj in context["object_list"]
|
|
],
|
|
"more": context["page_obj"].has_next(),
|
|
}
|
|
)
|
|
|
|
def get_name(self, obj):
|
|
return str(obj)
|
|
|
|
|
|
class UserSelect2View(Select2View):
|
|
def get(self, request, *args, **kwargs):
|
|
self.org_id = kwargs.get("org_id", request.GET.get("org_id", ""))
|
|
return super(UserSelect2View, self).get(request, *args, **kwargs)
|
|
|
|
def get_queryset(self):
|
|
return (
|
|
_get_user_queryset(self.term, self.org_id)
|
|
.annotate(username=F("user__username"))
|
|
.only("id")
|
|
)
|
|
|
|
def get_name(self, obj):
|
|
return obj.username
|
|
|
|
|
|
class OrganizationSelect2View(Select2View):
|
|
def get_queryset(self):
|
|
return Organization.objects.filter(name__icontains=self.term)
|
|
|
|
|
|
class ProblemSelect2View(Select2View):
|
|
def get_queryset(self):
|
|
return (
|
|
Problem.get_visible_problems(self.request.user)
|
|
.filter(Q(code__icontains=self.term) | Q(name__icontains=self.term))
|
|
.distinct()
|
|
)
|
|
|
|
|
|
class ContestSelect2View(Select2View):
|
|
def get_queryset(self):
|
|
return Contest.get_visible_contests(self.request.user).filter(
|
|
Q(key__icontains=self.term) | Q(name__icontains=self.term)
|
|
)
|
|
|
|
|
|
class CommentSelect2View(Select2View):
|
|
def get_queryset(self):
|
|
return Comment.objects.filter(page__icontains=self.term)
|
|
|
|
|
|
class UserSearchSelect2View(BaseListView):
|
|
paginate_by = 20
|
|
|
|
def get_queryset(self):
|
|
return _get_user_queryset(self.term)
|
|
|
|
def get_json_result_from_object(self, user_tuple):
|
|
pk, username, email, display_rank, profile_image = user_tuple
|
|
return {
|
|
"text": username,
|
|
"id": username,
|
|
"gravatar_url": gravatar(
|
|
None,
|
|
self.gravatar_size,
|
|
self.gravatar_default,
|
|
self.get_profile_image_url(profile_image),
|
|
email,
|
|
),
|
|
"display_rank": display_rank,
|
|
}
|
|
|
|
def get(self, request, *args, **kwargs):
|
|
self.request = request
|
|
self.kwargs = kwargs
|
|
self.term = kwargs.get("term", request.GET.get("term", ""))
|
|
self.gravatar_size = request.GET.get("gravatar_size", 128)
|
|
self.gravatar_default = request.GET.get("gravatar_default", None)
|
|
|
|
self.object_list = self.get_queryset().values_list(
|
|
"pk", "user__username", "user__email", "display_rank", "profile_image"
|
|
)
|
|
|
|
context = self.get_context_data()
|
|
|
|
return JsonResponse(
|
|
{
|
|
"results": [
|
|
self.get_json_result_from_object(user_tuple)
|
|
for user_tuple in context["object_list"]
|
|
],
|
|
"more": context["page_obj"].has_next(),
|
|
}
|
|
)
|
|
|
|
def get_name(self, obj):
|
|
return str(obj)
|
|
|
|
def get_profile_image_url(self, profile_image):
|
|
if profile_image:
|
|
return urljoin(settings.MEDIA_URL, profile_image)
|
|
return None
|
|
|
|
|
|
class ContestUserSearchSelect2View(UserSearchSelect2View):
|
|
def get_queryset(self):
|
|
contest = get_object_or_404(Contest, key=self.kwargs["contest"])
|
|
if not contest.is_accessible_by(
|
|
self.request.user
|
|
) or not contest.can_see_full_scoreboard(self.request.user):
|
|
raise Http404()
|
|
|
|
return Profile.objects.filter(
|
|
contest_history__contest=contest, user__username__icontains=self.term
|
|
).distinct()
|
|
|
|
|
|
class TicketUserSelect2View(UserSearchSelect2View):
|
|
def get_queryset(self):
|
|
return Profile.objects.filter(
|
|
tickets__isnull=False, user__username__icontains=self.term
|
|
).distinct()
|
|
|
|
|
|
class AssigneeSelect2View(UserSearchSelect2View):
|
|
def get_queryset(self):
|
|
return Profile.objects.filter(
|
|
assigned_tickets__isnull=False, user__username__icontains=self.term
|
|
).distinct()
|
|
|
|
|
|
class ChatUserSearchSelect2View(UserSearchSelect2View):
|
|
def get_json_result_from_object(self, user_tuple):
|
|
if not self.request.user.is_authenticated:
|
|
raise Http404()
|
|
pk, username, email, display_rank, profile_image = user_tuple
|
|
return {
|
|
"text": username,
|
|
"id": encrypt_url(self.request.profile.id, pk),
|
|
"gravatar_url": gravatar(
|
|
None,
|
|
self.gravatar_size,
|
|
self.gravatar_default,
|
|
self.get_profile_image_url(profile_image),
|
|
email,
|
|
),
|
|
"display_rank": display_rank,
|
|
}
|