From bc6d80d7458d2c053e8be7fa117b7e4768a504b5 Mon Sep 17 00:00:00 2001 From: Chiaki Date: Mon, 15 May 2017 13:09:54 +0800 Subject: [PATCH] Daily commit --- submission/urls/oj.py | 6 +- submission/views/oj.py | 138 +++++++++++++++++++++++++++++------------ utils/shortcuts.py | 2 +- 3 files changed, 103 insertions(+), 43 deletions(-) diff --git a/submission/urls/oj.py b/submission/urls/oj.py index 9f54c055..947aadf0 100644 --- a/submission/urls/oj.py +++ b/submission/urls/oj.py @@ -1,9 +1,11 @@ from django.conf.urls import url -from ..views.oj import (SubmissionAPI, SubmissionListAPI) +from ..views.oj import (SubmissionAPI, SubmissionListAPI, SubmissionDetailAPI) urlpatterns = [ - url(r"^submission/?$", SubmissionAPI.as_view(), name="submissiob_api"), + url(r"^submission/?$", SubmissionAPI.as_view(), name="submission_api"), + url(r"^submission/(?P\w+)/?$", SubmissionDetailAPI.as_view(), name="submission_detail_api"), url(r"^submissions/?$", SubmissionListAPI.as_view(), name="submission_list_api"), url(r"^submissions/(?P\d+)/?$", SubmissionListAPI.as_view(), name="submission_list_page_api"), + # MyProblemSubmissionListAPI ] diff --git a/submission/views/oj.py b/submission/views/oj.py index 553e3edd..1d4d937b 100644 --- a/submission/views/oj.py +++ b/submission/views/oj.py @@ -8,39 +8,45 @@ 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 ..models import Submission, JudgeStatus from ..serializers import CreateSubmissionSerializer +def _submit(response, user, problem_id, language, code): + # 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, + problem_id=problem.id) + + judge_task.delay(submission.id, problem.id) + return response.success({"submission_id": submission.id}) + + 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}) + return _submit(self, request.user, data["problem_id"], data["language"], data["code"]) @login_required def get(self, request): @@ -62,6 +68,7 @@ class MyProblemSubmissionListAPI(APIView): """ 用户单个题目的全部提交列表 """ + def get(self, request): problem_id = request.GET.get("problem_id") try: @@ -81,6 +88,7 @@ class SubmissionListAPI(APIView): """ 所有提交的列表 """ + def get(self, request, **kwargs): submission_filter = {"my": None, "user_id": None} show_all = False @@ -102,7 +110,6 @@ class SubmissionListAPI(APIView): 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) @@ -140,19 +147,70 @@ class SubmissionListAPI(APIView): 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 + 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}) + 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) + pass + 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"]) + + user = User.objects.get(id=submission.user_id) + return self.success({"submission": submission, "problem": problem, "info": info, + "user": user, "can_share": result["can_share"]}) diff --git a/utils/shortcuts.py b/utils/shortcuts.py index a7fcd116..38a4edb3 100644 --- a/utils/shortcuts.py +++ b/utils/shortcuts.py @@ -49,7 +49,7 @@ def rand_str(length=32, type="lower_hex"): def build_query_string(kv_data, ignore_none=True): # {"a": 1, "b": "test"} -> "?a=1&b=test" query_string = "" - for k, v in kv_data.iteritems(): + for k, v in kv_data.items(): if ignore_none is True and kv_data[k] is None: continue if query_string != "":