2017-05-08 09:29:01 +00:00
|
|
|
|
from django.core.paginator import Paginator
|
2017-05-09 06:41:26 +00:00
|
|
|
|
from django_redis import get_redis_connection
|
2017-05-08 09:29:01 +00:00
|
|
|
|
|
|
|
|
|
from account.decorators import login_required
|
|
|
|
|
from account.models import AdminType, User
|
|
|
|
|
from problem.models import Problem
|
2017-05-10 09:20:52 +00:00
|
|
|
|
from submission.tasks import judge_task
|
2017-05-15 08:42:15 +00:00
|
|
|
|
# from judge.dispatcher import JudgeDispatcher
|
2017-05-08 09:29:01 +00:00
|
|
|
|
from utils.api import APIView, validate_serializer
|
|
|
|
|
from utils.shortcuts import build_query_string
|
|
|
|
|
from utils.throttling import TokenBucket, BucketController
|
2017-05-15 05:09:54 +00:00
|
|
|
|
from ..models import Submission, JudgeStatus
|
2017-05-15 08:42:15 +00:00
|
|
|
|
from ..serializers import CreateSubmissionSerializer, SubmissionModelSerializer
|
2017-05-08 09:29:01 +00:00
|
|
|
|
|
|
|
|
|
|
2017-05-15 08:42:15 +00:00
|
|
|
|
def _submit(response, user, problem_id, language, code, contest_id=None):
|
2017-05-15 05:09:54 +00:00
|
|
|
|
# TODO: 预设默认值,需修改
|
|
|
|
|
controller = BucketController(user_id=user.id,
|
|
|
|
|
redis_conn=get_redis_connection("Throttling"),
|
|
|
|
|
default_capacity=30)
|
|
|
|
|
bucket = TokenBucket(fill_rate=10, capacity=20,
|
|
|
|
|
last_capacity=controller.last_capacity,
|
|
|
|
|
last_timestamp=controller.last_timestamp)
|
|
|
|
|
|
|
|
|
|
if bucket.consume():
|
|
|
|
|
controller.last_capacity -= 1
|
|
|
|
|
else:
|
|
|
|
|
return response.error("Please wait %d seconds" % int(bucket.expected_time() + 1))
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
problem = Problem.objects.get(id=problem_id)
|
|
|
|
|
except Problem.DoesNotExist:
|
|
|
|
|
return response.error("Problem not exist")
|
|
|
|
|
|
|
|
|
|
submission = Submission.objects.create(user_id=user.id,
|
|
|
|
|
language=language,
|
|
|
|
|
code=code,
|
2017-05-15 08:42:15 +00:00
|
|
|
|
problem_id=problem.id,
|
|
|
|
|
contest_id=contest_id)
|
2017-07-04 09:32:50 +00:00
|
|
|
|
# todo 暂时保留 方便排错
|
2017-05-15 08:42:15 +00:00
|
|
|
|
# JudgeDispatcher(submission.id, problem.id).judge()
|
2017-05-15 05:09:54 +00:00
|
|
|
|
judge_task.delay(submission.id, problem.id)
|
|
|
|
|
return response.success({"submission_id": submission.id})
|
|
|
|
|
|
|
|
|
|
|
2017-05-08 09:29:01 +00:00
|
|
|
|
class SubmissionAPI(APIView):
|
|
|
|
|
@validate_serializer(CreateSubmissionSerializer)
|
2017-05-15 08:42:15 +00:00
|
|
|
|
@login_required
|
2017-05-08 09:29:01 +00:00
|
|
|
|
def post(self, request):
|
|
|
|
|
data = request.data
|
2017-05-15 05:09:54 +00:00
|
|
|
|
return _submit(self, request.user, data["problem_id"], data["language"], data["code"])
|
2017-05-08 09:29:01 +00:00
|
|
|
|
|
|
|
|
|
@login_required
|
|
|
|
|
def get(self, request):
|
2017-05-15 08:42:15 +00:00
|
|
|
|
submission_id = request.GET.get("id")
|
2017-07-04 09:32:50 +00:00
|
|
|
|
if submission_id:
|
|
|
|
|
try:
|
|
|
|
|
submission = Submission.objects.get(id=submission_id, user_id=request.user.id)
|
|
|
|
|
except Submission.DoesNotExist:
|
|
|
|
|
return self.error("Submission not exist")
|
|
|
|
|
return self.success(SubmissionModelSerializer(submission).data)
|
2017-05-08 09:29:01 +00:00
|
|
|
|
|
2017-07-04 09:32:50 +00:00
|
|
|
|
problem_id = request.GET.get('problem_id')
|
|
|
|
|
subs = Submission.objects.filter(contest_id__isnull=True)
|
|
|
|
|
if problem_id:
|
|
|
|
|
subs = subs.filter(problem_id=problem_id)
|
2017-05-08 09:29:01 +00:00
|
|
|
|
|
2017-07-04 09:32:50 +00:00
|
|
|
|
if request.GET.get('myself'):
|
|
|
|
|
subs = subs.filter(user_id=request.user.id)
|
|
|
|
|
# todo: paginate
|
|
|
|
|
return self.success(SubmissionModelSerializer(subs, many=True).data)
|
2017-05-08 09:29:01 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class SubmissionListAPI(APIView):
|
|
|
|
|
"""
|
|
|
|
|
所有提交的列表
|
|
|
|
|
"""
|
|
|
|
|
def get(self, request, **kwargs):
|
|
|
|
|
submission_filter = {"my": None, "user_id": None}
|
|
|
|
|
show_all = False
|
|
|
|
|
page = kwargs.get("page", 1)
|
|
|
|
|
|
|
|
|
|
user_id = request.GET.get("user_id")
|
|
|
|
|
if user_id and request.user.admin_type == AdminType.SUPER_ADMIN:
|
|
|
|
|
submission_filter["user_id"] = user_id
|
|
|
|
|
submissions = Submission.objects.filter(user_id=user_id, contest_id__isnull=True)
|
|
|
|
|
else:
|
|
|
|
|
show_all = True
|
|
|
|
|
if request.GET.get("my") == "true":
|
|
|
|
|
submission_filter["my"] = "true"
|
|
|
|
|
show_all = False
|
|
|
|
|
if show_all:
|
|
|
|
|
submissions = Submission.objects.filter(contest_id__isnull=True)
|
|
|
|
|
else:
|
|
|
|
|
submissions = Submission.objects.filter(user_id=request.user.id, contest_id__isnull=True)
|
|
|
|
|
|
|
|
|
|
submissions = submissions.values("id", "user_id", "problem_id", "result", "created_time",
|
|
|
|
|
"accepted_time", "language").order_by("-created_time")
|
|
|
|
|
language = request.GET.get("language")
|
|
|
|
|
if language:
|
|
|
|
|
submissions = submissions.filter(language=language)
|
|
|
|
|
submission_filter["language"] = language
|
|
|
|
|
|
|
|
|
|
result = request.GET.get("result")
|
|
|
|
|
if result:
|
|
|
|
|
# TODO: 转换为数字结果
|
|
|
|
|
submissions = submissions.filter(result=int(result))
|
|
|
|
|
submission_filter["result"] = result
|
|
|
|
|
|
|
|
|
|
paginator = Paginator(submissions, 20)
|
|
|
|
|
try:
|
|
|
|
|
submissions = paginator.page(int(page))
|
|
|
|
|
except Exception:
|
|
|
|
|
return self.error("Page not exist")
|
|
|
|
|
|
|
|
|
|
# Cache
|
|
|
|
|
cache_result = {"problem": {}, "user": {}}
|
|
|
|
|
for item in submissions:
|
|
|
|
|
problem_id = item["problem_id"]
|
|
|
|
|
if problem_id not in cache_result["problem"]:
|
|
|
|
|
problem = Problem.objects.get(id=problem_id)
|
|
|
|
|
cache_result["problem"][problem_id] = problem.title
|
|
|
|
|
item["title"] = cache_result["problem"][problem_id]
|
|
|
|
|
|
|
|
|
|
user_id = item["user_id"]
|
|
|
|
|
if user_id not in cache_result["user"]:
|
|
|
|
|
user = User.objects.get(id=user_id)
|
|
|
|
|
cache_result["user"][user_id] = user
|
|
|
|
|
item["user"] = cache_result["user"][user_id]
|
|
|
|
|
|
|
|
|
|
if item["user_id"] == request.user.id or request.user.admin_type == AdminType.SUPER_ADMIN:
|
|
|
|
|
item["show_link"] = True
|
|
|
|
|
else:
|
|
|
|
|
item["show_link"] = False
|
|
|
|
|
|
2017-05-15 05:09:54 +00:00
|
|
|
|
previous_page = next_page = None
|
|
|
|
|
try:
|
|
|
|
|
previous_page = submissions.previous_page_number()
|
|
|
|
|
except Exception:
|
|
|
|
|
pass
|
|
|
|
|
try:
|
|
|
|
|
next_page = submissions.next_page_number()
|
|
|
|
|
except Exception:
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
return self.success({"submissions": submissions.object_list, "page": int(page),
|
|
|
|
|
"previous_page": previous_page, "next_page": next_page,
|
|
|
|
|
"start_id": int(page) * 20 - 20,
|
|
|
|
|
"query": build_query_string(submission_filter),
|
|
|
|
|
"submission_filter": submission_filter,
|
|
|
|
|
"show_all": show_all})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _get_submission(submission_id, user):
|
|
|
|
|
"""
|
|
|
|
|
用户权限判断
|
|
|
|
|
"""
|
|
|
|
|
submission = Submission.objects.get(id=submission_id)
|
|
|
|
|
# Super Admin / Owner / Share
|
|
|
|
|
if user.admin_type == AdminType.SUPER_ADMIN or submission.user_id == user.id:
|
|
|
|
|
return {"submission": submission, "can_share": True}
|
|
|
|
|
if submission.contest_id:
|
|
|
|
|
# 比赛部分
|
|
|
|
|
pass
|
|
|
|
|
if submission.shared:
|
|
|
|
|
return {"submission": submission, "can_share": False}
|
|
|
|
|
else:
|
|
|
|
|
raise Submission.DoesNotExist
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class SubmissionDetailAPI(APIView):
|
|
|
|
|
"""
|
|
|
|
|
单个提交页面详情
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
def get(self, request, **kwargs):
|
|
|
|
|
try:
|
|
|
|
|
result = _get_submission(kwargs["submission_id"], request.user)
|
|
|
|
|
submission = result["submission"]
|
|
|
|
|
except Submission.DoesNotExist:
|
|
|
|
|
return self.error("Submission not exist")
|
|
|
|
|
|
|
|
|
|
# TODO: Contest
|
|
|
|
|
try:
|
|
|
|
|
if submission.contest_id:
|
|
|
|
|
# problem = ContestProblem.objects.get(id=submission.problem_id, visible=True)
|
2017-05-08 09:29:01 +00:00
|
|
|
|
pass
|
2017-05-15 05:09:54 +00:00
|
|
|
|
else:
|
|
|
|
|
problem = Problem.objects.get(id=submission.problem_id, visible=True)
|
|
|
|
|
except (Problem.DoesNotExist, ):
|
|
|
|
|
return self.error("Submission not exist")
|
|
|
|
|
|
|
|
|
|
if submission.result in [JudgeStatus.COMPILE_ERROR, JudgeStatus.SYSTEM_ERROR, JudgeStatus.PENDING]:
|
|
|
|
|
info = submission.info
|
|
|
|
|
else:
|
|
|
|
|
info = submission.info
|
|
|
|
|
if "test_case" in info[0]:
|
|
|
|
|
info = sorted(info, key=lambda x: x["test_case"])
|
2017-05-08 09:29:01 +00:00
|
|
|
|
|
2017-05-15 05:09:54 +00:00
|
|
|
|
user = User.objects.get(id=submission.user_id)
|
|
|
|
|
return self.success({"submission": submission, "problem": problem, "info": info,
|
|
|
|
|
"user": user, "can_share": result["can_share"]})
|