Exemple #1
0
def rescore_problem(self, problem_id):
    problem = Problem.objects.get(id=problem_id)
    submissions = Submission.objects.filter(problem_id=problem_id)

    with Progress(self, submissions.count(), stage=_('Modifying submissions')) as p:
        rescored = 0
        for submission in submissions.iterator():
            submission.points = round(submission.case_points / submission.case_total * problem.points
                                      if submission.case_total else 0, 1)
            if not problem.partial and submission.points < problem.points:
                submission.points = 0
            submission.save(update_fields=['points'])
            submission.update_contest()
            rescored += 1
            if rescored % 10 == 0:
                p.done = rescored

    with Progress(self, submissions.values('user_id').distinct().count(), stage=_('Recalculating user points')) as p:
        users = 0
        profiles = Profile.objects.filter(id__in=submissions.values_list('user_id', flat=True).distinct())
        for profile in profiles.iterator():
            profile._updating_stats_only = True
            profile.calculate_points()
            cache.delete('user_complete:%d' % profile.id)
            cache.delete('user_attempted:%d' % profile.id)
            users += 1
            if users % 10 == 0:
                p.done = users
    return rescored
Exemple #2
0
def rejudge_problem_filter(self, problem_id, id_range=None, languages=None, results=None):
    queryset = Submission.objects.filter(problem_id=problem_id)
    queryset = apply_submission_filter(queryset, id_range, languages, results)

    rejudged = 0
    with Progress(self, queryset.count()) as p:
        for submission in queryset.iterator():
            submission.judge(rejudge=True, batch_rejudge=True)
            rejudged += 1
            if rejudged % 10 == 0:
                p.done = rejudged
    return rejudged
Exemple #3
0
def rescore_contest(self, contest_key):
    contest = Contest.objects.get(key=contest_key)
    participations = contest.users

    rescored = 0
    with Progress(self, participations.count(), stage=_('Recalculating contest scores')) as p:
        for participation in participations.iterator():
            participation.recompute_results()
            rescored += 1
            if rescored % 10 == 0:
                p.done = rescored
    return rescored
Exemple #4
0
def run_moss(self, contest_key):
    moss_api_key = settings.MOSS_API_KEY
    if moss_api_key is None:
        raise ImproperlyConfigured('No MOSS API Key supplied')

    contest = Contest.objects.get(key=contest_key)
    ContestMoss.objects.filter(contest=contest).delete()

    length = len(ContestMoss.LANG_MAPPING) * contest.problems.count()
    moss_results = []

    with Progress(self, length, stage=_('Running MOSS')) as p:
        for problem in contest.problems.all():
            for dmoj_lang, moss_lang in ContestMoss.LANG_MAPPING:
                result = ContestMoss(contest=contest,
                                     problem=problem,
                                     language=dmoj_lang)

                subs = Submission.objects.filter(
                    contest__participation__virtual__in=(
                        ContestParticipation.LIVE,
                        ContestParticipation.SPECTATE),
                    contest_object=contest,
                    problem=problem,
                    language__common_name=dmoj_lang,
                ).order_by('-points').values_list('user__user__username',
                                                  'source__source')

                if subs.exists():
                    moss_call = MOSS(moss_api_key,
                                     language=moss_lang,
                                     matching_file_limit=100,
                                     comment='%s - %s' %
                                     (contest.key, problem.code))

                    users = set()

                    for username, source in subs:
                        if username in users:
                            continue
                        users.add(username)
                        moss_call.add_file_from_memory(username,
                                                       source.encode('utf-8'))

                    result.url = moss_call.process()
                    result.submission_count = len(users)

                moss_results.append(result)
                p.did(1)

    ContestMoss.objects.bulk_create(moss_results)

    return len(moss_results)
Exemple #5
0
def progress(self, seconds=10):
    with Progress(self, seconds) as p:
        for i in range(seconds):
            time.sleep(1)
            p.did(1)
Exemple #6
0
def prepare_user_data(self, profile_id, options):
    options = json.loads(options)
    with Progress(self, 2, stage=_('Applying filters')) as p:
        # Force an update so that we get a progress bar.
        p.done = 0
        submissions = apply_submission_filter(
            Submission.objects.select_related(
                'problem', 'language', 'source').filter(user_id=profile_id),
            options,
        )
        p.did(1)
        comments = apply_comment_filter(
            Comment.objects.filter(author_id=profile_id), options)
        p.did(1)

    with zipfile.ZipFile(os.path.join(settings.DMOJ_USER_DATA_CACHE,
                                      '%s.zip' % profile_id),
                         mode='w') as data_file:
        submission_count = len(submissions)
        if submission_count:
            submission_info = {}
            with Progress(self,
                          submission_count,
                          stage=_('Preparing your submission data')) as p:
                prepared = 0
                interval = max(submission_count // 10, 1)
                for submission in submissions:
                    submission_info[submission.id] = {
                        'problem': submission.problem.code,
                        'date': submission.date.isoformat(),
                        'time': submission.time,
                        'memory': submission.memory,
                        'language': submission.language.key,
                        'status': submission.status,
                        'result': submission.result,
                        'case_points': submission.case_points,
                        'case_total': submission.case_total,
                    }
                    with data_file.open(
                            'submissions/%s.%s' %
                        (submission.id, submission.language.extension),
                            'w',
                    ) as f:
                        f.write(utf8bytes(submission.source.source))

                    prepared += 1
                    if prepared % interval == 0:
                        p.done = prepared

                with data_file.open('submissions/info.json', 'w') as f:
                    f.write(
                        utf8bytes(
                            json.dumps(submission_info,
                                       sort_keys=True,
                                       indent=4)))

        comment_count = len(comments)
        if comment_count:
            comment_info = {}
            with Progress(self,
                          comment_count,
                          stage=_('Preparing your comment data')) as p:
                prepared = 0
                interval = max(comment_count // 10, 1)
                for comment in comments:
                    related_object = {
                        'b': 'blog post',
                        'c': 'contest',
                        'p': 'problem',
                        's': 'problem editorial',
                    }
                    comment_info[comment.id] = {
                        'date': comment.time.isoformat(),
                        'related_object': related_object[comment.page[0]],
                        'page': comment.page[2:],
                        'score': comment.score,
                    }
                    with data_file.open('comments/%s.txt' % comment.id,
                                        'w') as f:
                        f.write(utf8bytes(comment.body))

                    prepared += 1
                    if prepared % interval == 0:
                        p.done = prepared

                with data_file.open('comments/info.json', 'w') as f:
                    f.write(
                        utf8bytes(
                            json.dumps(comment_info, sort_keys=True,
                                       indent=4)))

    return submission_count + comment_count