From b4f45a619f15332343d188c668192966da642d09 Mon Sep 17 00:00:00 2001 From: virusdefender <1670873886@qq.com> Date: Mon, 17 Aug 2015 16:31:42 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=BA=93=E8=B7=AF=E7=94=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- oj/db_router.py | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/oj/db_router.py b/oj/db_router.py index bd174cd..d8c1659 100644 --- a/oj/db_router.py +++ b/oj/db_router.py @@ -18,13 +18,6 @@ class DBRouter(object): def allow_migrate(self, db, app_label, model=None, **hints): if app_label == "submission": if db == "submission": - r = True - else: - r = False + return db == app_label else: - if db == "default": - r = True - else: - r = False - print db, app_label, r - return r \ No newline at end of file + return db == "default" \ No newline at end of file From 3385ddce188edb419eb63297ca4fc17f16fc2e97 Mon Sep 17 00:00:00 2001 From: virusdefender <1670873886@qq.com> Date: Mon, 17 Aug 2015 16:32:12 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=88=9B=E5=BB=BA?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E9=97=AE=E9=A2=98=E7=9A=84=E6=97=B6=E5=80=99?= =?UTF-8?q?=E6=8F=90=E7=A4=BA=E4=B8=8D=E8=83=BD=E4=B8=BA=E7=A9=BA=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- oj/urls.py | 4 +++- problem/serizalizers.py | 4 ++-- problem/views.py | 6 +++--- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/oj/urls.py b/oj/urls.py index 909d6bb..ba7c997 100644 --- a/oj/urls.py +++ b/oj/urls.py @@ -14,7 +14,8 @@ from group.views import (GroupAdminAPIView, GroupMemberAdminAPIView, from admin.views import AdminTemplateView from problem.views import TestCaseUploadAPIView, ProblemTagAdminAPIView, ProblemAdminAPIView -from submission.views import SubmissionAPIView +from submission.views import SubmissionAPIView, SubmissionAdminAPIView + urlpatterns = [ url(r'^install/$', "install.views.install"), @@ -57,5 +58,6 @@ urlpatterns = [ url(r'^api/admin/join_group_request/$', JoinGroupRequestAdminAPIView.as_view(), name="join_group_request_admin_api"), url(r'^api/submission/$', SubmissionAPIView.as_view(), name="submission_api"), + url(r'^api/admin/submission/$', SubmissionAdminAPIView.as_view(), name="submission_admin_api_view"), ] diff --git a/problem/serizalizers.py b/problem/serizalizers.py index d53b2bb..1fb61cc 100644 --- a/problem/serizalizers.py +++ b/problem/serizalizers.py @@ -30,7 +30,7 @@ class CreateProblemSerializer(serializers.Serializer): memory_limit = serializers.IntegerField() difficulty = serializers.IntegerField() tags = serializers.ListField(child=serializers.CharField(max_length=10)) - hint = serializers.CharField(max_length=3000, required=False, default=None) + hint = serializers.CharField(max_length=3000, allow_blank=True) class ProblemTagSerializer(serializers.ModelSerializer): @@ -66,7 +66,7 @@ class EditProblemSerializer(serializers.Serializer): difficulty = serializers.IntegerField() tags = serializers.ListField(child=serializers.CharField(max_length=20)) samples = ProblemSampleSerializer() - hint = serializers.CharField(max_length=10000) + hint = serializers.CharField(max_length=3000, allow_blank=True) visible = serializers.BooleanField() diff --git a/problem/views.py b/problem/views.py index 1d1702d..4a6e2c6 100644 --- a/problem/views.py +++ b/problem/views.py @@ -22,7 +22,7 @@ from .models import Problem, ProblemTag def problem_page(request, problem_id): try: - problem = Problem.objects.get(id=problem_id) + problem = Problem.objects.get(id=problem_id, visible=True) except Problem.DoesNotExist: return error_page(request, u"题目不存在") return render(request, "oj/problem/problem.html", {"problem": problem, "samples": json.loads(problem.samples)}) @@ -122,7 +122,7 @@ class ProblemAdminAPIView(APIView): return success_response(ProblemSerializer(problem).data) except Problem.DoesNotExist: return error_response(u"题目不存在") - problem = Problem.objects.all().order_by("-last_update_time") + problem = Problem.objects.all().order_by("-create_time") visible = request.GET.get("visible", None) if visible: problem = problem.filter(visible=(visible == "true")) @@ -217,7 +217,7 @@ class TestCaseUploadAPIView(APIView): def problem_list_page(request, page=1): # 正常情况 - problems = Problem.objects.all() + problems = Problem.objects.filter(visible=True) # 搜索的情况 keyword = request.GET.get("keyword", None) From ce5b0804b9a74d76e8df9a188668bf28159a9cff Mon Sep 17 00:00:00 2001 From: virusdefender <1670873886@qq.com> Date: Mon, 17 Aug 2015 16:33:05 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E5=90=8E=E5=8F=B0=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E8=B7=B3=E8=BD=AC=E6=97=B6=E4=BF=9D=E5=AD=98=E4=B8=8A=E4=B8=80?= =?UTF-8?q?=E9=A1=B5=E7=8A=B6=E6=80=81=EF=BC=8C=E5=90=8C=E6=97=B6=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E8=BF=94=E5=9B=9E=E6=8C=89=E9=92=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- static/src/js/app/admin/admin.js | 13 ++++ static/src/js/app/admin/group/group.js | 2 +- static/src/js/app/admin/group/groupDetail.js | 5 +- .../src/js/app/admin/problem/edit_problem.js | 3 + static/src/js/app/admin/problem/problem.js | 77 +++++++++++-------- .../js/app/admin/problem/submission_list.js | 76 ++++++++++++++++++ 6 files changed, 140 insertions(+), 36 deletions(-) create mode 100644 static/src/js/app/admin/problem/submission_list.js diff --git a/static/src/js/app/admin/admin.js b/static/src/js/app/admin/admin.js index 80ba2d9..c1ab398 100644 --- a/static/src/js/app/admin/admin.js +++ b/static/src/js/app/admin/admin.js @@ -41,6 +41,19 @@ define("admin", ["jquery", "avalon"], function ($, avalon) { vm.template_url = "template/problem/edit_problem.html"; }); + vm.$watch("showProblemListPage", function(){ + vm.template_url = "template/problem/problem_list.html"; + }); + + vm.$watch("showGroupListPage", function(){ + vm.template_url = "template/group/group.html"; + }); + + vm.$watch("showProblemSubmissionPage", function(problemId){ + vm.problemId = problemId; + vm.template_url = "template/problem/submission_list.html"; + }); + avalon.scan(); li_active("#li-" + hash.replace("/", "-")); diff --git a/static/src/js/app/admin/group/group.js b/static/src/js/app/admin/group/group.js index 4ff6ba4..b4b3117 100644 --- a/static/src/js/app/admin/group/group.js +++ b/static/src/js/app/admin/group/group.js @@ -45,7 +45,7 @@ require(["jquery", "avalon", "csrfToken", "bsAlert", "formValidation"], function getPageData(1); function getPageData(page) { - var url = "/api/admin/group/?paging=true&page=" + page + "&page_size=10"; + var url = "/api/admin/group/?paging=true&page=" + page + "&page_size=2"; if (vm.keyword) url += "&keyword=" + vm.keyword; $.ajax({ diff --git a/static/src/js/app/admin/group/groupDetail.js b/static/src/js/app/admin/group/groupDetail.js index 8dd0202..e622a16 100644 --- a/static/src/js/app/admin/group/groupDetail.js +++ b/static/src/js/app/admin/group/groupDetail.js @@ -3,7 +3,7 @@ require(["jquery", "avalon", "csrfToken", "bsAlert", "formValidation"], function // avalon:定义模式 group_list avalon.ready(function () { - avalon.vmodels.groupDetail = null; + avalon.vmodels.groupDetail = null; var vm = avalon.define({ $id: "groupDetail", //通用变量 @@ -47,6 +47,9 @@ require(["jquery", "avalon", "csrfToken", "bsAlert", "formValidation"], function bsAlert(data.data); } }) + }, + showGroupListPage: function () { + vm.$fire("up!showGroupListPage"); } }); diff --git a/static/src/js/app/admin/problem/edit_problem.js b/static/src/js/app/admin/problem/edit_problem.js index 75ebbae..25462d1 100644 --- a/static/src/js/app/admin/problem/edit_problem.js +++ b/static/src/js/app/admin/problem/edit_problem.js @@ -167,6 +167,9 @@ require(["jquery", "avalon", "editor", "uploader", "bsAlert", "csrfToken", "tagE if (item.visible) return "折叠"; return "展开"; + }, + showProblemListPage: function(){ + vm.$fire("up!showProblemListPage"); } }); var hintEditor = editor("#hint"); diff --git a/static/src/js/app/admin/problem/problem.js b/static/src/js/app/admin/problem/problem.js index 4f87b3d..d7e0739 100644 --- a/static/src/js/app/admin/problem/problem.js +++ b/static/src/js/app/admin/problem/problem.js @@ -1,40 +1,49 @@ require(["jquery", "avalon", "csrfToken", "bsAlert", "formValidation"], function ($, avalon, csrfTokenHeader, bsAlert) { avalon.ready(function () { - avalon.vmodels.problemList = null; - var vm = avalon.define({ - $id: "problemList", - problemList: [], - previousPage: 0, - nextPage: 0, - page: 1, - totalPage: 1, - keyword: "", - getNext: function () { - if (!vm.nextPage) - return; - getPageData(vm.page + 1); - }, - getPrevious: function () { - if (!vm.previousPage) - return; - getPageData(vm.page - 1); - }, - getBtnClass: function (btn) { - if (btn == "next") { - return vm.nextPage ? "btn btn-primary" : "btn btn-primary disabled"; + if(avalon.vmodels.problemList){ + vm = avalon.vmodels.problemList; + } + else { + var vm = avalon.define({ + $id: "problemList", + problemList: [], + previousPage: 0, + nextPage: 0, + page: 1, + totalPage: 1, + keyword: "", + getNext: function () { + if (!vm.nextPage) + return; + getPageData(vm.page + 1); + }, + getPrevious: function () { + if (!vm.previousPage) + return; + getPageData(vm.page - 1); + }, + getBtnClass: function (btn) { + if (btn == "next") { + return vm.nextPage ? "btn btn-primary" : "btn btn-primary disabled"; + } + else { + return vm.previousPage ? "btn btn-primary" : "btn btn-primary disabled"; + } + }, + getPage: function (page_index) { + getPageData(page_index); + }, + showEditProblemPage: function (problemId) { + vm.$fire("up!showEditProblemPage", problemId); + }, + showProblemSubmissionPage: function(problemId){ + vm.$fire("up!showProblemSubmissionPage", problemId); } - else { - return vm.previousPage ? "btn btn-primary" : "btn btn-primary disabled"; - } - }, - getPage: function (page_index) { - getPageData(page_index); - }, - showEditProblemPage: function (problem_id) { - vm.$fire("up!showEditProblemPage", problem_id); - } - }); + }); + + getPageData(1); + } function getPageData(page) { var url = "/api/admin/problem/?paging=true&page=" + page + "&page_size=10"; @@ -59,7 +68,7 @@ require(["jquery", "avalon", "csrfToken", "bsAlert", "formValidation"], function }); } - getPageData(1); + }); avalon.scan(); }); \ No newline at end of file diff --git a/static/src/js/app/admin/problem/submission_list.js b/static/src/js/app/admin/problem/submission_list.js new file mode 100644 index 0000000..21c451b --- /dev/null +++ b/static/src/js/app/admin/problem/submission_list.js @@ -0,0 +1,76 @@ +require(["jquery", "avalon", "csrfToken", "bsAlert", "formValidation"], function ($, avalon, csrfTokenHeader, bsAlert) { + + avalon.ready(function () { + avalon.vmodels.submissionList = null; + var vm = avalon.define({ + $id: "submissionList", + submissionList: [], + previousPage: 0, + nextPage: 0, + page: 1, + totalPage: 1, + results : { + 0: "Accepted", + 1: "Runtime Error", + 2: "Time Limit Exceeded", + 3: "Memory Limit Exceeded", + 4: "Compile Error", + 5: "Format Error", + 6: "Wrong Answer", + 7: "System Error", + 8: "Waiting" + }, + getNext: function () { + if (!vm.nextPage) + return; + getPageData(vm.page + 1); + }, + getPrevious: function () { + if (!vm.previousPage) + return; + getPageData(vm.page - 1); + }, + getBtnClass: function (btn) { + if (btn == "next") { + return vm.nextPage ? "btn btn-primary" : "btn btn-primary disabled"; + } + else { + return vm.previousPage ? "btn btn-primary" : "btn btn-primary disabled"; + } + }, + getPage: function (page_index) { + getPageData(page_index); + }, + + showSubmissionDetailPage: function (submissionId) { + + } + }); + + getPageData(1); + + function getPageData(page) { + var url = "/api/admin/submission/?paging=true&page=" + page + "&page_size=10&problem_id=" + avalon.vmodels.admin.problemId; + $.ajax({ + url: url, + dataType: "json", + method: "get", + success: function (data) { + if (!data.code) { + vm.submissionList = data.data.results; + vm.totalPage = data.data.total_page; + vm.previousPage = data.data.previous_page; + vm.nextPage = data.data.next_page; + vm.page = page; + } + else { + bsAlert(data.data); + } + } + }); + } + + + }); + avalon.scan(); +}); \ No newline at end of file From ba958eddc20e48bd1990c52396243fd5236e6e13 Mon Sep 17 00:00:00 2001 From: virusdefender <1670873886@qq.com> Date: Mon, 17 Aug 2015 16:33:26 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=89=8D=E5=8F=B0?= =?UTF-8?q?=E6=8F=90=E4=BA=A4=E9=A1=B5=E9=9D=A2=E7=9A=84=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- submission/serializers.py | 12 ++++++++ submission/views.py | 31 ++++++++++++++++++--- template/admin/group/group_detail.html | 6 ++++ template/admin/problem/edit_problem.html | 6 ++++ template/admin/problem/problem_list.html | 1 + template/admin/problem/submission_list.html | 28 +++++++++++++++++++ template/oj/problem/my_submission.html | 11 ++++++++ 7 files changed, 91 insertions(+), 4 deletions(-) create mode 100644 template/admin/problem/submission_list.html diff --git a/submission/serializers.py b/submission/serializers.py index c64ada6..e9f1052 100644 --- a/submission/serializers.py +++ b/submission/serializers.py @@ -1,6 +1,8 @@ # coding=utf-8 from rest_framework import serializers +from account.models import User +from .models import Submission class CreateSubmissionSerializer(serializers.Serializer): @@ -8,3 +10,13 @@ class CreateSubmissionSerializer(serializers.Serializer): language = serializers.IntegerField() code = serializers.CharField(max_length=3000) + +class SubmissionSerializer(serializers.ModelSerializer): + user = serializers.SerializerMethodField("_get_submission_user") + + class Meta: + model = Submission + fields = ["id", "result", "create_time", "language", "user"] + + def _get_submission_user(self, obj): + return User.objects.get(id=obj.user_id).username \ No newline at end of file diff --git a/submission/views.py b/submission/views.py index 2ebc843..10c7786 100644 --- a/submission/views.py +++ b/submission/views.py @@ -8,10 +8,11 @@ from rest_framework.views import APIView from judge.judger.result import result from judge.judger_controller.tasks import judge from account.decorators import login_required +from account.models import SUPER_ADMIN from problem.models import Problem -from utils.shortcuts import serializer_invalid_response, error_response, success_response, error_page +from utils.shortcuts import serializer_invalid_response, error_response, success_response, error_page, paginate from .models import Submission -from .serializers import CreateSubmissionSerializer +from .serializers import CreateSubmissionSerializer, SubmissionSerializer class SubmissionAPIView(APIView): @@ -70,12 +71,34 @@ def problem_my_submissions_list_page(request, problem_id): @login_required def my_submission(request, submission_id): try: - submission = Submission.objects.get(id=submission_id) + # 超级管理员可以查看所有的提交 + if request.user.admin_type != SUPER_ADMIN: + submission = Submission.objects.get(id=submission_id, user_id=request.user.id) + else: + submission = Submission.objects.get(id=submission_id) except Submission.DoesNotExist: return error_page(request, u"提交不存在") + try: problem = Problem.objects.get(id=submission.problem_id, visible=True) except Problem.DoesNotExist: return error_page(request, u"提交不存在") + if submission.info: + try: + info = json.loads(submission.info) + except Exception: + info = submission.info + else: + info = None return render(request, "oj/problem/my_submission.html", - {"submission": submission, "problem": problem}) \ No newline at end of file + {"submission": submission, "problem": problem, "info": info}) + + + +class SubmissionAdminAPIView(APIView): + def get(self, request): + problem_id = request.GET.get("problem_id", None) + if not problem_id: + return error_response(u"参数错误") + submissions = Submission.objects.filter(problem_id=problem_id).order_by("-create_time") + return paginate(request, submissions, SubmissionSerializer) \ No newline at end of file diff --git a/template/admin/group/group_detail.html b/template/admin/group/group_detail.html index 79cb144..f99efad 100644 --- a/template/admin/group/group_detail.html +++ b/template/admin/group/group_detail.html @@ -1,4 +1,10 @@
| ID | +创建时间 | +作者 | +结果 | ++ |
|---|---|---|---|---|
| {{ el.id }} | +{{ el.create_time|date("yyyy-MM-dd HH:mm:ss")}} | +{{ el.user }} | +{{ results[el.result] }} | ++ 详情 + | +
提交时间 : {{ submission.create_time }}
本调试信息仅超级管理员可见
+ {% ifequal submission.result 7 %} +System Error: {{ submission.info }}
+ {% else %}
+ {{ info }}
+ {% endifequal %}
+
+ {% endifequal %}
+
+