Add validation code

This commit is contained in:
cuom1999 2024-05-14 13:42:26 -05:00
parent 0ea822f7a0
commit adb7c182d8
2 changed files with 40 additions and 36 deletions

View file

@ -24,6 +24,7 @@ from django.shortcuts import get_object_or_404, render
from django.urls import reverse_lazy from django.urls import reverse_lazy
from django.utils.decorators import method_decorator from django.utils.decorators import method_decorator
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from django.utils.datastructures import MultiValueDictKeyError
from django.views.decorators.http import require_POST from django.views.decorators.http import require_POST
from django.views.generic import DetailView, UpdateView, View from django.views.generic import DetailView, UpdateView, View
from django.views.generic.base import TemplateResponseMixin from django.views.generic.base import TemplateResponseMixin
@ -130,7 +131,7 @@ def get_comments(request, limit=10):
try: try:
comment_id = int(request.GET["id"]) comment_id = int(request.GET["id"])
parent_none = int(request.GET["parent_none"]) parent_none = int(request.GET["parent_none"])
except ValueError: except (ValueError, MultiValueDictKeyError):
return HttpResponseBadRequest() return HttpResponseBadRequest()
else: else:
if comment_id and not Comment.objects.filter(id=comment_id).exists(): if comment_id and not Comment.objects.filter(id=comment_id).exists():
@ -138,7 +139,10 @@ def get_comments(request, limit=10):
offset = 0 offset = 0
if "offset" in request.GET: if "offset" in request.GET:
try:
offset = int(request.GET["offset"]) offset = int(request.GET["offset"])
except ValueError:
return HttpResponseBadRequest()
target_comment = -1 target_comment = -1
if "target_comment" in request.GET: if "target_comment" in request.GET:

View file

@ -51,6 +51,7 @@ from judge.utils.infinite_paginator import InfinitePaginationMixin
from judge.utils.views import TitleMixin from judge.utils.views import TitleMixin
from judge.utils.timedelta import nice_repr from judge.utils.timedelta import nice_repr
from judge.views.contests import ContestMixin from judge.views.contests import ContestMixin
from judge.caching import cache_wrapper
def submission_related(queryset): def submission_related(queryset):
@ -380,17 +381,7 @@ class SubmissionsListBase(DiggPaginatorMixin, TitleMixin, ListView):
) )
if self.selected_languages: if self.selected_languages:
# Note (DMOJ): MariaDB can't optimize this subquery for some insane, unknown reason, queryset = queryset.filter(language__in=self.selected_languages)
# so we are forcing an eager evaluation to get the IDs right here.
# Otherwise, with multiple language filters, MariaDB refuses to use an index
# (or runs the subquery for every submission, which is even more horrifying to think about).
queryset = queryset.filter(
language__in=list(
Language.objects.filter(
key__in=self.selected_languages
).values_list("id", flat=True)
)
)
if self.selected_statuses: if self.selected_statuses:
submission_results = [i for i, _ in Submission.RESULT] submission_results = [i for i, _ in Submission.RESULT]
if self.selected_statuses[0] in submission_results: if self.selected_statuses[0] in submission_results:
@ -461,7 +452,7 @@ class SubmissionsListBase(DiggPaginatorMixin, TitleMixin, ListView):
context["show_problem"] = self.show_problem context["show_problem"] = self.show_problem
context["profile"] = self.request.profile context["profile"] = self.request.profile
context["all_languages"] = Language.objects.all().values_list("key", "name") context["all_languages"] = Language.objects.all().values_list("key", "name")
context["selected_languages"] = self.selected_languages context["selected_languages"] = self.selected_languages_key
context["all_statuses"] = self.get_searchable_status_codes() context["all_statuses"] = self.get_searchable_status_codes()
context["selected_statuses"] = self.selected_statuses context["selected_statuses"] = self.selected_statuses
@ -501,6 +492,18 @@ class SubmissionsListBase(DiggPaginatorMixin, TitleMixin, ListView):
self.selected_languages = request.GET.getlist("language") self.selected_languages = request.GET.getlist("language")
self.selected_statuses = request.GET.getlist("status") self.selected_statuses = request.GET.getlist("status")
if self.selected_languages:
languages = Language.objects.filter(key__in=self.selected_languages).values(
"id", "key"
)
self.selected_languages = [i["id"] for i in languages]
self.selected_languages_key = [i["key"] for i in languages]
if self.selected_statuses:
allowed_statuses = [i for i, _ in Submission.RESULT + Submission.STATUS]
self.selected_statuses = [
i for i in self.selected_statuses if i in allowed_statuses
]
if self.in_contest and self.contest.is_editable_by(self.request.user): if self.in_contest and self.contest.is_editable_by(self.request.user):
self.include_frozen = True self.include_frozen = True
@ -795,28 +798,9 @@ class AllSubmissions(InfinitePaginationMixin, GeneralSubmissions):
if self.request.organization or self.in_contest: if self.request.organization or self.in_contest:
return super(AllSubmissions, self)._get_result_data() return super(AllSubmissions, self)._get_result_data()
key = "global_submission_result_data" return _get_global_submission_result_data(
if self.selected_statuses: self.selected_statuses, self.selected_languages
key += ":" + ",".join(self.selected_statuses)
if self.selected_languages:
key += ":" + ",".join(self.selected_languages)
result = cache.get(key)
if result:
return result
queryset = Submission.objects
if self.selected_languages:
queryset = queryset.filter(
language__in=Language.objects.filter(key__in=self.selected_languages)
) )
if self.selected_statuses:
submission_results = [i for i, _ in Submission.RESULT]
if self.selected_statuses[0] in submission_results:
queryset = queryset.filter(result__in=self.selected_statuses)
else:
queryset = queryset.filter(status__in=self.selected_statuses)
result = get_result_data(queryset)
cache.set(key, result, self.stats_update_interval)
return result
class ForceContestMixin(object): class ForceContestMixin(object):
@ -1071,3 +1055,19 @@ class SubmissionSourceFileView(View):
response["Content-Type"] = "application/octet-stream" response["Content-Type"] = "application/octet-stream"
response["Content-Disposition"] = "attachment; filename=%s" % (filename,) response["Content-Disposition"] = "attachment; filename=%s" % (filename,)
return response return response
@cache_wrapper(prefix="gsrd", timeout=3600, expected_type=dict)
def _get_global_submission_result_data(statuses, languages):
queryset = Submission.objects
if languages:
queryset = queryset.filter(
language__in=Language.objects.filter(id__in=languages)
)
if statuses:
submission_results = [i for i, _ in Submission.RESULT]
if statuses[0] in submission_results:
queryset = queryset.filter(result__in=statuses)
else:
queryset = queryset.filter(status__in=statuses)
return get_result_data(queryset)