NDOJ/judge/views/select2.py
2022-05-14 12:57:27 -05:00

190 lines
5.7 KiB
Python

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 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):
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_queryset(self):
return (
_get_user_queryset(self.term)
.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(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"
)
context = self.get_context_data()
return JsonResponse(
{
"results": [
{
"text": username,
"id": username,
"gravatar_url": gravatar(
email, self.gravatar_size, self.gravatar_default
),
"display_rank": display_rank,
}
for pk, username, email, display_rank in context["object_list"]
],
"more": context["page_obj"].has_next(),
}
)
def get_name(self, obj):
return str(obj)
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(BaseListView):
paginate_by = 20
def get_queryset(self): # TODO: add block
return _get_user_queryset(self.term)
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"
)
context = self.get_context_data()
return JsonResponse(
{
"results": [
{
"text": username,
"id": encrypt_url(request.profile.id, pk),
"gravatar_url": gravatar(
email, self.gravatar_size, self.gravatar_default
),
"display_rank": display_rank,
}
for pk, username, email, display_rank in context["object_list"]
],
"more": context["page_obj"].has_next(),
}
)
def get_name(self, obj):
return str(obj)