在前台添加今日提交数

This commit is contained in:
2025-04-14 12:32:49 +08:00
parent e5939d3592
commit 025276002d
2 changed files with 89 additions and 32 deletions

View File

@@ -1,6 +1,11 @@
from django.urls import path from django.urls import path
from ..views.oj import SubmissionAPI, SubmissionListAPI, ContestSubmissionListAPI, SubmissionExistsAPI from ..views.oj import (
SubmissionAPI,
SubmissionListAPI,
ContestSubmissionListAPI,
SubmissionExistsAPI,
)
urlpatterns = [ urlpatterns = [
path("submission", SubmissionAPI.as_view()), path("submission", SubmissionAPI.as_view()),

View File

@@ -1,9 +1,11 @@
from datetime import datetime
import ipaddress import ipaddress
from account.decorators import login_required, check_contest_permission from account.decorators import login_required, check_contest_permission
from contest.models import ContestStatus, ContestRuleType from contest.models import ContestStatus, ContestRuleType
from judge.tasks import judge_task from judge.tasks import judge_task
from options.options import SysOptions from options.options import SysOptions
# from judge.dispatcher import JudgeDispatcher # from judge.dispatcher import JudgeDispatcher
from problem.models import Problem, ProblemRuleType from problem.models import Problem, ProblemRuleType
from utils.api import APIView, validate_serializer from utils.api import APIView, validate_serializer
@@ -11,8 +13,11 @@ from utils.cache import cache
from utils.captcha import Captcha from utils.captcha import Captcha
from utils.throttling import TokenBucket from utils.throttling import TokenBucket
from ..models import Submission from ..models import Submission
from ..serializers import (CreateSubmissionSerializer, SubmissionModelSerializer, from ..serializers import (
ShareSubmissionSerializer) CreateSubmissionSerializer,
SubmissionModelSerializer,
ShareSubmissionSerializer,
)
from ..serializers import SubmissionSafeModelSerializer, SubmissionListSerializer from ..serializers import SubmissionSafeModelSerializer, SubmissionListSerializer
@@ -22,8 +27,9 @@ class SubmissionAPI(APIView):
auth_method = getattr(request, "auth_method", "") auth_method = getattr(request, "auth_method", "")
if auth_method == "api_key": if auth_method == "api_key":
return return
user_bucket = TokenBucket(key=str(request.user.id), user_bucket = TokenBucket(
redis_conn=cache, **SysOptions.throttling["user"]) key=str(request.user.id), redis_conn=cache, **SysOptions.throttling["user"]
)
can_consume, wait = user_bucket.consume() can_consume, wait = user_bucket.consume()
if not can_consume: if not can_consume:
return "Please wait %d seconds" % (int(wait)) return "Please wait %d seconds" % (int(wait))
@@ -42,7 +48,10 @@ class SubmissionAPI(APIView):
if not request.user.is_contest_admin(contest): if not request.user.is_contest_admin(contest):
user_ip = ipaddress.ip_address(request.session.get("ip")) user_ip = ipaddress.ip_address(request.session.get("ip"))
if contest.allowed_ip_ranges: 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") return self.error("Your IP is not allowed in this contest")
@validate_serializer(CreateSubmissionSerializer) @validate_serializer(CreateSubmissionSerializer)
@@ -66,18 +75,22 @@ class SubmissionAPI(APIView):
return self.error(error) return self.error(error)
try: try:
problem = Problem.objects.get(id=data["problem_id"], contest_id=data.get("contest_id"), visible=True) problem = Problem.objects.get(
id=data["problem_id"], contest_id=data.get("contest_id"), visible=True
)
except Problem.DoesNotExist: except Problem.DoesNotExist:
return self.error("Problem not exist") return self.error("Problem not exist")
if data["language"] not in problem.languages: if data["language"] not in problem.languages:
return self.error(f"{data['language']} is not allowed in the problem") return self.error(f"{data['language']} is not allowed in the problem")
submission = Submission.objects.create(user_id=request.user.id, submission = Submission.objects.create(
username=request.user.username, user_id=request.user.id,
language=data["language"], username=request.user.username,
code=data["code"], language=data["language"],
problem_id=problem.id, code=data["code"],
ip=request.session["ip"], problem_id=problem.id,
contest_id=data.get("contest_id")) ip=request.session["ip"],
contest_id=data.get("contest_id"),
)
# use this for debug # use this for debug
# JudgeDispatcher(submission.id, problem.id).judge() # JudgeDispatcher(submission.id, problem.id).judge()
judge_task.send(submission.id, problem.id) judge_task.send(submission.id, problem.id)
@@ -92,18 +105,25 @@ class SubmissionAPI(APIView):
if not submission_id: if not submission_id:
return self.error("Parameter id doesn't exist") return self.error("Parameter id doesn't exist")
try: try:
submission = Submission.objects.select_related("problem").get(id=submission_id) submission = Submission.objects.select_related("problem").get(
id=submission_id
)
except Submission.DoesNotExist: except Submission.DoesNotExist:
return self.error("Submission doesn't exist") return self.error("Submission doesn't exist")
if not submission.check_user_permission(request.user): if not submission.check_user_permission(request.user):
return self.error("No permission for this submission") 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 submission_data = SubmissionModelSerializer(submission).data
else: else:
submission_data = SubmissionSafeModelSerializer(submission).data 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) return self.success(submission_data)
@validate_serializer(ShareSubmissionSerializer) @validate_serializer(ShareSubmissionSerializer)
@@ -113,12 +133,17 @@ class SubmissionAPI(APIView):
share submission share submission
""" """
try: 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: except Submission.DoesNotExist:
return self.error("Submission doesn't exist") return self.error("Submission doesn't exist")
if not submission.check_user_permission(request.user, check_share=False): if not submission.check_user_permission(request.user, check_share=False):
return self.error("No permission to share the submission") 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") return self.error("Can not share submission now")
submission.shared = request.data["shared"] submission.shared = request.data["shared"]
submission.save(update_fields=["shared"]) submission.save(update_fields=["shared"])
@@ -132,21 +157,28 @@ class SubmissionListAPI(APIView):
if request.GET.get("contest_id"): if request.GET.get("contest_id"):
return self.error("Parameter error") 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") problem_id = request.GET.get("problem_id")
myself = request.GET.get("myself") myself = request.GET.get("myself")
result = request.GET.get("result") result = request.GET.get("result")
username = request.GET.get("username") username = request.GET.get("username")
if problem_id: if problem_id:
try: 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: except Problem.DoesNotExist:
return self.error("Problem doesn't exist") return self.error("Problem doesn't exist")
submissions = submissions.filter(problem=problem) submissions = submissions.filter(problem=problem)
if not SysOptions.submission_list_show_all and not request.user.is_super_admin(): if (
not SysOptions.submission_list_show_all
and not request.user.is_super_admin()
):
return self.success({"results": [], "total": 0}) return self.success({"results": [], "total": 0})
if myself and myself == "1": if myself and myself == "1":
submissions = submissions.filter(user_id=request.user.id) submissions = submissions.filter(user_id=request.user.id)
elif username: elif username:
@@ -155,7 +187,16 @@ class SubmissionListAPI(APIView):
submissions = submissions.filter(result=result) submissions = submissions.filter(result=result)
data = self.paginate_data(request, submissions) 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
today = datetime.today()
today_submissions_count = Submission.objects.filter(
create_time__gte=datetime(today.year, today.month, today.day, 0, 0)
).count()
data["today_count"] = today_submissions_count
return self.success(data) return self.success(data)
@@ -166,14 +207,18 @@ class ContestSubmissionListAPI(APIView):
return self.error("Limit is needed") return self.error("Limit is needed")
contest = self.contest 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") problem_id = request.GET.get("problem_id")
myself = request.GET.get("myself") myself = request.GET.get("myself")
result = request.GET.get("result") result = request.GET.get("result")
username = request.GET.get("username") username = request.GET.get("username")
if problem_id: if problem_id:
try: 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: except Problem.DoesNotExist:
return self.error("Problem doesn't exist") return self.error("Problem doesn't exist")
submissions = submissions.filter(problem=problem) submissions = submissions.filter(problem=problem)
@@ -191,11 +236,15 @@ class ContestSubmissionListAPI(APIView):
# 封榜的时候只能看到自己的提交 # 封榜的时候只能看到自己的提交
if contest.rule_type == ContestRuleType.ACM: 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) submissions = submissions.filter(user_id=request.user.id)
data = self.paginate_data(request, submissions) 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) return self.success(data)
@@ -203,6 +252,9 @@ class SubmissionExistsAPI(APIView):
def get(self, request): def get(self, request):
if not request.GET.get("problem_id"): if not request.GET.get("problem_id"):
return self.error("Parameter error, problem_id is required") return self.error("Parameter error, problem_id is required")
return self.success(request.user.is_authenticated and return self.success(
Submission.objects.filter(problem_id=request.GET["problem_id"], request.user.is_authenticated
user_id=request.user.id).exists()) and Submission.objects.filter(
problem_id=request.GET["problem_id"], user_id=request.user.id
).exists()
)