def attempt(request, contest_id, attempt_id): contest = get_object_or_404(models.TaskBasedContest, pk=contest_id) attempt = get_object_or_404(tasks_models.Attempt, pk=attempt_id) if attempt.contest_id != contest.id: return HttpResponseNotFound() if request.method == 'POST': form = tasks_forms.EditAttemptForm(attempt, data=request.POST) if form.is_valid(): new_attempt = tasks_models.Attempt( contest=contest, task=attempt.task, author=attempt.author, participant=attempt.participant, created_at=attempt.created_at, is_correct=form.cleaned_data['score'] == attempt.task.max_score, **form.cleaned_data) new_attempt.id = attempt.id new_attempt.save() messages.success(request, 'Saved!') return redirect( urlresolvers.reverse('contests:attempts', args=[contest.id])) else: form = tasks_forms.EditAttemptForm(attempt) return render( request, 'contests/edit_attempt.html', { 'current_contest': contest, 'contest': contest, 'attempt': attempt, 'form': form, })
def qctf_submit_flag(request, task_id): contest = get_object_or_404(models.TaskBasedContest, pk=settings.QCTF_CONTEST_ID) participant = contest.get_participant_for_user(request.user) task = get_object_or_404(tasks_models.Task, pk=task_id) if (not contest.is_visible_in_list and not request.user.is_staff) or \ not contest.has_task(task): return HttpResponseNotFound() form = tasks_forms.AttemptForm(data=request.POST) status = 'fail' if participant is None: message = 'Вы не зарегистрированы на это соревнование' elif participant.is_disqualified: message = 'Вы дисквалифицированы с этого соревнования' elif contest.is_finished_for(participant): message = 'К сожалению, соревнование уже закончилось' elif get_count_attempts_in_last_minute(contest, participant) >= settings.DRAPO_MAX_TRIES_IN_MINUTE: message = 'Вы отправляете слишком много флагов. Подождите некоторое время.' elif not form.is_valid(): message = 'Форма некорректна' else: answer = form.cleaned_data['answer'] attempt = tasks_models.Attempt( contest=contest, task=task, participant=contest.get_participant_for_user(request.user), author=request.user, answer=answer ) attempt.save() attempt.try_to_check() if not attempt.is_checked: message = 'Проверяющая система не может проверить ваш флаг в данный момент' elif not attempt.is_correct: message = 'Эта строка не является правильным ответом на задание. ' \ 'Попробуйте найти что‑нибудь ещё. Обратите внимание, что ' \ 'правильный ответ начинается с символов <code>QCTF</code>.' else: status = 'success' message = 'Спасибо за интересные данные! ' \ 'Вознаграждение перечислено на ваш счёт.' #invalidate cache k1 = make_template_fragment_key('scoreboard', [request.user.id]) k2 = make_template_fragment_key('tasks', [request.user.id]) cache.delete_many([k1, k2]) return JsonResponse({'status': status, 'message': message})
def task(request, contest_id, task_id): contest = get_object_or_404(models.TaskBasedContest, pk=contest_id) if not contest.is_visible_in_list and not request.user.is_staff: return HttpResponseNotFound() task = get_object_or_404(tasks_models.Task, pk=task_id) if not contest.has_task(task): return HttpResponseNotFound() participant = contest.get_participant_for_user(request.user) if not contest.is_started_for(participant) and not request.user.is_staff: return HttpResponseForbidden('Contest is not started') if not is_task_open(contest, task, participant) and not request.user.is_staff: return HttpResponseForbidden('Task is closed') if request.method == 'POST' and request.user.is_authenticated(): form = tasks_forms.AttemptForm(data=request.POST) if participant is None: messages.warning(request, 'You are not registered to the contest') elif participant.is_disqualified: messages.error(request, 'You are disqualified from the contest') elif contest.is_finished_for(participant): messages.error(request, 'Contest is finished! You are too late, sorry') elif get_count_attempts_in_last_minute(contest, participant) >= settings.DRAPO_MAX_TRIES_IN_MINUTE: messages.error(request, 'Too fast, try later') elif contest.is_finished(): messages.error(request, 'Contest is finished! You are too late, sorry') elif form.is_valid(): answer = form.cleaned_data['answer'] attempt = tasks_models.Attempt( contest=contest, task=task, participant=contest.get_participant_for_user(request.user), author=request.user, answer=answer ) attempt.save() attempt.try_to_check() if not attempt.is_checked: messages.info(request, 'We will check you answer, thank you') elif attempt.is_correct: messages.success(request, 'Yeah! Correct answer!') else: messages.error(request, 'Wrong answer, sorry') return redirect(urlresolvers.reverse('contests:task', args=[contest.id, task.id])) else: form = tasks_forms.AttemptForm() statement_generator = task.statement_generator if request.user.is_anonymous() and not statement_generator.is_available_for_anonymous(): messages.error(request, 'This task is not available for guests. Please sign in') return redirect(urlresolvers.reverse('contests:tasks', args=[contest.id])) try: statement = statement_generator.generate({ 'task': task, 'user': request.user, 'participant': participant, 'locale': get_language() }) except Exception as e: logging.getLogger(__name__).exception(e) messages.error(request, 'This task cannot be displayed') return redirect(urlresolvers.reverse('contests:tasks', args=[contest.id])) # Files can be in statement or in task for this participant files = list(task.files.filter(Q(is_private=False) & (Q(participant__isnull=True) | Q(participant=participant)))) participant_score = max(task.attempts .filter(contest=contest_id, participant=participant, is_checked=True) .values_list('score', flat=True), default=None ) return render(request, 'contests/task.html', { 'current_contest': contest, 'contest': contest, 'task': task, 'statement': statement, 'files': files, 'attempt_form': form, 'participant': participant, 'participant_score': participant_score, })