mirror of
https://github.com/QingdaoU/OnlineJudge.git
synced 2024-12-29 16:41:56 +00:00
add migration to correct database record; rejudge function now can work normally.
This commit is contained in:
parent
a0da0b5fa6
commit
2e50910931
@ -85,12 +85,11 @@ class SPJCompiler(DispatcherBase):
|
||||
|
||||
|
||||
class JudgeDispatcher(DispatcherBase):
|
||||
def __init__(self, submission_id, problem_id, is_rejudge=False):
|
||||
def __init__(self, submission_id, problem_id):
|
||||
super().__init__()
|
||||
self.submission = Submission.objects.get(id=submission_id)
|
||||
self.contest_id = self.submission.contest_id
|
||||
self.is_rejudge = is_rejudge
|
||||
self.last_result = None
|
||||
self.last_result = self.submission.result if self.submission.info else None
|
||||
|
||||
if self.contest_id:
|
||||
self.problem = Problem.objects.select_related("contest").get(id=problem_id, contest_id=self.contest_id)
|
||||
@ -122,7 +121,7 @@ class JudgeDispatcher(DispatcherBase):
|
||||
def judge(self):
|
||||
server = self.choose_judge_server()
|
||||
if not server:
|
||||
data = {"submission_id": self.submission.id, "problem_id": self.problem.id, "is_rejudge": self.is_rejudge}
|
||||
data = {"submission_id": self.submission.id, "problem_id": self.problem.id}
|
||||
cache.lpush(CacheKey.waiting_queue, json.dumps(data))
|
||||
return
|
||||
|
||||
@ -153,7 +152,6 @@ class JudgeDispatcher(DispatcherBase):
|
||||
"spj_compile_config": spj_config.get("compile"),
|
||||
"spj_src": self.problem.spj_code
|
||||
}
|
||||
self.last_result = self.submission.result
|
||||
|
||||
Submission.objects.filter(id=self.submission.id).update(result=JudgeStatus.JUDGING)
|
||||
|
||||
@ -181,30 +179,66 @@ class JudgeDispatcher(DispatcherBase):
|
||||
if self.contest_id:
|
||||
if self.contest.status != ContestStatus.CONTEST_UNDERWAY or \
|
||||
User.objects.get(id=self.submission.user_id).is_contest_admin(self.contest):
|
||||
logger.info("Contest debug mode, id: " + str(self.contest_id) + ", submission id: " + self.submission.id)
|
||||
logger.info(
|
||||
"Contest debug mode, id: " + str(self.contest_id) + ", submission id: " + self.submission.id)
|
||||
return
|
||||
self.update_contest_problem_status()
|
||||
self.update_contest_rank()
|
||||
else:
|
||||
if self.last_result:
|
||||
self.update_problem_status_rejudge()
|
||||
else:
|
||||
self.update_problem_status()
|
||||
|
||||
# 至此判题结束,尝试处理任务队列中剩余的任务
|
||||
process_pending_task()
|
||||
|
||||
def update_problem_status_rejudge(self):
|
||||
result = str(self.submission.result)
|
||||
problem_id = str(self.problem.id)
|
||||
with transaction.atomic():
|
||||
# update problem status
|
||||
problem = Problem.objects.select_for_update().get(contest_id=self.contest_id, id=self.problem.id)
|
||||
if self.last_result != JudgeStatus.ACCEPTED and self.submission.result == JudgeStatus.ACCEPTED:
|
||||
problem.accepted_number += 1
|
||||
problem_info = problem.statistic_info
|
||||
problem_info[self.last_result] = problem_info.get(self.last_result, 1) - 1
|
||||
problem_info[result] = problem_info.get(result, 0) + 1
|
||||
problem.save(update_fields=["accepted_number", "statistic_info"])
|
||||
|
||||
profile = User.objects.select_for_update().get(id=self.submission.user_id).userprofile
|
||||
if problem.rule_type == ProblemRuleType.ACM:
|
||||
acm_problems_status = profile.acm_problems_status.get("problems", {})
|
||||
if acm_problems_status[problem_id]["status"] != JudgeStatus.ACCEPTED:
|
||||
acm_problems_status[problem_id]["status"] = self.submission.result
|
||||
if self.submission.result == JudgeStatus.ACCEPTED:
|
||||
profile.accepted_number += 1
|
||||
profile.acm_problems_status["problems"] = acm_problems_status
|
||||
profile.save(update_fields=["accepted_number", "acm_problems_status"])
|
||||
|
||||
else:
|
||||
oi_problems_status = profile.oi_problems_status.get("problems", {})
|
||||
score = self.submission.statistic_info["score"]
|
||||
if oi_problems_status[problem_id]["status"] != JudgeStatus.ACCEPTED:
|
||||
# minus last time score, add this tim score
|
||||
profile.add_score(this_time_score=score,
|
||||
last_time_score=oi_problems_status[problem_id]["score"])
|
||||
oi_problems_status[problem_id]["score"] = score
|
||||
oi_problems_status[problem_id]["status"] = self.submission.result
|
||||
if self.submission.result == JudgeStatus.ACCEPTED:
|
||||
profile.accepted_number += 1
|
||||
profile.oi_problems_status["problems"] = oi_problems_status
|
||||
profile.save(update_fields=["accepted_number", "oi_problems_status"])
|
||||
|
||||
def update_problem_status(self):
|
||||
result = str(self.submission.result)
|
||||
problem_id = str(self.problem.id)
|
||||
with transaction.atomic():
|
||||
# update problem status
|
||||
problem = Problem.objects.select_for_update().get(contest_id=self.contest_id, id=self.problem.id)
|
||||
if not self.is_rejudge:
|
||||
problem.submission_number += 1
|
||||
if self.submission.result == JudgeStatus.ACCEPTED:
|
||||
if self.last_result != JudgeStatus.ACCEPTED:
|
||||
problem.accepted_number += 1
|
||||
else:
|
||||
if self.last_result == JudgeStatus.ACCEPTED:
|
||||
problem.accepted_number -= 1
|
||||
problem_info = problem.statistic_info
|
||||
problem_info[result] = problem_info.get(result, 0) + 1
|
||||
problem.save(update_fields=["accepted_number", "submission_number", "statistic_info"])
|
||||
|
@ -4,5 +4,5 @@ from judge.dispatcher import JudgeDispatcher
|
||||
|
||||
|
||||
@shared_task
|
||||
def judge_task(submission_id, problem_id, is_rejudge=False):
|
||||
JudgeDispatcher(submission_id, problem_id, is_rejudge=is_rejudge).judge()
|
||||
def judge_task(submission_id, problem_id):
|
||||
JudgeDispatcher(submission_id, problem_id).judge()
|
||||
|
38
submission/migrations/0010_fix_submission_number.py
Normal file
38
submission/migrations/0010_fix_submission_number.py
Normal file
@ -0,0 +1,38 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations
|
||||
from django.db.models import Count
|
||||
|
||||
|
||||
def fix_rejudge_bugs(apps, schema_editor):
|
||||
Submission = apps.get_model("submission", "Submission")
|
||||
Problem = apps.get_model("problem", "Problem")
|
||||
User = apps.get_model("account", "User")
|
||||
|
||||
for item in Problem.objects.filter(contest__isnull=True):
|
||||
submissions = Submission.objects.filter(problem=item)
|
||||
item.submission_number = submissions.count()
|
||||
results_count = submissions.annotate(count=Count('result')).values('result', 'count')
|
||||
for stat in results_count:
|
||||
if stat["result"] == 0:
|
||||
item.accepted_number = stat["count"]
|
||||
item.statistic_info[str(stat)] = stat["count"]
|
||||
item.save(update_fields=["submission_number", "accepted_number", "statistic_info"])
|
||||
|
||||
for user in User.objects.all():
|
||||
submissions = Submission.objects.filter(user_id=user.id)
|
||||
profile = user.userprofile
|
||||
profile.submission_number = submissions.count()
|
||||
profile.accepted_number = submissions.filter(result=0).count()
|
||||
profile.save(update_fields=["submission_number", "accepted_number"])
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
('submission', '0009_delete_user_output'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RunPython(fix_rejudge_bugs, reverse_code=migrations.RunPython.noop)
|
||||
]
|
@ -2,7 +2,7 @@ from account.decorators import super_admin_required
|
||||
from judge.tasks import judge_task
|
||||
# from judge.dispatcher import JudgeDispatcher
|
||||
from utils.api import APIView
|
||||
from ..models import Submission, JudgeStatus
|
||||
from ..models import Submission
|
||||
|
||||
|
||||
class SubmissionRejudgeAPI(APIView):
|
||||
@ -19,5 +19,5 @@ class SubmissionRejudgeAPI(APIView):
|
||||
submission.statistic_info = {}
|
||||
submission.save()
|
||||
|
||||
judge_task.delay(submission.id, submission.problem.id, is_rejudge=True)
|
||||
judge_task.delay(submission.id, submission.problem.id)
|
||||
return self.success()
|
||||
|
Loading…
Reference in New Issue
Block a user