Make submit form work

This commit is contained in:
cuom1999 2020-07-19 16:39:28 -05:00
parent 3629369fba
commit 6f25762ffa
2 changed files with 31 additions and 53 deletions

View file

@ -10,9 +10,9 @@ from django.contrib.auth.decorators import login_required
from django.contrib.auth.mixins import PermissionRequiredMixin
from django.core.exceptions import ObjectDoesNotExist, PermissionDenied
from django.db import transaction
from django.db.models import Count, F, Prefetch, Q, Sum, Case, When, IntegerField
from django.db.models import Count, F, Prefetch, Q
from django.db.utils import ProgrammingError
from django.http import Http404, HttpResponse, HttpResponseBadRequest, HttpResponseForbidden, HttpResponseRedirect
from django.http import Http404, HttpResponse, HttpResponseForbidden, HttpResponseRedirect
from django.shortcuts import get_object_or_404, render
from django.template.loader import get_template
from django.urls import reverse
@ -49,7 +49,7 @@ def get_contest_problem(problem, profile):
def get_contest_submission_count(problem, profile, virtual):
return profile.current_contest.submissions.exclude(submission__status__in=['IE']) \
.filter(problem__problem__code=problem, participation__virtual=virtual).count()
.filter(problem__problem=problem, participation__virtual=virtual).count()
class ProblemMixin(object):
@ -177,7 +177,7 @@ class ProblemDetail(ProblemMixin, SolvedProblemMixin, CommentedDetailView):
context['submission_limit'] = contest_problem.max_submissions
if contest_problem.max_submissions:
context['submissions_left'] = max(contest_problem.max_submissions -
get_contest_submission_count(self.object.code, user.profile,
get_contest_submission_count(self.object, user.profile,
user.profile.current_contest.virtual), 0)
context['available_judges'] = Judge.objects.filter(online=True, problems=self.object)
@ -287,11 +287,11 @@ class ProblemList(QueryStringSortMixin, TitleMixin, SolvedProblemMixin, ListView
context_object_name = 'problems'
template_name = 'problem/list.html'
paginate_by = 50
sql_sort = frozenset(('date', 'points', 'ac_rate', 'user_count', 'code'))
sql_sort = frozenset(('points', 'ac_rate', 'user_count', 'code'))
manual_sort = frozenset(('name', 'group', 'solved', 'type'))
all_sorts = sql_sort | manual_sort
default_desc = frozenset(('date', 'points', 'ac_rate', 'user_count'))
default_sort = '-date'
default_desc = frozenset(('points', 'ac_rate', 'user_count'))
default_sort = 'code'
def get_paginator(self, queryset, per_page, orphans=0,
allow_empty_first_page=True, **kwargs):
@ -404,17 +404,9 @@ class ProblemList(QueryStringSortMixin, TitleMixin, SolvedProblemMixin, ListView
def get_context_data(self, **kwargs):
context = super(ProblemList, self).get_context_data(**kwargs)
context['hide_solved'] = 0 if self.in_contest else int(self.hide_solved)
context['show_types'] = 0 if self.in_contest else int(self.show_types)
context['full_text'] = 0 if self.in_contest else int(self.full_text)
context['show_editorial'] = 0 if self.in_contest else int(self.show_editorial)
if (context['show_editorial']):
context['object_list'] = context['object_list'] \
.annotate(has_public_editorial=Sum(Case(When(solution__is_public=True, then=1),
default=0, output_field=IntegerField())))
context['category'] = self.category
context['categories'] = ProblemGroup.objects.all()
if self.show_types:
@ -464,7 +456,6 @@ class ProblemList(QueryStringSortMixin, TitleMixin, SolvedProblemMixin, ListView
self.hide_solved = self.GET_with_session(request, 'hide_solved')
self.show_types = self.GET_with_session(request, 'show_types')
self.full_text = self.GET_with_session(request, 'full_text')
self.show_editorial = self.GET_with_session(request, 'show_editorial')
self.search_query = None
self.category = None
@ -494,7 +485,7 @@ class ProblemList(QueryStringSortMixin, TitleMixin, SolvedProblemMixin, ListView
return generic_message(request, 'FTS syntax error', e.args[1], status=400)
def post(self, request, *args, **kwargs):
to_update = ('hide_solved', 'show_types', 'full_text', 'show_editorial')
to_update = ('hide_solved', 'show_types', 'full_text')
for key in to_update:
if key in request.GET:
val = request.GET.get(key) == '1'
@ -531,12 +522,19 @@ user_logger = logging.getLogger('judge.user')
@login_required
def problem_submit(request, problem=None, submission=None):
def problem_submit(request, problem, submission=None):
if submission is not None and not request.user.has_perm('judge.resubmit_other') and \
get_object_or_404(Submission, id=int(submission)).user.user != request.user:
raise PermissionDenied()
profile = request.profile
problem = get_object_or_404(Problem, code=problem)
if not problem.is_accessible_by(request.user):
if request.method == 'POST':
user_logger.info('Naughty user %s wants to submit to %s without permission',
request.user.username, problem.code)
return HttpResponseForbidden('<h1>Do you want me to ban you?</h1>')
raise Http404()
if problem.is_editable_by(request.user):
judge_choices = tuple(Judge.objects.filter(online=True, problems=problem).values_list('name', 'name'))
@ -551,15 +549,9 @@ def problem_submit(request, problem=None, submission=None):
Submission.objects.filter(user=profile, was_rejudged=False)
.exclude(status__in=['D', 'IE', 'CE', 'AB']).count() >= settings.DMOJ_SUBMISSION_LIMIT):
return HttpResponse('<h1>You submitted too many submissions.</h1>', status=429)
if not form.cleaned_data['problem'].allowed_languages.filter(
id=form.cleaned_data['language'].id).exists():
if not problem.allowed_languages.filter(id=form.cleaned_data['language'].id).exists():
raise PermissionDenied()
if not form.cleaned_data['problem'].is_accessible_by(request.user):
user_logger.info('Naughty user %s wants to submit to %s without permission',
request.user.username, form.cleaned_data['problem'].code)
return HttpResponseForbidden('<h1>Do you want me to ban you?</h1>')
if not request.user.is_superuser and form.cleaned_data['problem'].banned_users.filter(
id=profile.id).exists():
if not request.user.is_superuser and problem.banned_users.filter(id=profile.id).exists():
return generic_message(request, _('Banned from submitting'),
_('You have been declared persona non grata for this problem. '
'You are permanently barred from submitting this problem.'))
@ -568,7 +560,7 @@ def problem_submit(request, problem=None, submission=None):
if profile.current_contest is not None:
contest_id = profile.current_contest.contest_id
try:
contest_problem = form.cleaned_data['problem'].contests.get(contest_id=contest_id)
contest_problem = problem.contests.get(contest_id=contest_id)
except ContestProblem.DoesNotExist:
model = form.save()
else:
@ -600,16 +592,8 @@ def problem_submit(request, problem=None, submission=None):
form_data = form.cleaned_data
if submission is not None:
sub = get_object_or_404(Submission, id=int(submission))
if 'problem' not in form_data:
return HttpResponseBadRequest()
else:
initial = {'language': profile.language}
if problem is not None:
initial['problem'] = get_object_or_404(Problem, code=problem)
problem_object = initial['problem']
if not problem_object.is_accessible_by(request.user):
raise Http404()
if submission is not None:
try:
sub = get_object_or_404(Submission.objects.select_related('source', 'language'), id=int(submission))
@ -619,12 +603,10 @@ def problem_submit(request, problem=None, submission=None):
raise Http404()
form = ProblemSubmitForm(judge_choices=judge_choices, initial=initial)
form_data = initial
if 'problem' in form_data:
form.fields['language'].queryset = (
form_data['problem'].usable_languages.order_by('name', 'key')
problem.usable_languages.order_by('name', 'key')
.prefetch_related(Prefetch('runtimeversion_set', RuntimeVersion.objects.order_by('priority')))
)
problem_object = form_data['problem']
if 'language' in form_data:
form.fields['source'].widget.mode = form_data['language'].ace
form.fields['source'].widget.theme = profile.ace_theme
@ -637,7 +619,7 @@ def problem_submit(request, problem=None, submission=None):
submission_limit = submissions_left = None
if profile.current_contest is not None:
try:
submission_limit = problem_object.contests.get(contest=profile.current_contest.contest).max_submissions
submission_limit = problem.contests.get(contest=profile.current_contest.contest).max_submissions
except ContestProblem.DoesNotExist:
pass
else:
@ -647,19 +629,18 @@ def problem_submit(request, problem=None, submission=None):
return render(request, 'problem/submit.html', {
'form': form,
'title': _('Submit to %(problem)s') % {
'problem': problem_object.translated_name(request.LANGUAGE_CODE),
'problem': problem.translated_name(request.LANGUAGE_CODE),
},
'content_title': mark_safe(escape(_('Submit to %(problem)s')) % {
'problem': format_html('<a href="{0}">{1}</a>',
reverse('problem_detail', args=[problem_object.code]),
problem_object.translated_name(request.LANGUAGE_CODE)),
reverse('problem_detail', args=[problem.code]),
problem.translated_name(request.LANGUAGE_CODE)),
}),
'langs': Language.objects.all(),
'no_judges': not form.fields['language'].queryset,
'submission_limit': submission_limit,
'submissions_left': submissions_left,
'ACE_URL': settings.ACE_URL,
'default_lang': default_lang,
})

View file

@ -47,7 +47,7 @@
function formatSelection(state) {
if (!state.id) return state.text; // optgroup
var data = makeDisplayData($("option[data-id=" + state.id + "]"));
return "<b>" + state.text + "</b> (" + data + ")";
return $('<span>').append($('<b>').text(state.text), ' (', data, ')');
}
// Terrible hack, adapted from https://github.com/select2/select2/issues/4436
@ -71,9 +71,6 @@
$("#id_language").select2({
templateResult: format,
templateSelection: formatSelection,
escapeMarkup: function (m) {
return m;
},
resultsAdapter: customAdapter
});
@ -156,7 +153,7 @@
white-space: nowrap
}
#language-select2 .select2-dropdown--above {
#language-select2.select2-dropdown--above {
display: flex;
flex-direction: column-reverse;
}