OnlineJudge/submission/views/oj.py
2017-05-10 17:46:59 +08:00

159 lines
6.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from django.core.paginator import Paginator
from django_redis import get_redis_connection
from account.decorators import login_required
from account.models import AdminType, User
from problem.models import Problem
from submission.tasks import judge_task
from utils.api import APIView, validate_serializer
from utils.shortcuts import build_query_string
from utils.throttling import TokenBucket, BucketController
from ..models import Submission
from ..serializers import CreateSubmissionSerializer
class SubmissionAPI(APIView):
@validate_serializer(CreateSubmissionSerializer)
# TODO: login
# @login_required
def post(self, request):
controller = BucketController(user_id=request.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 self.error("Please wait %d seconds" % int(bucket.expected_time() + 1))
data = request.data
try:
problem = Problem.objects.get(id=data["problem_id"])
except Problem.DoesNotExist:
return self.error("Problem not exist")
# TODO: user_id
submission = Submission.objects.create(user_id=1,
language=data["language"],
code=data["code"],
problem_id=problem.id)
judge_task.delay(submission.id, problem.id)
# JudgeDispatcher(submission.id, problem.id).judge()
return self.success({"submission_id": submission.id})
@login_required
def get(self, request):
submission_id = request.GET.get("submission_id")
if not submission_id:
return self.error("Parameter error")
try:
submission = Submission.objects.get(id=submission_id, user_id=request.user.id)
except Submission.DoesNotExist:
return self.error("Submission not exist")
response_data = {"result": submission.result}
if submission.result == 0:
response_data["accepted_answer_time"] = submission.accepted_answer_time
return self.success(response_data)
class MyProblemSubmissionListAPI(APIView):
"""
用户单个题目的全部提交列表
"""
def get(self, request):
problem_id = request.GET.get("problem_id")
try:
problem = Problem.objects.get(id=problem_id, visible=True)
except Problem.DoesNotExist:
return self.error("Problem not exist")
submissions = Submission.objects.filter(user_id=request.user.id, problem_id=problem.id,
contest_id__isnull=True). \
order_by("-created_time"). \
values("id", "result", "created_time", "accepted_time", "language")
return self.success({"submissions": submissions, "problem": problem})
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
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, "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})