From 9560f15c4deef4a2e41577cb883c43aba7c3ac5a Mon Sep 17 00:00:00 2001 From: Tree Saengja Date: Mon, 21 Mar 2022 11:02:49 +0700 Subject: [PATCH] :sparkles: admin submit invisible problem --- submission/views/oj.py | 104 ++++++++++++++++++++++++++++++----------- 1 file changed, 76 insertions(+), 28 deletions(-) diff --git a/submission/views/oj.py b/submission/views/oj.py index 0f7c4a58..351b001a 100644 --- a/submission/views/oj.py +++ b/submission/views/oj.py @@ -4,6 +4,7 @@ from account.decorators import login_required, check_contest_permission from contest.models import ContestStatus, ContestRuleType from judge.tasks import judge_task from options.options import SysOptions + # from judge.dispatcher import JudgeDispatcher from problem.models import Problem, ProblemRuleType from utils.api import APIView, validate_serializer @@ -11,8 +12,11 @@ from utils.cache import cache from utils.captcha import Captcha from utils.throttling import TokenBucket from ..models import Submission -from ..serializers import (CreateSubmissionSerializer, SubmissionModelSerializer, - ShareSubmissionSerializer) +from ..serializers import ( + CreateSubmissionSerializer, + SubmissionModelSerializer, + ShareSubmissionSerializer, +) from ..serializers import SubmissionSafeModelSerializer, SubmissionListSerializer @@ -22,8 +26,9 @@ class SubmissionAPI(APIView): auth_method = getattr(request, "auth_method", "") if auth_method == "api_key": return - user_bucket = TokenBucket(key=str(request.user.id), - redis_conn=cache, **SysOptions.throttling["user"]) + user_bucket = TokenBucket( + key=str(request.user.id), redis_conn=cache, **SysOptions.throttling["user"] + ) can_consume, wait = user_bucket.consume() if not can_consume: return "Please wait %d seconds" % (int(wait)) @@ -42,7 +47,10 @@ class SubmissionAPI(APIView): if not request.user.is_contest_admin(contest): user_ip = ipaddress.ip_address(request.session.get("ip")) if contest.allowed_ip_ranges: - if not any(user_ip in ipaddress.ip_network(cidr, strict=False) for cidr in contest.allowed_ip_ranges): + if not any( + user_ip in ipaddress.ip_network(cidr, strict=False) + for cidr in contest.allowed_ip_ranges + ): return self.error("Your IP is not allowed in this contest") @validate_serializer(CreateSubmissionSerializer) @@ -66,18 +74,29 @@ class SubmissionAPI(APIView): return self.error(error) try: - problem = Problem.objects.get(id=data["problem_id"], contest_id=data.get("contest_id"), visible=True) + if request.user.is_admin_role: + problem = Problem.objects.get( + id=data["problem_id"], contest_id=data.get("contest_id") + ) + else: + problem = Problem.objects.get( + id=data["problem_id"], + contest_id=data.get("contest_id"), + visible=True, + ) except Problem.DoesNotExist: return self.error("Problem not exist") if data["language"] not in problem.languages: return self.error(f"{data['language']} is now allowed in the problem") - submission = Submission.objects.create(user_id=request.user.id, - username=request.user.username, - language=data["language"], - code=data["code"], - problem_id=problem.id, - ip=request.session["ip"], - contest_id=data.get("contest_id")) + submission = Submission.objects.create( + user_id=request.user.id, + username=request.user.username, + language=data["language"], + code=data["code"], + problem_id=problem.id, + ip=request.session["ip"], + contest_id=data.get("contest_id"), + ) # use this for debug # JudgeDispatcher(submission.id, problem.id).judge() judge_task.send(submission.id, problem.id) @@ -92,18 +111,25 @@ class SubmissionAPI(APIView): if not submission_id: return self.error("Parameter id doesn't exist") try: - submission = Submission.objects.select_related("problem").get(id=submission_id) + submission = Submission.objects.select_related("problem").get( + id=submission_id + ) except Submission.DoesNotExist: return self.error("Submission doesn't exist") if not submission.check_user_permission(request.user): return self.error("No permission for this submission") - if submission.problem.rule_type == ProblemRuleType.OI or request.user.is_admin_role(): + if ( + submission.problem.rule_type == ProblemRuleType.OI + or request.user.is_admin_role() + ): submission_data = SubmissionModelSerializer(submission).data else: submission_data = SubmissionSafeModelSerializer(submission).data # 是否有权限取消共享 - submission_data["can_unshare"] = submission.check_user_permission(request.user, check_share=False) + submission_data["can_unshare"] = submission.check_user_permission( + request.user, check_share=False + ) return self.success(submission_data) @validate_serializer(ShareSubmissionSerializer) @@ -113,12 +139,17 @@ class SubmissionAPI(APIView): share submission """ try: - submission = Submission.objects.select_related("problem").get(id=request.data["id"]) + 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: + if ( + submission.contest + and submission.contest.status == ContestStatus.CONTEST_UNDERWAY + ): return self.error("Can not share submission now") submission.shared = request.data["shared"] submission.save(update_fields=["shared"]) @@ -132,14 +163,18 @@ class SubmissionListAPI(APIView): if request.GET.get("contest_id"): return self.error("Parameter error") - submissions = Submission.objects.filter(contest_id__isnull=True).select_related("problem__created_by") + submissions = Submission.objects.filter(contest_id__isnull=True).select_related( + "problem__created_by" + ) problem_id = request.GET.get("problem_id") myself = request.GET.get("myself") result = request.GET.get("result") username = request.GET.get("username") if problem_id: try: - problem = Problem.objects.get(_id=problem_id, contest_id__isnull=True, visible=True) + problem = Problem.objects.get( + _id=problem_id, contest_id__isnull=True, visible=True + ) except Problem.DoesNotExist: return self.error("Problem doesn't exist") submissions = submissions.filter(problem=problem) @@ -150,7 +185,9 @@ class SubmissionListAPI(APIView): if result: submissions = submissions.filter(result=result) data = self.paginate_data(request, submissions) - data["results"] = SubmissionListSerializer(data["results"], many=True, user=request.user).data + data["results"] = SubmissionListSerializer( + data["results"], many=True, user=request.user + ).data return self.success(data) @@ -161,14 +198,18 @@ class ContestSubmissionListAPI(APIView): return self.error("Limit is needed") contest = self.contest - submissions = Submission.objects.filter(contest_id=contest.id).select_related("problem__created_by") + submissions = Submission.objects.filter(contest_id=contest.id).select_related( + "problem__created_by" + ) problem_id = request.GET.get("problem_id") myself = request.GET.get("myself") result = request.GET.get("result") username = request.GET.get("username") if problem_id: try: - problem = Problem.objects.get(_id=problem_id, contest_id=contest.id, visible=True) + problem = Problem.objects.get( + _id=problem_id, contest_id=contest.id, visible=True + ) except Problem.DoesNotExist: return self.error("Problem doesn't exist") submissions = submissions.filter(problem=problem) @@ -186,11 +227,15 @@ class ContestSubmissionListAPI(APIView): # 封榜的时候只能看到自己的提交 if contest.rule_type == ContestRuleType.ACM: - if not contest.real_time_rank and not request.user.is_contest_admin(contest): + if not contest.real_time_rank and not request.user.is_contest_admin( + contest + ): 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 + data["results"] = SubmissionListSerializer( + data["results"], many=True, user=request.user + ).data return self.success(data) @@ -198,6 +243,9 @@ class SubmissionExistsAPI(APIView): def get(self, request): if not request.GET.get("problem_id"): return self.error("Parameter error, problem_id is required") - return self.success(request.user.is_authenticated and - Submission.objects.filter(problem_id=request.GET["problem_id"], - user_id=request.user.id).exists()) + return self.success( + request.user.is_authenticated + and Submission.objects.filter( + problem_id=request.GET["problem_id"], user_id=request.user.id + ).exists() + )