Make submit form work
This commit is contained in:
parent
3629369fba
commit
6f25762ffa
2 changed files with 31 additions and 53 deletions
|
@ -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,8 +456,7 @@ 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
|
||||
self.selected_types = []
|
||||
|
@ -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')
|
||||
.prefetch_related(Prefetch('runtimeversion_set', RuntimeVersion.objects.order_by('priority')))
|
||||
)
|
||||
problem_object = form_data['problem']
|
||||
form.fields['language'].queryset = (
|
||||
problem.usable_languages.order_by('name', 'key')
|
||||
.prefetch_related(Prefetch('runtimeversion_set', RuntimeVersion.objects.order_by('priority')))
|
||||
)
|
||||
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,
|
||||
})
|
||||
|
||||
|
@ -687,4 +668,4 @@ class ProblemClone(ProblemMixin, PermissionRequiredMixin, TitleMixin, SingleObje
|
|||
problem.language_limits.set(language_limits)
|
||||
problem.types.set(types)
|
||||
|
||||
return HttpResponseRedirect(reverse('admin:judge_problem_change', args=(problem.id,)))
|
||||
return HttpResponseRedirect(reverse('admin:judge_problem_change', args=(problem.id,)))
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue