mirror of
https://github.com/QingdaoU/OnlineJudge.git
synced 2024-09-21 00:13:18 +00:00
完善OI细则
This commit is contained in:
parent
2c5a1e42bf
commit
f5566148bc
@ -92,7 +92,8 @@ def check_contest_permission(func):
|
||||
if not user.is_authenticated():
|
||||
return self.error("Please login in first.")
|
||||
# password error
|
||||
if ("contests" not in request.session) or (self.contest.id not in request.session["contests"]):
|
||||
if ("accessible_contests" not in request.session) or \
|
||||
(self.contest.id not in request.session["accessible_contests"]):
|
||||
return self.error("Password is required.")
|
||||
|
||||
return func(*args, **kwargs)
|
||||
|
@ -45,6 +45,14 @@ class Contest(models.Model):
|
||||
def is_contest_admin(self, user):
|
||||
return user.is_authenticated() and (self.created_by == user or user.admin_type == AdminType.SUPER_ADMIN)
|
||||
|
||||
def check_oi_permission(self, user):
|
||||
if self.status != ContestStatus.CONTEST_ENDED and self.real_time_rank == False:
|
||||
if self.is_contest_admin(user):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
return True
|
||||
|
||||
class Meta:
|
||||
db_table = "contest"
|
||||
ordering = ("-create_time",)
|
||||
|
@ -67,7 +67,7 @@ class ContestPasswordVerifyAPI(APIView):
|
||||
# password verify OK.
|
||||
if "accessible_contests" not in request.session:
|
||||
request.session["accessible_contests"] = []
|
||||
request.session["contests"].append(contest.id)
|
||||
request.session["accessible_contests"].append(contest.id)
|
||||
# https://docs.djangoproject.com/en/dev/topics/http/sessions/#when-sessions-are-saved
|
||||
request.session.modified = True
|
||||
return self.success(True)
|
||||
@ -93,10 +93,12 @@ class ContestRankAPI(APIView):
|
||||
|
||||
@check_contest_permission
|
||||
def get(self, request):
|
||||
if self.contest.rule_type == ContestRuleType.ACM:
|
||||
serializer = ACMContestRankSerializer
|
||||
else:
|
||||
if self.contest.rule_type == ContestRuleType.OI:
|
||||
if not self.contest.check_oi_permission(request.user):
|
||||
return self.error("You have no permission for ranks now")
|
||||
serializer = OIContestRankSerializer
|
||||
else:
|
||||
serializer = ACMContestRankSerializer
|
||||
|
||||
cache_key = f"{CacheKey.contest_rank_cache}:{self.contest.id}"
|
||||
qs = cache.get(cache_key)
|
||||
|
@ -156,7 +156,6 @@ class JudgeDispatcher(object):
|
||||
with transaction.atomic():
|
||||
# prepare problem and user_profile
|
||||
problem = Problem.objects.select_for_update().get(contest_id=self.contest_id, id=self.problem.id)
|
||||
problem_info = problem.statistic_info
|
||||
user = User.objects.select_for_update().select_for_update("userprofile").get(id=self.submission.user_id)
|
||||
user_profile = user.userprofile
|
||||
if self.contest_id:
|
||||
@ -165,25 +164,25 @@ class JudgeDispatcher(object):
|
||||
key = "problems"
|
||||
acm_problems_status = user_profile.acm_problems_status.get(key, {})
|
||||
oi_problems_status = user_profile.oi_problems_status.get(key, {})
|
||||
problem_id = str(self.problem.id)
|
||||
problem_info = problem.statistic_info
|
||||
|
||||
# update problem info
|
||||
result = str(self.submission.result)
|
||||
problem_info[result] = problem_info.get(result, 0) + 1
|
||||
problem.statistic_info = problem_info
|
||||
|
||||
# update submission and accepted number counter
|
||||
problem.submission_number += 1
|
||||
if self.submission.result == JudgeStatus.ACCEPTED:
|
||||
problem.accepted_number += 1
|
||||
# only when submission is not in contest, we update user profile,
|
||||
# in other words, users' submission in a contest will not be counted in user profile
|
||||
# submission in a contest will not be counted in user profile
|
||||
if not self.contest_id:
|
||||
user_profile.submission_number += 1
|
||||
if self.submission.result == JudgeStatus.ACCEPTED:
|
||||
user_profile.accepted_number += 1
|
||||
|
||||
problem_id = str(self.problem.id)
|
||||
if self.problem.rule_type == ProblemRuleType.ACM:
|
||||
# update acm problem info
|
||||
result = str(self.submission.result)
|
||||
problem_info[result] = problem_info.get(result, 0) + 1
|
||||
problem.statistic_info = problem_info
|
||||
|
||||
# update user_profile
|
||||
if problem_id not in acm_problems_status:
|
||||
acm_problems_status[problem_id] = {"status": self.submission.result, "_id": self.problem._id}
|
||||
@ -193,12 +192,8 @@ class JudgeDispatcher(object):
|
||||
user_profile.acm_problems_status[key] = acm_problems_status
|
||||
|
||||
else:
|
||||
# update oi problem info
|
||||
score = self.submission.statistic_info["score"]
|
||||
problem_info[score] = problem_info.get(score, 0) + 1
|
||||
problem.statistic_info = problem_info
|
||||
|
||||
# update user_profile
|
||||
score = self.submission.statistic_info["score"]
|
||||
if problem_id not in oi_problems_status:
|
||||
user_profile.add_score(score)
|
||||
oi_problems_status[problem_id] = {"status": self.submission.result,
|
||||
@ -218,8 +213,8 @@ class JudgeDispatcher(object):
|
||||
def update_contest_rank(self):
|
||||
if self.contest_id and self.contest.status != ContestStatus.CONTEST_UNDERWAY:
|
||||
return
|
||||
if self.contest.real_time_rank:
|
||||
cache.delete(CacheKey.contest_rank_cache + str(self.contest_id))
|
||||
if self.contest.rule_type == ContestRuleType.OI or self.contest.real_time_rank:
|
||||
cache.delete(f"{CacheKey.contest_rank_cache}:{self.contest.id}")
|
||||
with transaction.atomic():
|
||||
if self.contest.rule_type == ContestRuleType.ACM:
|
||||
acm_rank, _ = ACMContestRank.objects.select_for_update(). \
|
||||
|
@ -95,6 +95,7 @@ class ProblemAdminSerializer(BaseProblemSerializer):
|
||||
class ContestProblemAdminSerializer(BaseProblemSerializer):
|
||||
class Meta:
|
||||
model = Problem
|
||||
fields = "__all__"
|
||||
|
||||
|
||||
class ProblemSerializer(BaseProblemSerializer):
|
||||
|
@ -21,11 +21,10 @@ class ProblemAPI(APIView):
|
||||
oi_problems_status = profile.oi_problems_status.get("problems", {})
|
||||
# paginate data
|
||||
results = queryset_values.get("results")
|
||||
if results:
|
||||
if results is not None:
|
||||
problems = results
|
||||
else:
|
||||
problems = [queryset_values,]
|
||||
|
||||
for problem in problems:
|
||||
if problem["rule_type"] == ProblemRuleType.ACM:
|
||||
problem["my_status"] = acm_problems_status.get(str(problem["id"]), {}).get("status")
|
||||
@ -53,11 +52,7 @@ class ProblemAPI(APIView):
|
||||
# 按照标签筛选
|
||||
tag_text = request.GET.get("tag")
|
||||
if tag_text:
|
||||
try:
|
||||
tag = ProblemTag.objects.get(name=tag_text)
|
||||
except ProblemTag.DoesNotExist:
|
||||
return self.error("The Tag does not exist.")
|
||||
problems = tag.problem_set.all().filter(visible=True)
|
||||
problems = problems.filter(tags__name=tag_text)
|
||||
|
||||
# 搜索的情况
|
||||
keyword = request.GET.get("keyword", "").strip()
|
||||
@ -76,7 +71,11 @@ class ProblemAPI(APIView):
|
||||
|
||||
class ContestProblemAPI(APIView):
|
||||
def _add_problem_status(self, request, queryset_values):
|
||||
if request.user.is_authenticated() and self.contest.rule_type != ContestRuleType.OI:
|
||||
print("checking")
|
||||
if self.contest.rule_type == ContestRuleType.OI and not self.contest.check_oi_permission(request.user):
|
||||
return
|
||||
print('here')
|
||||
if request.user.is_authenticated():
|
||||
profile = request.user.userprofile
|
||||
if self.contest.rule_type == ContestRuleType.ACM:
|
||||
problems_status = profile.acm_problems_status.get("contest_problems", {})
|
||||
@ -96,7 +95,7 @@ class ContestProblemAPI(APIView):
|
||||
except Problem.DoesNotExist:
|
||||
return self.error("Problem does not exist.")
|
||||
problem_data = ContestProblemSerializer(problem).data
|
||||
self._add_problem_status(request, problem_data)
|
||||
self._add_problem_status(request, [problem_data,])
|
||||
return self.success(problem_data)
|
||||
|
||||
contest_problems = Problem.objects.select_related("created_by").filter(contest=self.contest, visible=True)
|
||||
|
@ -84,14 +84,13 @@ class SubmissionAPI(APIView):
|
||||
@login_required
|
||||
def put(self, request):
|
||||
try:
|
||||
submission = Submission.objects.select_related("problem")\
|
||||
.get(id=request.data["id"], contest__isnull=True)
|
||||
submission = Submission.objects.select_related("problem").get(id=request.data["id"])
|
||||
except Submission.DoesNotExist:
|
||||
return self.error("Submission doesn't exist")
|
||||
if not submission.check_user_permission(request.user, check_share=False):
|
||||
return self.error("No permission to share the submission")
|
||||
if submission.contest and submission.contest.status == ContestStatus.CONTEST_UNDERWAY:
|
||||
return self.error("Can not share submission during a contest going")
|
||||
return self.error("Can not share submission now")
|
||||
submission.shared = request.data["shared"]
|
||||
submission.save(update_fields=["shared"])
|
||||
return self.success()
|
||||
@ -130,7 +129,7 @@ class ContestSubmissionListAPI(APIView):
|
||||
return self.error("Limit is needed")
|
||||
|
||||
contest = self.contest
|
||||
if contest.rule_type == ContestRuleType.OI and not contest.is_contest_admin(request.user):
|
||||
if not contest.check_oi_permission(request.user):
|
||||
return self.error("No permission for OI contest submissions")
|
||||
|
||||
submissions = Submission.objects.filter(contest_id=contest.id).select_related("problem__created_by")
|
||||
@ -154,9 +153,11 @@ class ContestSubmissionListAPI(APIView):
|
||||
submissions = submissions.filter(create_time__gte=contest.start_time)
|
||||
|
||||
# 封榜的时候只能看到自己的提交
|
||||
if not contest.real_time_rank and not contest.is_contest_admin(request.user):
|
||||
submissions = submissions.filter(user_id=request.user.id)
|
||||
if contest.rule_type == ContestRuleType.ACM:
|
||||
if not contest.real_time_rank and not contest.is_contest_admin(request.user):
|
||||
submissions = submissions.filter(user_id=request.user.id)
|
||||
|
||||
data = self.paginate_data(request, submissions)
|
||||
data["results"] = SubmissionListSerializer(data["results"], many=True, user=request.user).data
|
||||
return self.success(data)
|
||||
|
||||
|
@ -23,6 +23,6 @@ class ContestRuleType(Choices):
|
||||
|
||||
class CacheKey:
|
||||
waiting_queue = "waiting_queue"
|
||||
contest_rank_cache = "contest_rank_cache_"
|
||||
contest_rank_cache = "contest_rank_cache"
|
||||
website_config = "website_config"
|
||||
option = "option"
|
||||
|
Loading…
Reference in New Issue
Block a user