From f417b8d708606f90fcc1bb9b32d3ef499c526080 Mon Sep 17 00:00:00 2001 From: virusdefender <1670873886@qq.com> Date: Thu, 24 Sep 2015 21:35:41 +0800 Subject: [PATCH 01/13] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=B8=8D=E8=83=BD?= =?UTF-8?q?=E6=98=BE=E7=A4=BA=E7=9C=9F=E5=AE=9E=E5=A7=93=E5=90=8D=E7=9A=84?= =?UTF-8?q?=20bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- template/src/oj/contest/contest_rank.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/template/src/oj/contest/contest_rank.html b/template/src/oj/contest/contest_rank.html index 4b7f9398..dca8cfea 100644 --- a/template/src/oj/contest/contest_rank.html +++ b/template/src/oj/contest/contest_rank.html @@ -52,7 +52,7 @@ {{ item.user.username }} {% if show_real_name %} - ({{ item.real_name }}) + ({{ item.user.real_name }}) {% endif %} {{ item.total_ac_number }} / {{ item.total_submission_number }} From 08373ebb023f659958c28f4fe0f798c38e0fa473 Mon Sep 17 00:00:00 2001 From: virusdefender <1670873886@qq.com> Date: Fri, 25 Sep 2015 13:10:09 +0800 Subject: [PATCH 02/13] update security --- judge/judger_controller/tasks.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/judge/judger_controller/tasks.py b/judge/judger_controller/tasks.py index 2de71d75..3afc2c1d 100644 --- a/judge/judger_controller/tasks.py +++ b/judge/judger_controller/tasks.py @@ -13,9 +13,10 @@ def judge(submission_id, time_limit, memory_limit, test_case_id): try: command = "%s run --privileged --rm " \ "--link mysql " \ - "-v %s:/var/judger/test_case/ " \ + "-v %s:/var/judger/test_case/:ro " \ "-v %s:/var/judger/code/ " \ "-v %s:/var/judger/code/log/ " \ + "--device /dev/null:/dev/null " \ "%s " \ "python judge/judger/run.py " \ "--solution_id %s --time_limit %s --memory_limit %s --test_case_id %s" % \ From f7a8b80b0c3bbf08ed172f3db280dd43ba966492 Mon Sep 17 00:00:00 2001 From: virusdefender <1670873886@qq.com> Date: Fri, 25 Sep 2015 15:03:09 +0800 Subject: [PATCH 03/13] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20ajax=20=E6=8F=90?= =?UTF-8?q?=E4=BA=A4=20json=20=E4=B8=AD=E6=96=87=E4=B9=B1=E7=A0=81?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- static/src/js/app/admin/announcement/announcement.js | 4 ++-- static/src/js/app/admin/contest/addContest.js | 2 +- static/src/js/app/admin/contest/contestList.js | 5 ++--- static/src/js/app/admin/contest/editProblem.js | 2 +- static/src/js/app/admin/group/groupDetail.js | 2 +- static/src/js/app/admin/problem/addProblem.js | 2 +- static/src/js/app/admin/problem/editProblem.js | 2 +- static/src/js/app/oj/group/group.js | 4 ++-- static/src/js/app/oj/problem/problem.js | 2 +- 9 files changed, 12 insertions(+), 13 deletions(-) diff --git a/static/src/js/app/admin/announcement/announcement.js b/static/src/js/app/admin/announcement/announcement.js index 4c67ef2e..df737692 100644 --- a/static/src/js/app/admin/announcement/announcement.js +++ b/static/src/js/app/admin/announcement/announcement.js @@ -91,7 +91,7 @@ require(["jquery", "avalon", "csrfToken", "bsAlert", "editor", "validator"], $.ajax({ beforeSend: csrfTokenHeader, url: "/api/admin/announcement/", - contentType: "application/json", + contentType: "application/json;charset=UTF-8", dataType: "json", method: "put", data: JSON.stringify({ @@ -209,7 +209,7 @@ require(["jquery", "avalon", "csrfToken", "bsAlert", "editor", "validator"], $.ajax({ beforeSend: csrfTokenHeader, url: "/api/admin/announcement/", - contentType: "application/json", + contentType: "application/json;charset=UTF-8", data: JSON.stringify({ title: title, content: content, diff --git a/static/src/js/app/admin/contest/addContest.js b/static/src/js/app/admin/contest/addContest.js index 8aa5354f..e2059b86 100644 --- a/static/src/js/app/admin/contest/addContest.js +++ b/static/src/js/app/admin/contest/addContest.js @@ -46,7 +46,7 @@ require(["jquery", "avalon", "editor", "uploader", "bsAlert", "csrfToken", "date beforeSend: csrfTokenHeader, url: "/api/admin/contest/", dataType: "json", - contentType: "application/json", + contentType: "application/json;charset=UTF-8", data: JSON.stringify(ajaxData), method: "post", success: function (data) { diff --git a/static/src/js/app/admin/contest/contestList.js b/static/src/js/app/admin/contest/contestList.js index cfaf664e..4951979c 100644 --- a/static/src/js/app/admin/contest/contestList.js +++ b/static/src/js/app/admin/contest/contestList.js @@ -48,10 +48,9 @@ require(["jquery", "avalon", "csrfToken", "bsAlert", "editor", "datetimePicker", beforeSend: csrfTokenHeader, url: "/api/admin/contest/", dataType: "json", - contentType: "application/json", + contentType: "application/json;charset=UTF-8", data: JSON.stringify(ajaxData), method: "put", - contentType: "application/json", success: function (data) { if (!data.code) { bsAlert("修改成功!"); @@ -237,7 +236,7 @@ require(["jquery", "avalon", "csrfToken", "bsAlert", "editor", "datetimePicker", dataType: "json", data: JSON.stringify(ajaxData), method: "post", - contentType: "application/json", + contentType: "application/json;charset=UTF-8", success: function (data) { if (!data.code) { bsAlert("题目添加成功!题目现在处于隐藏状态,请到题目列表手动修改,并添加分类和难度信息!"); diff --git a/static/src/js/app/admin/contest/editProblem.js b/static/src/js/app/admin/contest/editProblem.js index 51a668d1..81c69316 100644 --- a/static/src/js/app/admin/contest/editProblem.js +++ b/static/src/js/app/admin/contest/editProblem.js @@ -66,7 +66,7 @@ require(["jquery", "avalon", "editor", "uploader", "bsAlert", "csrfToken", "tagE dataType: "json", data: JSON.stringify(ajaxData), method: method, - contentType: "application/json", + contentType: "application/json;charset=UTF-8", success: function (data) { if (!data.code) { bsAlert("题目编辑成功!"); diff --git a/static/src/js/app/admin/group/groupDetail.js b/static/src/js/app/admin/group/groupDetail.js index c06f9ce0..de4a0ff5 100644 --- a/static/src/js/app/admin/group/groupDetail.js +++ b/static/src/js/app/admin/group/groupDetail.js @@ -45,7 +45,7 @@ require(["jquery", "avalon", "csrfToken", "bsAlert", "validator"], function ($, url: "/api/admin/group_member/", method: "put", data: JSON.stringify({group_id: relation.group, members: [relation.user.id]}), - contentType: "application/json", + contentType: "application/json;charset=UTF-8", success: function (data) { vm.memberList.remove(relation); bsAlert(data.data); diff --git a/static/src/js/app/admin/problem/addProblem.js b/static/src/js/app/admin/problem/addProblem.js index 103396b7..e67e9a71 100644 --- a/static/src/js/app/admin/problem/addProblem.js +++ b/static/src/js/app/admin/problem/addProblem.js @@ -59,7 +59,7 @@ require(["jquery", "avalon", "editor", "uploader", "bsAlert", "csrfToken", "tagE dataType: "json", data: JSON.stringify(ajaxData), method: "post", - contentType: "application/json", + contentType: "application/json;charset=UTF-8", success: function (data) { if (!data.code) { bsAlert("题目添加成功!"); diff --git a/static/src/js/app/admin/problem/editProblem.js b/static/src/js/app/admin/problem/editProblem.js index e3f235c4..90361788 100644 --- a/static/src/js/app/admin/problem/editProblem.js +++ b/static/src/js/app/admin/problem/editProblem.js @@ -60,7 +60,7 @@ require(["jquery", "avalon", "editor", "uploader", "bsAlert", "csrfToken", "tagE dataType: "json", data: JSON.stringify(ajaxData), method: "put", - contentType: "application/json", + contentType: "application/json;charset=UTF-8", success: function (data) { if (!data.code) { bsAlert("题目编辑成功!"); diff --git a/static/src/js/app/oj/group/group.js b/static/src/js/app/oj/group/group.js index c36448ec..d9371427 100644 --- a/static/src/js/app/oj/group/group.js +++ b/static/src/js/app/oj/group/group.js @@ -9,14 +9,14 @@ require(["jquery", "csrfToken", "bsAlert"], function ($, csrfTokenHeader, bsAler } var groupId = window.location.pathname.split("/")[2]; - data = {group_id: groupId,message:message} + var data = {group_id: groupId,message:message}; $.ajax({ url: "/api/group_join/", method: "post", dataType: "json", beforeSend: csrfTokenHeader, data: JSON.stringify(data), - contentType: "application/json", + contentType: "application/json;charset=UTF-8", success: function (data) { if (data.code) { bsAlert(data.data); diff --git a/static/src/js/app/oj/problem/problem.js b/static/src/js/app/oj/problem/problem.js index 8f76fbec..4b5e639b 100644 --- a/static/src/js/app/oj/problem/problem.js +++ b/static/src/js/app/oj/problem/problem.js @@ -222,7 +222,7 @@ require(["jquery", "codeMirror", "csrfToken", "bsAlert", "ZeroClipboard"], url: url, method: "post", data: JSON.stringify(data), - contentType: "application/json", + contentType: "application/json;charset=UTF-8", success: function (data) { if (!data.code) { submissionId = data.data.submission_id; From e3d3fa7eb48ef30ae561a2ab923e82b79e14af49 Mon Sep 17 00:00:00 2001 From: virusdefender <1670873886@qq.com> Date: Fri, 25 Sep 2015 15:04:57 +0800 Subject: [PATCH 04/13] =?UTF-8?q?=E4=BD=BF=E7=94=A8=E5=85=B3=E8=81=94?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2=E6=8F=90=E4=BE=9B=E6=80=A7=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- contest/views.py | 6 +++--- template/src/oj/contest/contest_rank.html | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/contest/views.py b/contest/views.py index ade14079..f7b080b6 100644 --- a/contest/views.py +++ b/contest/views.py @@ -334,7 +334,7 @@ def contest_problems_list_page(request, contest_id): 比赛所有题目的列表页 """ contest = Contest.objects.get(id=contest_id) - contest_problems = ContestProblem.objects.filter(contest=contest).order_by("sort_index") + contest_problems = ContestProblem.objects.filter(contest=contest).select_related("contest").order_by("sort_index") return render(request, "oj/contest/contest_problems_list.html", {"contest_problems": contest_problems, "contest": {"id": contest_id}}) @@ -383,8 +383,8 @@ def contest_list_page(request, page=1): @check_user_contest_permission def contest_rank_page(request, contest_id): contest = Contest.objects.get(id=contest_id) - contest_problems = ContestProblem.objects.filter(contest=contest).order_by("sort_index") - rank = ContestRank.objects.filter(contest_id=contest_id).order_by("-total_ac_number", "total_time") + contest_problems = ContestProblem.objects.filter(contest=contest).order_by("sort_index")[:20] + rank = ContestRank.objects.filter(contest_id=contest_id).select_related("user").order_by("-total_ac_number", "total_time") return render(request, "oj/contest/contest_rank.html", {"rank": rank, "contest": contest, "contest_problems": contest_problems, diff --git a/template/src/oj/contest/contest_rank.html b/template/src/oj/contest/contest_rank.html index dca8cfea..eb86cc79 100644 --- a/template/src/oj/contest/contest_rank.html +++ b/template/src/oj/contest/contest_rank.html @@ -39,8 +39,8 @@ AC / 总提交 用时 + 罚时 {% for item in contest_problems %} - {{ item.sort_index }} + + {{ item.sort_index }} {% endfor %} From 4ab1107627a3f8e55edba581c81041ce9a0c8fb0 Mon Sep 17 00:00:00 2001 From: virusdefender <1670873886@qq.com> Date: Fri, 25 Sep 2015 15:05:17 +0800 Subject: [PATCH 05/13] =?UTF-8?q?=E5=A2=9E=E5=BC=BA=E5=88=A4=E9=A2=98?= =?UTF-8?q?=E5=92=8C=20docker=20=E5=AE=89=E5=85=A8=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- judge/judger/client.py | 2 ++ judge/judger_controller/tasks.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/judge/judger/client.py b/judge/judger/client.py index 53164e5b..7c217aad 100644 --- a/judge/judger/client.py +++ b/judge/judger/client.py @@ -62,6 +62,8 @@ class JudgeClient(object): " --max-real-time " + str(self._max_real_time / 1000.0 * 2) + \ " --max-memory " + str(self._max_memory * 1000 * 1000) + \ " --network false" + \ + " --remount-dev true " + \ + " --reset-env true " + \ " --syscalls '" + self._language["syscalls"] + "'" + \ " --max-nprocess 20" + \ " --uid " + str(lrun_uid) + \ diff --git a/judge/judger_controller/tasks.py b/judge/judger_controller/tasks.py index 3afc2c1d..2219d96e 100644 --- a/judge/judger_controller/tasks.py +++ b/judge/judger_controller/tasks.py @@ -14,7 +14,7 @@ def judge(submission_id, time_limit, memory_limit, test_case_id): command = "%s run --privileged --rm " \ "--link mysql " \ "-v %s:/var/judger/test_case/:ro " \ - "-v %s:/var/judger/code/ " \ + "-v %s:/var/judger/code/:ro " \ "-v %s:/var/judger/code/log/ " \ "--device /dev/null:/dev/null " \ "%s " \ From 634bc82024b67b1f678874879745f3cb838dea94 Mon Sep 17 00:00:00 2001 From: virusdefender <1670873886@qq.com> Date: Fri, 25 Sep 2015 19:35:48 +0800 Subject: [PATCH 06/13] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=AF=94=E8=B5=9B?= =?UTF-8?q?=E7=9A=84=E5=89=8D=E5=8F=B0=E6=98=BE=E7=A4=BA=E6=A0=B7=E5=BC=8F?= =?UTF-8?q?=EF=BC=9B=E5=88=A0=E9=99=A4=E5=85=AC=E5=91=8A=EF=BC=8C=E6=B2=A1?= =?UTF-8?q?=E6=9C=89=E6=8F=90=E4=BA=A4=E7=9A=84=E6=97=B6=E5=80=99=E4=B8=8D?= =?UTF-8?q?=E6=98=BE=E7=A4=BA=E8=A1=A8=E6=A0=BC=E7=9A=84=E8=A1=A8=E5=A4=B4?= =?UTF-8?q?=EF=BC=9B=E4=BF=AE=E6=94=B9=E9=83=A8=E5=88=86=20typo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- template/src/oj/contest/contest_problems_list.html | 6 ++---- template/src/oj/contest/contest_rank.html | 4 ++-- template/src/oj/contest/submissions_list.html | 7 ++++--- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/template/src/oj/contest/contest_problems_list.html b/template/src/oj/contest/contest_problems_list.html index bca4c089..c0cb58a1 100644 --- a/template/src/oj/contest/contest_problems_list.html +++ b/template/src/oj/contest/contest_problems_list.html @@ -29,7 +29,7 @@ -
+
@@ -60,9 +60,7 @@ -
- {% include "oj/announcement/_announcement_panel.html" %} -
+ {% endblock %} diff --git a/template/src/oj/contest/contest_rank.html b/template/src/oj/contest/contest_rank.html index eb86cc79..99eda73b 100644 --- a/template/src/oj/contest/contest_rank.html +++ b/template/src/oj/contest/contest_rank.html @@ -50,9 +50,9 @@ diff --git a/template/src/oj/contest/submissions_list.html b/template/src/oj/contest/submissions_list.html index bee1e91b..1bdfdebf 100644 --- a/template/src/oj/contest/submissions_list.html +++ b/template/src/oj/contest/submissions_list.html @@ -24,8 +24,10 @@
{{ forloop.counter }} - {{ item.user.username }} + {{ item.user__username }} {% if show_real_name %} - ({{ item.user.real_name }}) + ({{ item.user__real_name }}) {% endif %} {{ item.total_ac_number }} / {{ item.total_submission_number }}
- - + + {% if submissions %} + + @@ -65,7 +67,6 @@ - {% if submissions %} {% for item in submissions %} From 67de24a5b321e27b66bba99b634269eba2b50c84 Mon Sep 17 00:00:00 2001 From: virusdefender <1670873886@qq.com> Date: Sun, 27 Sep 2015 20:41:56 +0800 Subject: [PATCH 07/13] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=AF=94=E8=B5=9B?= =?UTF-8?q?=E7=BB=93=E6=9E=9C=E7=BC=93=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- contest/views.py | 17 +++++++++++++++-- utils/templatetags/contest.py | 13 +++++++------ 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/contest/views.py b/contest/views.py index f7b080b6..162b9b8a 100644 --- a/contest/views.py +++ b/contest/views.py @@ -1,6 +1,7 @@ # coding=utf-8 import json import datetime +import redis from django.shortcuts import render from django.db import IntegrityError @@ -8,6 +9,7 @@ from django.utils import dateparse from django.db.models import Q, Sum from django.core.paginator import Paginator from django.utils.timezone import now +from django.conf import settings from rest_framework.views import APIView @@ -383,8 +385,19 @@ def contest_list_page(request, page=1): @check_user_contest_permission def contest_rank_page(request, contest_id): contest = Contest.objects.get(id=contest_id) - contest_problems = ContestProblem.objects.filter(contest=contest).order_by("sort_index")[:20] - rank = ContestRank.objects.filter(contest_id=contest_id).select_related("user").order_by("-total_ac_number", "total_time") + contest_problems = ContestProblem.objects.filter(contest=contest).order_by("sort_index") + r = redis.Redis(host=settings.REDIS_CACHE["host"], port=settings.REDIS_CACHE["port"], db=settings.REDIS_CACHE["db"]) + cache_key = str(contest_id) + "_rank_cache" + rank = r.get(cache_key) + if not rank: + rank = ContestRank.objects.filter(contest_id=contest_id).\ + select_related("user").\ + order_by("-total_ac_number", "total_time").\ + values("id", "user__id", "user__username", "user__real_name", "contest_id", "submission_info", + "total_submission_number", "total_ac_number", "total_time") + r.set(cache_key, json.dumps([dict(item) for item in rank])) + else: + rank = json.loads(rank) return render(request, "oj/contest/contest_rank.html", {"rank": rank, "contest": contest, "contest_problems": contest_problems, diff --git a/utils/templatetags/contest.py b/utils/templatetags/contest.py index 2667922f..cc029089 100644 --- a/utils/templatetags/contest.py +++ b/utils/templatetags/contest.py @@ -1,6 +1,5 @@ # coding=utf-8 -import datetime -from django.utils.timezone import now +import json def get_contest_status(contest): @@ -34,10 +33,11 @@ def get_the_formatted_time(seconds): def get_submission_class(rank, problem): - if str(problem.id) not in rank.submission_info: + submission_info = json.loads(rank["submission_info"]) + if str(problem.id) not in submission_info: return "" else: - submission = rank.submission_info[str(problem.id)] + submission = submission_info[str(problem.id)] if submission["is_ac"]: _class = "alert-success" if submission["is_first_ac"]: @@ -48,10 +48,11 @@ def get_submission_class(rank, problem): def get_submission_content(rank, problem): - if str(problem.id) not in rank.submission_info: + submission_info = json.loads(rank["submission_info"]) + if str(problem.id) not in submission_info: return "" else: - submission = rank.submission_info[str(problem.id)] + submission = submission_info[str(problem.id)] if submission["is_ac"]: r = get_the_formatted_time(submission["ac_time"]) if submission["error_number"]: From 37517a135a8ab967444abd21e740a5127ca54df9 Mon Sep 17 00:00:00 2001 From: virusdefender <1670873886@qq.com> Date: Tue, 29 Sep 2015 18:59:21 +0800 Subject: [PATCH 08/13] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=AF=BC=E8=88=AA?= =?UTF-8?q?=E6=A0=8F=E5=9C=A8=E5=B0=8F=E5=B1=8F=E5=B9=95=E4=B8=8A=E6=8A=98?= =?UTF-8?q?=E5=8F=A0=E5=90=8E=E6=97=A0=E6=B3=95=E5=B1=95=E5=BC=80=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 --- static/src/js/config.js | 1 + static/src/js/lib/bootstrap/collapse.js | 214 ++++++++++++++++++++++++ 2 files changed, 215 insertions(+) create mode 100644 static/src/js/lib/bootstrap/collapse.js diff --git a/static/src/js/config.js b/static/src/js/config.js index e318d973..68e4225d 100644 --- a/static/src/js/config.js +++ b/static/src/js/config.js @@ -38,6 +38,7 @@ var require = { modal: "lib/bootstrap/modal", dropdown: "lib/bootstrap/dropdown", transition: "lib/bootstrap/transition", + collapse: "lib/bootstrap/collapse", //百度webuploader -> uploader webUploader: "lib/webuploader/webuploader", diff --git a/static/src/js/lib/bootstrap/collapse.js b/static/src/js/lib/bootstrap/collapse.js new file mode 100644 index 00000000..de0392e8 --- /dev/null +++ b/static/src/js/lib/bootstrap/collapse.js @@ -0,0 +1,214 @@ +define([ 'jquery', './transition' ], function ( jQuery ) { +/* ======================================================================== + * Bootstrap: collapse.js v3.3.5 + * http://getbootstrap.com/javascript/#collapse + * ======================================================================== + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // COLLAPSE PUBLIC CLASS DEFINITION + // ================================ + + var Collapse = function (element, options) { + this.$element = $(element) + this.options = $.extend({}, Collapse.DEFAULTS, options) + this.$trigger = $('[data-toggle="collapse"][href="#' + element.id + '"],' + + '[data-toggle="collapse"][data-target="#' + element.id + '"]') + this.transitioning = null + + if (this.options.parent) { + this.$parent = this.getParent() + } else { + this.addAriaAndCollapsedClass(this.$element, this.$trigger) + } + + if (this.options.toggle) this.toggle() + } + + Collapse.VERSION = '3.3.5' + + Collapse.TRANSITION_DURATION = 350 + + Collapse.DEFAULTS = { + toggle: true + } + + Collapse.prototype.dimension = function () { + var hasWidth = this.$element.hasClass('width') + return hasWidth ? 'width' : 'height' + } + + Collapse.prototype.show = function () { + if (this.transitioning || this.$element.hasClass('in')) return + + var activesData + var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing') + + if (actives && actives.length) { + activesData = actives.data('bs.collapse') + if (activesData && activesData.transitioning) return + } + + var startEvent = $.Event('show.bs.collapse') + this.$element.trigger(startEvent) + if (startEvent.isDefaultPrevented()) return + + if (actives && actives.length) { + Plugin.call(actives, 'hide') + activesData || actives.data('bs.collapse', null) + } + + var dimension = this.dimension() + + this.$element + .removeClass('collapse') + .addClass('collapsing')[dimension](0) + .attr('aria-expanded', true) + + this.$trigger + .removeClass('collapsed') + .attr('aria-expanded', true) + + this.transitioning = 1 + + var complete = function () { + this.$element + .removeClass('collapsing') + .addClass('collapse in')[dimension]('') + this.transitioning = 0 + this.$element + .trigger('shown.bs.collapse') + } + + if (!$.support.transition) return complete.call(this) + + var scrollSize = $.camelCase(['scroll', dimension].join('-')) + + this.$element + .one('bsTransitionEnd', $.proxy(complete, this)) + .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize]) + } + + Collapse.prototype.hide = function () { + if (this.transitioning || !this.$element.hasClass('in')) return + + var startEvent = $.Event('hide.bs.collapse') + this.$element.trigger(startEvent) + if (startEvent.isDefaultPrevented()) return + + var dimension = this.dimension() + + this.$element[dimension](this.$element[dimension]())[0].offsetHeight + + this.$element + .addClass('collapsing') + .removeClass('collapse in') + .attr('aria-expanded', false) + + this.$trigger + .addClass('collapsed') + .attr('aria-expanded', false) + + this.transitioning = 1 + + var complete = function () { + this.transitioning = 0 + this.$element + .removeClass('collapsing') + .addClass('collapse') + .trigger('hidden.bs.collapse') + } + + if (!$.support.transition) return complete.call(this) + + this.$element + [dimension](0) + .one('bsTransitionEnd', $.proxy(complete, this)) + .emulateTransitionEnd(Collapse.TRANSITION_DURATION) + } + + Collapse.prototype.toggle = function () { + this[this.$element.hasClass('in') ? 'hide' : 'show']() + } + + Collapse.prototype.getParent = function () { + return $(this.options.parent) + .find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]') + .each($.proxy(function (i, element) { + var $element = $(element) + this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element) + }, this)) + .end() + } + + Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) { + var isOpen = $element.hasClass('in') + + $element.attr('aria-expanded', isOpen) + $trigger + .toggleClass('collapsed', !isOpen) + .attr('aria-expanded', isOpen) + } + + function getTargetFromTrigger($trigger) { + var href + var target = $trigger.attr('data-target') + || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7 + + return $(target) + } + + + // COLLAPSE PLUGIN DEFINITION + // ========================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.collapse') + var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option) + + if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false + if (!data) $this.data('bs.collapse', (data = new Collapse(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.collapse + + $.fn.collapse = Plugin + $.fn.collapse.Constructor = Collapse + + + // COLLAPSE NO CONFLICT + // ==================== + + $.fn.collapse.noConflict = function () { + $.fn.collapse = old + return this + } + + + // COLLAPSE DATA-API + // ================= + + $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) { + var $this = $(this) + + if (!$this.attr('data-target')) e.preventDefault() + + var $target = getTargetFromTrigger($this) + var data = $target.data('bs.collapse') + var option = data ? 'toggle' : $this.data() + + Plugin.call($target, option) + }) + +}(jQuery); + +}); \ No newline at end of file From e517dbcbc2619a5a03d2938978dd22a68ba5dd10 Mon Sep 17 00:00:00 2001 From: virusdefender <1670873886@qq.com> Date: Tue, 29 Sep 2015 19:04:42 +0800 Subject: [PATCH 09/13] =?UTF-8?q?require.js=20=E5=8A=A0=E8=BD=BD=E7=9A=84?= =?UTF-8?q?=20js=20=E4=B9=9F=E5=8A=A0=E7=89=88=E6=9C=AC=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- static/src/js/config.js | 1 + 1 file changed, 1 insertion(+) diff --git a/static/src/js/config.js b/static/src/js/config.js index 68e4225d..eeae1341 100644 --- a/static/src/js/config.js +++ b/static/src/js/config.js @@ -1,4 +1,5 @@ var require = { + urlArgs: "v=2", // RequireJS 通过一个相对的路径 baseUrl来加载所有代码。baseUrl通常被设置成data-main属性指定脚本的同级目录。 baseUrl: "/static/js/", paths: { From 2f17424fac9d38a26866b8b889dacb25d69db4e7 Mon Sep 17 00:00:00 2001 From: virusdefender <1670873886@qq.com> Date: Tue, 29 Sep 2015 19:08:59 +0800 Subject: [PATCH 10/13] =?UTF-8?q?bootstrap=20=E6=9B=B4=E6=96=B0=E6=89=93?= =?UTF-8?q?=E5=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- static/src/js/build.js | 1 + static/src/js/lib/bootstrap/bootstrap.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/static/src/js/build.js b/static/src/js/build.js index 3acf938c..6baa25cd 100644 --- a/static/src/js/build.js +++ b/static/src/js/build.js @@ -37,6 +37,7 @@ modal: "lib/bootstrap/modal", dropdown: "lib/bootstrap/dropdown", transition: "lib/bootstrap/transition", + collapse: "lib/bootstrap/collapse", //百度webuploader -> uploader webUploader: "lib/webuploader/webuploader", diff --git a/static/src/js/lib/bootstrap/bootstrap.js b/static/src/js/lib/bootstrap/bootstrap.js index fb914ec8..d5573dfc 100644 --- a/static/src/js/lib/bootstrap/bootstrap.js +++ b/static/src/js/lib/bootstrap/bootstrap.js @@ -1 +1 @@ -require(["jquery", "modal", "dropdown", "transition"]); \ No newline at end of file +require(["jquery", "modal", "dropdown", "transition", "collapse"]); \ No newline at end of file From 04b60acbad3a730225427312227ef6ec41902c2d Mon Sep 17 00:00:00 2001 From: virusdefender <1670873886@qq.com> Date: Tue, 29 Sep 2015 23:18:14 +0800 Subject: [PATCH 11/13] =?UTF-8?q?=E9=83=A8=E5=88=86=20model=20=E6=8C=87?= =?UTF-8?q?=E5=AE=9A=E6=95=B0=E6=8D=AE=E5=BA=93=E8=A1=A8=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- contest/models.py | 3 +++ group/models.py | 1 + problem/models.py | 1 + 3 files changed, 5 insertions(+) diff --git a/contest/models.py b/contest/models.py index 1e4f45aa..2708bcf4 100644 --- a/contest/models.py +++ b/contest/models.py @@ -120,6 +120,9 @@ class ContestRank(models.Model): # key 是比赛题目的id submission_info = JSONField(default={}) + class Meta: + db_table = "contest_rank" + def update_rank(self, submission): if not submission.contest_id or submission.contest_id != self.contest_id: raise ValueError("Error submission type") diff --git a/group/models.py b/group/models.py index b3992468..a2db074a 100644 --- a/group/models.py +++ b/group/models.py @@ -37,5 +37,6 @@ class JoinGroupRequest(models.Model): # 是否处理 status = models.BooleanField(default=False) accepted = models.BooleanField(default=False) + class Meta: db_table = "join_group_request" diff --git a/problem/models.py b/problem/models.py index adb7dd4d..331f003e 100644 --- a/problem/models.py +++ b/problem/models.py @@ -45,6 +45,7 @@ class AbstractProblem(models.Model): total_accepted_number = models.IntegerField(default=0) class Meta: + db_table = "problem" abstract = True From 246826139f0db41f3fe3ddf0e81ee23b9a3da3b4 Mon Sep 17 00:00:00 2001 From: virusdefender <1670873886@qq.com> Date: Wed, 30 Sep 2015 21:21:04 +0800 Subject: [PATCH 12/13] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20mq=20=E4=B8=AD?= =?UTF-8?q?=E5=AF=B9=E4=BA=8E=E9=9D=9E=20ac=20=E7=9A=84=E9=A2=98=E7=9B=AE?= =?UTF-8?q?=E9=80=BB=E8=BE=91=E5=88=A4=E6=96=AD=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mq/scripts/mq.py | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/mq/scripts/mq.py b/mq/scripts/mq.py index 47231da1..5e16edf5 100644 --- a/mq/scripts/mq.py +++ b/mq/scripts/mq.py @@ -39,20 +39,21 @@ class MessageQueue(object): logger.warning("Submission user does not exist, submission_id: " + submission_id) continue - if submission.result == result["accepted"] and not submission.contest_id: + if not submission.contest_id: # 更新普通题目的 ac 计数器 - try: - problem = Problem.objects.get(id=submission.problem_id) - problem.total_accepted_number += 1 - problem.save() - except Problem.DoesNotExist: - logger.warning("Submission problem does not exist, submission_id: " + submission_id) - continue + if submission.result == result["accepted"]: + try: + problem = Problem.objects.get(id=submission.problem_id) + problem.total_accepted_number += 1 + problem.save() + except Problem.DoesNotExist: + logger.warning("Submission problem does not exist, submission_id: " + submission_id) + continue - problems_status = user.problems_status - problems_status["problems"][str(problem.id)] = 1 - user.problems_status = problems_status - user.save() + problems_status = user.problems_status + problems_status["problems"][str(problem.id)] = 1 + user.problems_status = problems_status + user.save() # 普通题目的话,到这里就结束了 continue From 85ab5adfe629274ba782c9eb3c9a1f39e6d97364 Mon Sep 17 00:00:00 2001 From: virusdefender <1670873886@qq.com> Date: Thu, 8 Oct 2015 11:13:53 +0800 Subject: [PATCH 13/13] =?UTF-8?q?=E4=BF=AE=E6=94=B9=20xss=20filter=20?= =?UTF-8?q?=E8=A7=84=E5=88=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- utils/xss_filter.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/utils/xss_filter.py b/utils/xss_filter.py index 825fbc97..337f0a5a 100644 --- a/utils/xss_filter.py +++ b/utils/xss_filter.py @@ -38,7 +38,7 @@ class XssHtml(HTMLParser): 'p', 'div', 'em', 'span', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'blockquote', 'ul', 'ol', 'tr', 'th', 'td', 'hr', 'li', 'u', 'embed', 's', 'table', 'thead', 'tbody', - 'caption', 'small', 'q', 'sup', 'sub'] + 'caption', 'small', 'q', 'sup', 'sub', 'font'] common_attrs = ["style", "class", "name"] nonend_tags = ["img", "hr", "br", "embed"] tags_own_attrs = { @@ -46,6 +46,7 @@ class XssHtml(HTMLParser): "a": ["href", "target", "rel", "title"], "embed": ["src", "width", "height", "type", "allowfullscreen", "loop", "play", "wmode", "menu"], "table": ["border", "cellpadding", "cellspacing"], + "font": ["color"] } def __init__(self, allows=[]):
# 题目名称 用户