mirror of
https://github.com/QingdaoU/OnlineJudge.git
synced 2024-09-21 00:13:18 +00:00
fix bugs due to problem id
This commit is contained in:
parent
51c229a2c5
commit
2a91fd5e9f
@ -226,7 +226,7 @@ class UserProfileAPITest(APITestCase):
|
|||||||
|
|
||||||
def test_get_profile_without_login(self):
|
def test_get_profile_without_login(self):
|
||||||
resp = self.client.get(self.url)
|
resp = self.client.get(self.url)
|
||||||
self.assertDictEqual(resp.data, {"error": None, "data": 0})
|
self.assertDictEqual(resp.data, {"error": None, "data": {}})
|
||||||
|
|
||||||
def test_get_profile(self):
|
def test_get_profile(self):
|
||||||
self.create_user("test", "test123")
|
self.create_user("test", "test123")
|
||||||
|
@ -39,7 +39,7 @@ class UserProfileAPI(APIView):
|
|||||||
"""
|
"""
|
||||||
user = request.user
|
user = request.user
|
||||||
if not user.is_authenticated():
|
if not user.is_authenticated():
|
||||||
return self.success(0)
|
return self.success({})
|
||||||
username = request.GET.get("username")
|
username = request.GET.get("username")
|
||||||
try:
|
try:
|
||||||
if username:
|
if username:
|
||||||
|
@ -3,6 +3,8 @@ import hashlib
|
|||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
|
||||||
from utils.api.tests import APITestCase
|
from utils.api.tests import APITestCase
|
||||||
|
from utils.cache import default_cache
|
||||||
|
from utils.constants import CacheKey
|
||||||
|
|
||||||
from .models import JudgeServer, JudgeServerToken, SMTPConfig
|
from .models import JudgeServer, JudgeServerToken, SMTPConfig
|
||||||
|
|
||||||
@ -76,7 +78,10 @@ class WebsiteConfigAPITest(APITestCase):
|
|||||||
url = self.reverse("website_info_api")
|
url = self.reverse("website_info_api")
|
||||||
resp = self.client.get(url)
|
resp = self.client.get(url)
|
||||||
self.assertSuccess(resp)
|
self.assertSuccess(resp)
|
||||||
self.assertEqual(resp.data["data"]["name_shortcut"], "test oj")
|
self.assertEqual(resp.data["data"]["name_shortcut"], "oj")
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
default_cache.delete(CacheKey.website_config)
|
||||||
|
|
||||||
|
|
||||||
class JudgeServerHeartbeatTest(APITestCase):
|
class JudgeServerHeartbeatTest(APITestCase):
|
||||||
|
@ -4,17 +4,16 @@ import logging
|
|||||||
from urllib.parse import urljoin
|
from urllib.parse import urljoin
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
from django.core.cache import cache
|
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
from django.db.models import F
|
from django.db.models import F
|
||||||
|
|
||||||
from account.models import User
|
from account.models import User
|
||||||
from conf.models import JudgeServer, JudgeServerToken
|
from conf.models import JudgeServer, JudgeServerToken
|
||||||
from contest.models import ContestRuleType, ACMContestRank, OIContestRank
|
from contest.models import ContestRuleType, ACMContestRank, OIContestRank, ContestStatus
|
||||||
from judge.languages import languages
|
from judge.languages import languages
|
||||||
from problem.models import Problem, ProblemRuleType
|
from problem.models import Problem, ProblemRuleType
|
||||||
from submission.models import JudgeStatus, Submission
|
from submission.models import JudgeStatus, Submission
|
||||||
from utils.cache import judge_cache
|
from utils.cache import judge_cache, default_cache
|
||||||
from utils.constants import CacheKey
|
from utils.constants import CacheKey
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
@ -126,6 +125,7 @@ class JudgeDispatcher(object):
|
|||||||
if resp["err"]:
|
if resp["err"]:
|
||||||
self.submission.result = JudgeStatus.COMPILE_ERROR
|
self.submission.result = JudgeStatus.COMPILE_ERROR
|
||||||
self.submission.statistic_info["err_info"] = resp["data"]
|
self.submission.statistic_info["err_info"] = resp["data"]
|
||||||
|
self.submission.statistic_info["score"] = 0
|
||||||
else:
|
else:
|
||||||
self._compute_statistic_info(resp["data"])
|
self._compute_statistic_info(resp["data"])
|
||||||
error_test_case = list(filter(lambda case: case["result"] != 0, resp["data"]))
|
error_test_case = list(filter(lambda case: case["result"] != 0, resp["data"]))
|
||||||
@ -154,6 +154,9 @@ class JudgeDispatcher(object):
|
|||||||
return self._request(urljoin(service_url, "compile_spj"), data=data)
|
return self._request(urljoin(service_url, "compile_spj"), data=data)
|
||||||
|
|
||||||
def update_problem_status(self):
|
def update_problem_status(self):
|
||||||
|
if self.contest_id and self.contest.status != ContestStatus.CONTEST_UNDERWAY:
|
||||||
|
logger.info("Contest debug mode, id: " + str(self.contest_id) + ", submission id: " + self.submission.id)
|
||||||
|
return
|
||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
# prepare problem and user_profile
|
# prepare problem and user_profile
|
||||||
problem = Problem.objects.select_for_update().get(contest_id=self.contest_id, id=self.problem.id)
|
problem = Problem.objects.select_for_update().get(contest_id=self.contest_id, id=self.problem.id)
|
||||||
@ -168,15 +171,15 @@ class JudgeDispatcher(object):
|
|||||||
oi_problems_status = user_profile.oi_problems_status.get(key, {})
|
oi_problems_status = user_profile.oi_problems_status.get(key, {})
|
||||||
|
|
||||||
# update submission and accepted number counter
|
# 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,
|
# 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
|
# in other words, users' submission in a contest will not be counted in user profile
|
||||||
if not self.contest_id:
|
if not self.contest_id:
|
||||||
user_profile.submission_number += 1
|
user_profile.submission_number += 1
|
||||||
if self.submission.result == JudgeStatus.ACCEPTED:
|
if self.submission.result == JudgeStatus.ACCEPTED:
|
||||||
user_profile.accepted_number += 1
|
user_profile.accepted_number += 1
|
||||||
problem.submission_number += 1
|
|
||||||
if self.submission.result == JudgeStatus.ACCEPTED:
|
|
||||||
problem.accepted_number += 1
|
|
||||||
|
|
||||||
problem_id = str(self.problem.id)
|
problem_id = str(self.problem.id)
|
||||||
if self.problem.rule_type == ProblemRuleType.ACM:
|
if self.problem.rule_type == ProblemRuleType.ACM:
|
||||||
@ -217,8 +220,10 @@ class JudgeDispatcher(object):
|
|||||||
"submission_number", "accepted_number", "acm_problems_status", "oi_problems_status"])
|
"submission_number", "accepted_number", "acm_problems_status", "oi_problems_status"])
|
||||||
|
|
||||||
def update_contest_rank(self):
|
def update_contest_rank(self):
|
||||||
|
if self.contest_id and self.contest.status != ContestStatus.CONTEST_UNDERWAY:
|
||||||
|
return
|
||||||
if self.contest.real_time_rank:
|
if self.contest.real_time_rank:
|
||||||
cache.delete(str(self.contest.id) + "_rank_cache")
|
default_cache.delete(CacheKey.contest_rank_cache + str(self.contest_id))
|
||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
if self.contest.rule_type == ContestRuleType.ACM:
|
if self.contest.rule_type == ContestRuleType.ACM:
|
||||||
acm_rank, _ = ACMContestRank.objects.select_for_update(). \
|
acm_rank, _ = ACMContestRank.objects.select_for_update(). \
|
||||||
@ -232,7 +237,7 @@ class JudgeDispatcher(object):
|
|||||||
def _update_acm_contest_rank(self, rank):
|
def _update_acm_contest_rank(self, rank):
|
||||||
info = rank.submission_info.get(str(self.submission.problem_id))
|
info = rank.submission_info.get(str(self.submission.problem_id))
|
||||||
# 因前面更改过,这里需要重新获取
|
# 因前面更改过,这里需要重新获取
|
||||||
problem = Problem.objects.get(contest_id=self.contest_id, _id=self.problem.id)
|
problem = Problem.objects.get(contest_id=self.contest_id, id=self.problem.id)
|
||||||
# 此题提交过
|
# 此题提交过
|
||||||
if info:
|
if info:
|
||||||
if info["is_ac"]:
|
if info["is_ac"]:
|
||||||
|
@ -18,7 +18,8 @@ class ProblemAPI(APIView):
|
|||||||
problem_id = request.GET.get("problem_id")
|
problem_id = request.GET.get("problem_id")
|
||||||
if problem_id:
|
if problem_id:
|
||||||
try:
|
try:
|
||||||
problem = Problem.objects.select_related("created_by").get(_id=problem_id, visible=True)
|
problem = Problem.objects.select_related("created_by")\
|
||||||
|
.get(_id=problem_id, contest_id__isnull=True, visible=True)
|
||||||
return self.success(ProblemSerializer(problem).data)
|
return self.success(ProblemSerializer(problem).data)
|
||||||
except Problem.DoesNotExist:
|
except Problem.DoesNotExist:
|
||||||
return self.error("Problem does not exist")
|
return self.error("Problem does not exist")
|
||||||
@ -27,7 +28,7 @@ class ProblemAPI(APIView):
|
|||||||
if not limit:
|
if not limit:
|
||||||
return self.error("Limit is needed")
|
return self.error("Limit is needed")
|
||||||
|
|
||||||
problems = Problem.objects.select_related("created_by").filter(visible=True)
|
problems = Problem.objects.select_related("created_by").filter(contest_id__isnull=True, visible=True)
|
||||||
# 按照标签筛选
|
# 按照标签筛选
|
||||||
tag_text = request.GET.get("tag")
|
tag_text = request.GET.get("tag")
|
||||||
if tag_text:
|
if tag_text:
|
||||||
@ -54,9 +55,9 @@ class ProblemAPI(APIView):
|
|||||||
oi_problems_status = profile.oi_problems_status.get("problems", {})
|
oi_problems_status = profile.oi_problems_status.get("problems", {})
|
||||||
for problem in data["results"]:
|
for problem in data["results"]:
|
||||||
if problem["rule_type"] == ProblemRuleType.ACM:
|
if problem["rule_type"] == ProblemRuleType.ACM:
|
||||||
problem["my_status"] = acm_problems_status.get(problem["_id"], None)
|
problem["my_status"] = acm_problems_status.get(str(problem["id"]), None)
|
||||||
else:
|
else:
|
||||||
problem["my_status"] = oi_problems_status.get(problem["_id"], None)
|
problem["my_status"] = oi_problems_status.get(str(problem["id"]), None)
|
||||||
return self.success(data)
|
return self.success(data)
|
||||||
|
|
||||||
|
|
||||||
@ -83,5 +84,5 @@ class ContestProblemAPI(APIView):
|
|||||||
else:
|
else:
|
||||||
problems_status = profile.oi_problems_status.get("contest_problems", {})
|
problems_status = profile.oi_problems_status.get("contest_problems", {})
|
||||||
for problem in data:
|
for problem in data:
|
||||||
problem["my_status"] = problems_status.get(problem["_id"], None)
|
problem["my_status"] = problems_status.get(str(problem["id"]), None)
|
||||||
return self.success(ContestProblemSerializer(contest_problems, many=True).data)
|
return self.success(data)
|
||||||
|
@ -20,6 +20,7 @@ class SubmissionModelSerializer(serializers.ModelSerializer):
|
|||||||
|
|
||||||
# 不显示submission info的serializer, 用于ACM rule_type
|
# 不显示submission info的serializer, 用于ACM rule_type
|
||||||
class SubmissionSafeSerializer(serializers.ModelSerializer):
|
class SubmissionSafeSerializer(serializers.ModelSerializer):
|
||||||
|
problem = serializers.SlugRelatedField(read_only=True, slug_field="_id")
|
||||||
statistic_info = serializers.JSONField()
|
statistic_info = serializers.JSONField()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
@ -28,6 +29,7 @@ class SubmissionSafeSerializer(serializers.ModelSerializer):
|
|||||||
|
|
||||||
|
|
||||||
class SubmissionListSerializer(serializers.ModelSerializer):
|
class SubmissionListSerializer(serializers.ModelSerializer):
|
||||||
|
problem = serializers.SlugRelatedField(read_only=True, slug_field="_id")
|
||||||
statistic_info = serializers.JSONField()
|
statistic_info = serializers.JSONField()
|
||||||
show_link = serializers.SerializerMethodField()
|
show_link = serializers.SerializerMethodField()
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ DEFAULT_PROBLEM_DATA = {"_id": "110", "title": "test", "description": "<p>test</
|
|||||||
"rule_type": "ACM", "hint": "<p>test</p>", "source": "test"}
|
"rule_type": "ACM", "hint": "<p>test</p>", "source": "test"}
|
||||||
|
|
||||||
DEFAULT_SUBMISSION_DATA = {
|
DEFAULT_SUBMISSION_DATA = {
|
||||||
"problem_id": "110",
|
"problem_id": "1",
|
||||||
"user_id": 1,
|
"user_id": 1,
|
||||||
"username": "test",
|
"username": "test",
|
||||||
"code": "xxxxxxxxxxxxxx",
|
"code": "xxxxxxxxxxxxxx",
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
from account.models import AdminType
|
||||||
from account.decorators import login_required, check_contest_permission
|
from account.decorators import login_required, check_contest_permission
|
||||||
from judge.tasks import judge_task
|
from judge.tasks import judge_task
|
||||||
# from judge.dispatcher import JudgeDispatcher
|
# from judge.dispatcher import JudgeDispatcher
|
||||||
@ -25,7 +26,7 @@ def _submit(response, user, problem_id, language, code, contest_id):
|
|||||||
return response.error("Please wait %d seconds" % int(bucket.expected_time() + 1))
|
return response.error("Please wait %d seconds" % int(bucket.expected_time() + 1))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
problem = Problem.objects.get(_id=problem_id,
|
problem = Problem.objects.get(id=problem_id,
|
||||||
contest_id=contest_id,
|
contest_id=contest_id,
|
||||||
visible=True)
|
visible=True)
|
||||||
except Problem.DoesNotExist:
|
except Problem.DoesNotExist:
|
||||||
@ -53,8 +54,10 @@ class SubmissionAPI(APIView):
|
|||||||
contest = Contest.objects.get(id=data["contest_id"])
|
contest = Contest.objects.get(id=data["contest_id"])
|
||||||
except Contest.DoesNotExist:
|
except Contest.DoesNotExist:
|
||||||
return self.error("Contest doesn't exist.")
|
return self.error("Contest doesn't exist.")
|
||||||
if contest.status != ContestStatus.CONTEST_UNDERWAY and request.user != contest.created_by:
|
if contest.status == ContestStatus.CONTEST_ENDED:
|
||||||
return self.error("Contest have not started or have ended, you can't submit code.")
|
return self.error("The contest have ended")
|
||||||
|
if contest.status == ContestStatus.CONTEST_NOT_START and request.user != contest.created_by:
|
||||||
|
return self.error("Contest have not started")
|
||||||
return _submit(self, request.user, data["problem_id"], data["language"], data["code"], data.get("contest_id"))
|
return _submit(self, request.user, data["problem_id"], data["language"], data["code"], data.get("contest_id"))
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@ -86,8 +89,21 @@ class SubmissionListAPI(APIView):
|
|||||||
|
|
||||||
@check_contest_permission
|
@check_contest_permission
|
||||||
def _get_contest_submission_list(self, request):
|
def _get_contest_submission_list(self, request):
|
||||||
subs = Submission.objects.filter(contest_id=self.contest.id)
|
contest = self.contest
|
||||||
return self.process_submissions(request, subs)
|
# todo OI mode
|
||||||
|
submissions = Submission.objects.filter(contest_id=contest.id)
|
||||||
|
# filter the test submissions submitted before contest start
|
||||||
|
if contest.status != ContestStatus.CONTEST_NOT_START:
|
||||||
|
print(contest.start_time)
|
||||||
|
submissions = submissions.filter(create_time__gte=contest.start_time)
|
||||||
|
|
||||||
|
# 封榜的时候只能看到自己的提交
|
||||||
|
if not contest.real_time_rank:
|
||||||
|
if request.user and not (
|
||||||
|
request.user.admin_type == AdminType.SUPER_ADMIN or request.user == contest.created_by):
|
||||||
|
submissions = submissions.filter(user_id=request.user.id)
|
||||||
|
|
||||||
|
return self.process_submissions(request, submissions)
|
||||||
|
|
||||||
def process_submissions(self, request, submissions):
|
def process_submissions(self, request, submissions):
|
||||||
problem_id = request.GET.get("problem_id")
|
problem_id = request.GET.get("problem_id")
|
||||||
@ -98,7 +114,7 @@ class SubmissionListAPI(APIView):
|
|||||||
problem = Problem.objects.get(_id=problem_id, visible=True)
|
problem = Problem.objects.get(_id=problem_id, visible=True)
|
||||||
except Problem.DoesNotExist:
|
except Problem.DoesNotExist:
|
||||||
return self.error("Problem doesn't exist")
|
return self.error("Problem doesn't exist")
|
||||||
submissions = problem.submission_set.all()
|
submissions = submissions.filter(problem=problem)
|
||||||
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)
|
||||||
if result:
|
if result:
|
||||||
|
Loading…
Reference in New Issue
Block a user