Exemplo n.º 1
0
    def simulate_submissions(self, submissions):
        """
        Submissions is a list of tuples:
            (ctask, date, action, expected_score_triple),
        Action can be:
            True -> sending a correct solution
            False -> sending an incorrect solution
            int x -> ID of the solution (assume 1-based).
        """
        team = self.team
        for index, test_case in enumerate(submissions):
            try:
                ctask, date, action, expected_score_triple = test_case
                if isinstance(action, bool):
                    is_correct = action
                    result = "42" if is_correct else "0"
                    submission = Submission.objects.create(ctask=ctask,
                            team=team, date=date, result=result,
                            cache_is_correct=is_correct)
                    update_score_on_ctask_action(self.competition, team,
                            self.chain, ctask, submission, False)
                else:
                    # Raise an exception if not found.
                    submission = Submission.objects.get(id=action)
                    submission.delete()
                    update_score_on_ctask_action(self.competition, team,
                            self.chain, ctask, None, True)
                score_triple = (team.cache_score_before_freeze,
                        team.cache_score, team.cache_max_score_after_freeze)

                refresh_teams_cache_score([team])
                score_triple = (team.cache_score_before_freeze,
                        team.cache_score, team.cache_max_score_after_freeze)
                self.assertEqual(score_triple, expected_score_triple)
            except:
                print "Test case #{}: {}".format(index, test_case)
                raise
Exemplo n.º 2
0
def task_detail(request, competition, data, ctask_id):
    is_admin = data['is_admin']
    extra = ['task__author'] if is_admin else []
    ctask = get_object_or_404(
            CompetitionTask.objects.select_related('chain', 'task',
                'task__content', *extra),
            competition=competition, id=ctask_id)
    ctask_id = int(ctask_id)
    team = data['team']
    if not is_admin:
        if (not team and not data['has_finished']) or not data['has_started'] \
                or ctask.chain.unlock_minutes > data['minutes_passed']:
            raise Http404

    if ctask.score > 1:
        ctask.t_score_text = ungettext(
                "This task is worth %d point.",
                "This task is worth %d points.",
                ctask.score) % ctask.score

    evaluator = get_evaluator(competition.evaluator_version)
    variables = safe_parse_descriptor(evaluator, ctask.descriptor)
    if team:
        ctasks, chain_submissions = preprocess_chain(
                competition, ctask.chain, team, preloaded_ctask=ctask)
        submissions = [x for x in chain_submissions if x.ctask_id == ctask_id]
        submissions.sort(key=lambda x: x.date)

        if data['has_finished']:
            ctask.t_is_locked = False

        if ctask.t_is_locked and not is_admin:
            raise Http404

        if request.method == 'POST' and (not data['has_finished'] or is_admin):
            solution_form = CompetitionSolutionForm(request.POST,
                    descriptor=ctask.descriptor, evaluator=evaluator)
            submission = None
            delete = False
            if is_admin and 'delete-submission' in request.POST:
                try:
                    submission = Submission.objects.get(
                            id=request.POST['delete-submission'])
                    chain_submissions = \
                            [x for x in chain_submissions if x != submission]
                    submissions = [x for x in submissions if x != submission]
                    submission.delete()
                    delete = True
                except Submission.DoesNotExist:
                    pass
            elif solution_form.is_valid():
                # TODO: Ignore submission if already correctly solved.
                if len(submissions) < ctask.max_submissions:
                    result = solution_form.cleaned_data['result']
                    is_correct = evaluator.check_result(
                            ctask.descriptor, result)
                    submission = Submission(ctask=ctask, team=team,
                            result=result, cache_is_correct=is_correct)
                    submission.save()
                    chain_submissions.append(submission)
                    submissions.append(submission)

            if delete or submission:
                if is_admin and team.is_admin_private():
                    update_ctask_cache_admin_solved_count(
                            competition, ctask, ctask.chain)
                update_score_on_ctask_action(competition, team, ctask.chain,
                        ctask, submission, delete,
                        chain_ctask_ids=[x.id for x in ctasks],
                        chain_submissions=chain_submissions)

                # Prevent form resubmission.
                return (ctask.get_absolute_url(), )

        else:
            solution_form = CompetitionSolutionForm(
                    descriptor=ctask.descriptor, evaluator=evaluator)

        data['is_solved'] = any(x.cache_is_correct for x in submissions)
        data['solution_form'] = solution_form
        data['submissions'] = submissions
        data['submissions_left'] = ctask.max_submissions - len(submissions)

    if is_admin:
        data['all_ctask_submissions'] = list(Submission.objects \
                .filter(ctask_id=ctask_id) \
                .select_related('team') \
                .order_by('id'))
        for submission in data['all_ctask_submissions']:
            submission.team.competition = competition

    data['help_text'] = get_solution_help_text(variables)
    data['chain'] = ctask.chain
    data['ctask'] = ctask

    if competition.show_solutions and data['has_finished'] \
            and not data.get('is_solved', False):
        data['sample_solution'] = get_sample_solution(variables)

    return data