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
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
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
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)
def progress(self, seconds=10): with Progress(self, seconds) as p: for i in range(seconds): time.sleep(1) p.did(1)
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