예제 #1
0
파일: views.py 프로젝트: xelez/drapo
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,
        })
예제 #2
0
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})
예제 #3
0
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,
    })