From 83124f3c866a7657b8120034b6d83e1bb2b37fbc Mon Sep 17 00:00:00 2001
From: virusdefender <1670873886@qq.com>
Date: Sat, 19 Sep 2015 18:46:03 +0800
Subject: [PATCH 01/11] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=88=A4=E6=96=AD?=
=?UTF-8?q?=E9=AA=8C=E8=AF=81=E7=A0=81=E6=98=AF=E5=90=A6=E5=AD=98=E5=9C=A8?=
=?UTF-8?q?=E7=9A=84=E6=97=B6=E5=80=99=EF=BC=8C=E7=94=A8=E6=88=B7=E4=B8=8D?=
=?UTF-8?q?=E5=AD=98=E5=9C=A8=E5=AF=BC=E8=87=B4=E7=9A=84=E6=8A=A5=E9=94=99?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
account/serializers.py | 2 +-
account/views.py | 14 ++++++--------
2 files changed, 7 insertions(+), 9 deletions(-)
diff --git a/account/serializers.py b/account/serializers.py
index f60e9cac..c2852a3c 100644
--- a/account/serializers.py
+++ b/account/serializers.py
@@ -7,7 +7,7 @@ from .models import User
class UserLoginSerializer(serializers.Serializer):
username = serializers.CharField(max_length=30)
password = serializers.CharField(max_length=30)
- captcha = serializers.CharField(required=False,min_length=4,max_length=4)
+ captcha = serializers.CharField(required=False, min_length=4, max_length=4)
class UsernameCheckSerializer(serializers.Serializer):
diff --git a/account/views.py b/account/views.py
index 8a3414f3..c482aeae 100644
--- a/account/views.py
+++ b/account/views.py
@@ -26,17 +26,15 @@ class UserLoginAPIView(APIView):
serializer = UserLoginSerializer(data=request.data)
if serializer.is_valid():
data = serializer.data
- user = User.objects.get(username=data["username"])
- # 只有管理员才适用验证码登录
- if user.admin_type > 0:
- if not "captcha" in data:
- return error_response(u"请填写验证码!")
- captcha = Captcha(request)
- if not captcha.check(data["captcha"]):
- return error_response(u"验证码错误")
user = auth.authenticate(username=data["username"], password=data["password"])
# 用户名或密码错误的话 返回None
if user:
+ if user.admin_type > 0:
+ if "captcha" not in data:
+ return error_response(u"请填写验证码!")
+ captcha = Captcha(request)
+ if not captcha.check(data["captcha"]):
+ return error_response(u"验证码错误")
auth.login(request, user)
return success_response(u"登录成功")
else:
From 0d6d1a410260d429071a6483cadfcded603bf9bd Mon Sep 17 00:00:00 2001
From: virusdefender <1670873886@qq.com>
Date: Sun, 20 Sep 2015 14:10:38 +0800
Subject: [PATCH 02/11] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=88=A4=E9=A2=98?=
=?UTF-8?q?=E5=B8=AE=E5=8A=A9?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
template/src/utils/help.html | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/template/src/utils/help.html b/template/src/utils/help.html
index 0b9d605f..3c9a1539 100644
--- a/template/src/utils/help.html
+++ b/template/src/utils/help.html
@@ -45,7 +45,9 @@ java -cp {exe_path} Main
C/C++ 的64位整数类型,请使用 long long 声明,使用 cin/cout 或 %lld 输入输出。
使用__int64会导致编译错误。
程序执行时间指CPU时间,占用内存按执行过程中内存消耗的峰值计,有多组测试数据时以最大的时间和内存消耗为准
-
+ 判题的时候会去除你的输出的最后的换行和空格,然后与去除最后的换行和空格的答案做比较,如果不一致就是 Wrong Answer。
+ 其余的行末空格和空行不去除,看清楚题目的要求。没有格式错误。
+
From fcafd3444283134bde4960a44d78496d88d6c0ed Mon Sep 17 00:00:00 2001
From: virusdefender <1670873886@qq.com>
Date: Sun, 20 Sep 2015 14:11:03 +0800
Subject: [PATCH 03/11] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=AF=94=E8=B5=9B?=
=?UTF-8?q?=E5=80=92=E8=AE=A1=E6=97=B6=E7=9A=84=20api?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
contest/views.py | 21 +++++++++++++++++++++
oj/urls.py | 6 ++++--
2 files changed, 25 insertions(+), 2 deletions(-)
diff --git a/contest/views.py b/contest/views.py
index c1c19580..b38161a5 100644
--- a/contest/views.py
+++ b/contest/views.py
@@ -7,6 +7,8 @@ from django.db import IntegrityError
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 rest_framework.views import APIView
from utils.shortcuts import (serializer_invalid_response, error_response,
@@ -454,3 +456,22 @@ def contest_rank_page(request, contest_id):
"auto_refresh": request.GET.get("auto_refresh", None) == "true",
"show_real_name": request.GET.get("show_real_name", None) == "true",
"real_time_rank": contest.real_time_rank})
+
+
+class ContestTimeAPIView(APIView):
+ """
+ 获取比赛开始或者结束的倒计时,返回毫秒数字
+ """
+ def get(self, request):
+ t = request.GET.get("type", "start")
+ contest_id = request.GET.get("contest_id", -1)
+ try:
+ contest = Contest.objects.get(id=contest_id)
+ except Contest.DoesNotExist:
+ return error_response(u"比赛不存在")
+ if t == "start":
+ # 距离开始还有多长时间
+ return success_response(int((contest.start_time - now()).total_seconds() * 1000))
+ else:
+ # 距离结束还有多长时间
+ return success_response(int((contest.end_time - now()).total_seconds() * 1000))
diff --git a/oj/urls.py b/oj/urls.py
index 6d556fc6..6f16acf8 100644
--- a/oj/urls.py
+++ b/oj/urls.py
@@ -8,7 +8,8 @@ from account.views import (UserLoginAPIView, UsernameCheckAPIView, UserRegisterA
from announcement.views import AnnouncementAdminAPIView
-from contest.views import ContestAdminAPIView, ContestProblemAdminAPIView, ContestPasswordVerifyAPIView
+from contest.views import (ContestAdminAPIView, ContestProblemAdminAPIView,
+ ContestPasswordVerifyAPIView, ContestTimeAPIView)
from group.views import (GroupAdminAPIView, GroupMemberAdminAPIView,
JoinGroupAPIView, JoinGroupRequestAdminAPIView)
@@ -25,7 +26,6 @@ from contest_submission.views import contest_problem_my_submissions_list_page
urlpatterns = [
- url(r'^install/$', "install.views.install"),
url("^$", "account.views.index_page", name="index_page"),
url(r'^docs/', include('rest_framework_swagger.urls')),
url(r'^admin/$', TemplateView.as_view(template_name="admin/admin.html"), name="admin_spa_page"),
@@ -117,4 +117,6 @@ urlpatterns = [
url(r'^captcha/$', "utils.captcha.views.show_captcha", name="show_captcha"),
url(r'^api/account_security_check/$', AccountSecurityAPIView.as_view(), name="account_security_check"),
+
+ url(r'^api/contest/time/$', ContestTimeAPIView.as_view(), name="contest_time_api_view"),
]
From 899f2768007669268bc0478629bc29195c67852a Mon Sep 17 00:00:00 2001
From: virusdefender <1670873886@qq.com>
Date: Sun, 20 Sep 2015 14:11:17 +0800
Subject: [PATCH 04/11] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E9=A2=98=E7=9B=AE?=
=?UTF-8?q?=E9=A1=B5=E9=9D=A2=E5=80=92=E8=AE=A1=E6=97=B6=E7=9A=84=20js?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
static/src/js/app/oj/problem/problem.js | 37 ++++++++++++++++++++++++-
1 file changed, 36 insertions(+), 1 deletion(-)
diff --git a/static/src/js/app/oj/problem/problem.js b/static/src/js/app/oj/problem/problem.js
index fe51417c..6b31a729 100644
--- a/static/src/js/app/oj/problem/problem.js
+++ b/static/src/js/app/oj/problem/problem.js
@@ -86,7 +86,7 @@ require(["jquery", "codeMirror", "csrfToken", "bsAlert", "ZeroClipboard"],
function getResult() {
if (counter++ > 10) {
hideLoading();
- bsAlert("抱歉,服务器可能出现了故障,请稍后到我的提交列表中查看");
+ bsAlert("抱歉,服务器正在紧张判题中,请稍后到我的提交列表中查看");
counter = 0;
return;
}
@@ -130,6 +130,41 @@ require(["jquery", "codeMirror", "csrfToken", "bsAlert", "ZeroClipboard"],
}
}
+ function getServerTime(){
+ var contestId = location.pathname.split("/")[2];
+ var time = 0;
+ $.ajax({
+ url: "/api/contest/time/?contest_id=" + contestId + "&type=end",
+ dataType: "json",
+ method: "get",
+ async: false,
+ success: function(data){
+ if(!data.code){
+ time = data.data;
+ }
+ },
+ error: function(){
+ time = new Date().getTime();
+ }
+ });
+ return time;
+ }
+
+ if(location.href.indexOf("contest") > -1) {
+ setInterval(function () {
+ var time = getServerTime();
+ console.log(time);
+ var minutes = parseInt(time / (1000 * 60));
+ console.log(time);
+ if(minutes == 0){
+ bsAlert("比赛即将结束");
+ }
+ else if(minutes > 0 && minutes <= 5){
+ bsAlert("比赛还剩" + minutes.toString() + "分钟");
+ }
+ }, 1000 * 5);
+ }
+
$("#submit-code-button").click(function () {
var code = codeEditor.getValue();
From 3ef7644e9b4332cb269c629043eddba4a03e057b Mon Sep 17 00:00:00 2001
From: virusdefender <1670873886@qq.com>
Date: Sun, 20 Sep 2015 14:41:34 +0800
Subject: [PATCH 05/11] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=88=B7=E6=96=B0?=
=?UTF-8?q?=E6=97=B6=E9=97=B4?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
static/src/js/app/oj/problem/problem.js | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/static/src/js/app/oj/problem/problem.js b/static/src/js/app/oj/problem/problem.js
index 6b31a729..b018f523 100644
--- a/static/src/js/app/oj/problem/problem.js
+++ b/static/src/js/app/oj/problem/problem.js
@@ -153,16 +153,14 @@ require(["jquery", "codeMirror", "csrfToken", "bsAlert", "ZeroClipboard"],
if(location.href.indexOf("contest") > -1) {
setInterval(function () {
var time = getServerTime();
- console.log(time);
var minutes = parseInt(time / (1000 * 60));
- console.log(time);
if(minutes == 0){
bsAlert("比赛即将结束");
}
else if(minutes > 0 && minutes <= 5){
bsAlert("比赛还剩" + minutes.toString() + "分钟");
}
- }, 1000 * 5);
+ }, 1000 * 60);
}
$("#submit-code-button").click(function () {
From 43be94cce63e1c396bdbce79eeb98dfc52889145 Mon Sep 17 00:00:00 2001
From: virusdefender <1670873886@qq.com>
Date: Mon, 21 Sep 2015 11:06:11 +0800
Subject: [PATCH 06/11] =?UTF-8?q?=E6=AF=94=E8=B5=9B=E5=A6=82=E6=9E=9C?=
=?UTF-8?q?=E4=B8=8D=E6=98=AF=E6=AD=A3=E5=9C=A8=E8=BF=9B=E8=A1=8C=E7=9A=84?=
=?UTF-8?q?=E7=8A=B6=E6=80=81=EF=BC=8C=E5=B0=B1=E4=B8=8D=E5=88=9B=E5=BB=BA?=
=?UTF-8?q?=E6=AF=94=E8=B5=9B=E7=9A=84=E5=88=86=E6=95=B0=E8=AE=B0=E5=BD=95?=
=?UTF-8?q?=E5=92=8C=E5=A2=9E=E5=8A=A0=E6=AF=94=E8=B5=9B=E9=A2=98=E7=9B=AE?=
=?UTF-8?q?=E8=AE=A1=E6=95=B0=E5=99=A8?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
mq/scripts/mq.py | 3 +++
1 file changed, 3 insertions(+)
diff --git a/mq/scripts/mq.py b/mq/scripts/mq.py
index 567eebb1..b26a46fd 100644
--- a/mq/scripts/mq.py
+++ b/mq/scripts/mq.py
@@ -57,6 +57,9 @@ class MessageQueue(object):
# 能运行到这里的都是比赛题目
try:
contest = Contest.objects.get(id=submission.contest_id)
+ if contest.status != 0:
+ logger.info("Contest debug mode, id: " + str(contest.id) + ", submission id: " + submission_id)
+ continue
contest_problem = ContestProblem.objects.get(contest=contest, id=submission.problem_id)
except Contest.DoesNotExist:
logger.warning("Submission contest does not exist, submission_id: " + submission_id)
From 041fd2cb602c72299c1e96fb204be7b93d2fdc69 Mon Sep 17 00:00:00 2001
From: virusdefender <1670873886@qq.com>
Date: Mon, 21 Sep 2015 11:16:30 +0800
Subject: [PATCH 07/11] =?UTF-8?q?=E5=8E=BB=E9=99=A4=E9=83=A8=E5=88=86=20ma?=
=?UTF-8?q?gic=20number?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
contest/decorators.py | 10 +++++-----
contest/models.py | 10 +++++++---
2 files changed, 12 insertions(+), 8 deletions(-)
diff --git a/contest/decorators.py b/contest/decorators.py
index df73274a..600d98b8 100644
--- a/contest/decorators.py
+++ b/contest/decorators.py
@@ -3,12 +3,12 @@ from functools import wraps
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render
-from django.utils.timezone import now
from utils.shortcuts import error_response, error_page
from account.models import SUPER_ADMIN
-from .models import Contest
+from .models import (Contest, PASSWORD_PROTECTED_CONTEST, PUBLIC_CONTEST, GROUP_CONTEST,
+ CONTEST_ENDED, CONTEST_NOT_START, CONTEST_UNDERWAY)
def check_user_contest_permission(func):
@@ -55,7 +55,7 @@ def check_user_contest_permission(func):
return func(*args, **kwargs)
# 有密码的公开赛
- if contest.contest_type == 2:
+ if contest.contest_type == PASSWORD_PROTECTED_CONTEST:
# 没有输入过密码
if contest.id not in request.session.get("contests", []):
if request.is_ajax():
@@ -65,7 +65,7 @@ def check_user_contest_permission(func):
{"reason": "password_protect", "show_tab": False, "contest": contest})
# 指定小组参加的
- if contest.contest_type == 0:
+ if contest.contest_type == GROUP_CONTEST:
if not contest.groups.filter(id__in=request.user.group_set.all()).exists():
if request.is_ajax():
return error_response(u"只有指定小组的可以参加这场比赛")
@@ -74,7 +74,7 @@ def check_user_contest_permission(func):
{"reason": "group_limited", "show_tab": False, "contest": contest})
# 比赛没有开始
- if contest.status == 1:
+ if contest.status == CONTEST_NOT_START:
if request.is_ajax():
return error_response(u"比赛还没有开始")
else:
diff --git a/contest/models.py b/contest/models.py
index 7331ec27..e0484555 100644
--- a/contest/models.py
+++ b/contest/models.py
@@ -10,6 +10,10 @@ GROUP_CONTEST = 0
PUBLIC_CONTEST = 1
PASSWORD_PROTECTED_CONTEST = 2
+CONTEST_NOT_START = 1
+CONTEST_ENDED = -1
+CONTEST_UNDERWAY = 0
+
class Contest(models.Model):
title = models.CharField(max_length=40, unique=True)
@@ -44,13 +48,13 @@ class Contest(models.Model):
def status(self):
if self.start_time > now():
# 没有开始 返回1
- return 1
+ return CONTEST_NOT_START
elif self.end_time < now():
# 已经结束 返回0
- return -1
+ return CONTEST_ENDED
else:
# 正在进行 返回0
- return 0
+ return CONTEST_UNDERWAY
class Meta:
db_table = "contest"
From 725d950e27f971cf2308049b938ec523b80abd5d Mon Sep 17 00:00:00 2001
From: virusdefender <1670873886@qq.com>
Date: Mon, 21 Sep 2015 12:28:22 +0800
Subject: [PATCH 08/11] =?UTF-8?q?=E7=94=A8=E6=88=B7=E4=B8=8D=E9=9C=80?=
=?UTF-8?q?=E8=A6=81=E9=AA=8C=E8=AF=81=E7=A0=81=E7=9A=84=E6=97=B6=E5=80=99?=
=?UTF-8?q?=E5=88=B7=E6=96=B0=E9=AA=8C=E8=AF=81=E4=BC=9A=E5=AF=BC=E8=87=B4?=
=?UTF-8?q?=E9=94=99=E8=AF=AF=EF=BC=8C=E5=A2=9E=E5=8A=A0=E5=88=A4=E6=96=AD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
static/src/js/app/oj/account/login.js | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/static/src/js/app/oj/account/login.js b/static/src/js/app/oj/account/login.js
index 32343c95..22d47593 100644
--- a/static/src/js/app/oj/account/login.js
+++ b/static/src/js/app/oj/account/login.js
@@ -33,7 +33,9 @@ require(["jquery", "bsAlert", "csrfToken", "validator"], function ($, bsAlert, c
location.href = "/";
}
else {
- refresh_captcha();
+ if(applied_captcha) {
+ refresh_captcha();
+ }
bsAlert(data.data);
}
}
From cb0e7cf9382b94299b2df3b9c00d0e3d68aa98aa Mon Sep 17 00:00:00 2001
From: virusdefender <1670873886@qq.com>
Date: Mon, 21 Sep 2015 12:32:50 +0800
Subject: [PATCH 09/11] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=85=AC=E5=91=8A?=
=?UTF-8?q?=E5=88=97=E8=A1=A8=E4=B8=AD=E7=94=A8=E6=88=B7=E6=9D=83=E9=99=90?=
=?UTF-8?q?=E5=88=A4=E6=96=AD=E9=94=99=E8=AF=AF=E7=9A=84=E6=83=85=E5=86=B5?=
=?UTF-8?q?=EF=BC=8C=E6=8A=BD=E5=8F=96=E4=BB=A3=E7=A0=81=E4=B8=BA=20decora?=
=?UTF-8?q?tor=E3=80=82?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
announcement/decorators.py | 43 +++++++++++++++++++++++++
announcement/models.py | 2 +-
announcement/views.py | 22 +++----------
utils/templatetags/announcement_list.py | 1 +
4 files changed, 49 insertions(+), 19 deletions(-)
create mode 100644 announcement/decorators.py
diff --git a/announcement/decorators.py b/announcement/decorators.py
new file mode 100644
index 00000000..96df987d
--- /dev/null
+++ b/announcement/decorators.py
@@ -0,0 +1,43 @@
+# coding=utf-8
+from functools import wraps
+
+from django.http import HttpResponse, HttpResponseRedirect
+from django.shortcuts import render
+
+from utils.shortcuts import error_response, error_page
+
+from account.models import SUPER_ADMIN
+from .models import Announcement
+
+
+def check_user_announcement_permission(func):
+ @wraps(func)
+ def _check_user_announcement_permission(*args, **kwargs):
+ """
+ 这个函数检测当前用户能否查看这个公告
+ """
+ # CBV 的情况,第一个参数是self,第二个参数是request
+ if len(args) == 2:
+ request = args[-1]
+ else:
+ request = args[0]
+
+ if "announcement_id" not in kwargs:
+ return error_page(request, u"参数错误")
+ announcement_id = kwargs["announcement_id"]
+
+ try:
+ announcement = Announcement.objects.get(id=announcement_id, visible=True)
+ except Announcement.DoesNotExist:
+ return error_page(request, u"公告不存在")
+
+ # 如果公告是只有部分小组可见的
+ if not announcement.is_global:
+ # 用户必须是登录状态的
+ if not request.user.is_authenticated():
+ return HttpResponseRedirect("/login/")
+ if not announcement.groups.filter(id__in=request.user.group_set.all()).exists():
+ return error_page(request, u"公告不存在")
+ return func(*args, **kwargs)
+
+ return _check_user_announcement_permission
diff --git a/announcement/models.py b/announcement/models.py
index 1dfa6060..c3267f12 100644
--- a/announcement/models.py
+++ b/announcement/models.py
@@ -18,7 +18,7 @@ class Announcement(models.Model):
last_update_time = models.DateTimeField(auto_now=True)
# 是否可见 false的话相当于删除
visible = models.BooleanField(default=True)
- # 公告可见范围 0是全局可见 1是部分小组可见,需要在下面的字段中存储可见的小组
+ # 公告可见范围 True 是全局可见 False 是部分小组可见,需要在下面的字段中存储可见的小组
is_global = models.BooleanField()
groups = models.ManyToManyField(Group)
diff --git a/announcement/views.py b/announcement/views.py
index 6790e8ce..3160d9ef 100644
--- a/announcement/views.py
+++ b/announcement/views.py
@@ -10,27 +10,13 @@ from group.models import Group
from .models import Announcement
from .serializers import (CreateAnnouncementSerializer, AnnouncementSerializer,
EditAnnouncementSerializer)
+from .decorators import check_user_announcement_permission
+@check_user_announcement_permission
def announcement_page(request, announcement_id):
- try:
- announcement = Announcement.objects.get(id=announcement_id, visible=True)
- except Announcement.DoesNotExist:
- return error_page(request, u"公告不存在")
- # 公开的公告
- if announcement.is_global == 0:
- return render(request, "oj/announcement/announcement.html", {"announcement": announcement})
- else:
- if not request.user.is_authenticated():
- return error_page(request, u"公告不存在")
- # 判断是不是在组里面
- if request.user.admin_type == SUPER_ADMIN or request.user == announcement.created_by:
- return render(request, "oj/announcement/announcement.html", {"announcement": announcement})
- else:
- if request.user.groups.filter(id__in=[item.id for item in announcement.groups.all()]).exists():
- return render(request, "oj/announcement/announcement.html", {"announcement": announcement})
- else:
- return error_page(request, u"公告不存在")
+ announcement = Announcement.objects.get(id=announcement_id, visible=True)
+ return render(request, "oj/announcement/announcement.html", {"announcement": announcement})
class AnnouncementAdminAPIView(APIView):
diff --git a/utils/templatetags/announcement_list.py b/utils/templatetags/announcement_list.py
index acf38d9f..1b2f331e 100644
--- a/utils/templatetags/announcement_list.py
+++ b/utils/templatetags/announcement_list.py
@@ -3,6 +3,7 @@ from django import template
from announcement.models import Announcement
+
def public_announcement_list():
return Announcement.objects.filter(is_global=True, visible=True).order_by("-create_time")
From 60d727d7b23a07a71d6b8593fb773d22254cf0c5 Mon Sep 17 00:00:00 2001
From: virusdefender <1670873886@qq.com>
Date: Mon, 21 Sep 2015 13:41:14 +0800
Subject: [PATCH 10/11] =?UTF-8?q?=E5=88=A0=E9=99=A4=E7=BB=9F=E8=AE=A1?=
=?UTF-8?q?=E5=8A=9F=E8=83=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
static/src/js/app/admin/admin.js | 3 +--
template/src/admin/admin.html | 39 -----------------------------
template/src/admin/index/index.html | 2 +-
3 files changed, 2 insertions(+), 42 deletions(-)
diff --git a/static/src/js/app/admin/admin.js b/static/src/js/app/admin/admin.js
index 878b9cad..d68dba11 100644
--- a/static/src/js/app/admin/admin.js
+++ b/static/src/js/app/admin/admin.js
@@ -24,8 +24,7 @@ require(["jquery", "avalon", "bootstrap"], function ($, avalon) {
var superAdminNav = [
{ name: "首页",
children: [{name: "主页", hash: "#index/index"},
- {name: "监控", hash: "#monitor/monitor"},
- {name: "统计", hash: "#statistics/statistics"}]
+ {name: "监控", hash: "#monitor/monitor"}]
},
{
name: "通用",
diff --git a/template/src/admin/admin.html b/template/src/admin/admin.html
index 0e470c6e..7020dae3 100644
--- a/template/src/admin/admin.html
+++ b/template/src/admin/admin.html
@@ -71,45 +71,6 @@
{{ item.name }}
-
diff --git a/template/src/admin/index/index.html b/template/src/admin/index/index.html
index 61168280..257eab15 100644
--- a/template/src/admin/index/index.html
+++ b/template/src/admin/index/index.html
@@ -1 +1 @@
-Hello world
\ No newline at end of file
+Online Judge Admin
\ No newline at end of file
From 5f23bff3c5a9040c4292fdd0a3c231e02eb07a71 Mon Sep 17 00:00:00 2001
From: virusdefender <1670873886@qq.com>
Date: Mon, 21 Sep 2015 13:56:54 +0800
Subject: [PATCH 11/11] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=89=8D=E5=8F=B0?=
=?UTF-8?q?=E9=A2=98=E7=9B=AE=E7=9A=84=E9=87=8D=E6=96=B0=E5=88=A4=E9=A2=98?=
=?UTF-8?q?=E5=8A=9F=E8=83=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
oj/urls.py | 4 ++-
.../js/app/admin/problem/submissionList.js | 14 +++++++++
submission/serializers.py | 4 +++
submission/views.py | 30 ++++++++++++++++++-
.../src/admin/problem/submission_list.html | 1 +
5 files changed, 51 insertions(+), 2 deletions(-)
diff --git a/oj/urls.py b/oj/urls.py
index 6f16acf8..5b65e4c0 100644
--- a/oj/urls.py
+++ b/oj/urls.py
@@ -17,7 +17,8 @@ from group.views import (GroupAdminAPIView, GroupMemberAdminAPIView,
from admin.views import AdminTemplateView
from problem.views import TestCaseUploadAPIView, ProblemTagAdminAPIView, ProblemAdminAPIView
-from submission.views import SubmissionAPIView, SubmissionAdminAPIView, SubmissionShareAPIView
+from submission.views import (SubmissionAPIView, SubmissionAdminAPIView,
+ SubmissionShareAPIView, SubmissionRejudgeAdminAPIView)
from contest_submission.views import ContestSubmissionAPIView, ContestSubmissionAdminAPIView
from monitor.views import QueueLengthMonitorAPIView
from utils.views import SimditorImageUploadAPIView
@@ -119,4 +120,5 @@ urlpatterns = [
url(r'^api/account_security_check/$', AccountSecurityAPIView.as_view(), name="account_security_check"),
url(r'^api/contest/time/$', ContestTimeAPIView.as_view(), name="contest_time_api_view"),
+ url(r'^api/admin/rejudge/$', SubmissionRejudgeAdminAPIView.as_view(), name="submission_rejudge_api"),
]
diff --git a/static/src/js/app/admin/problem/submissionList.js b/static/src/js/app/admin/problem/submissionList.js
index 1af2e6ce..e8d00bb0 100644
--- a/static/src/js/app/admin/problem/submissionList.js
+++ b/static/src/js/app/admin/problem/submissionList.js
@@ -51,6 +51,20 @@ require(["jquery", "avalon", "csrfToken", "bsAlert"], function ($, avalon, csrfT
},
showProblemListPage: function(){
vm.$fire("up!showProblemListPage");
+ },
+ rejudge: function(submission_id){
+ $.ajax({
+ beforeSend: csrfTokenHeader,
+ url: "/api/admin/rejudge/",
+ method: "post",
+ data: {"submission_id": submission_id},
+ success: function(data){
+ if(!data.code){
+ bsAlert("重判任务提交成功");
+ }
+ }
+
+ })
}
});
}
diff --git a/submission/serializers.py b/submission/serializers.py
index 8fd62787..3a5308cd 100644
--- a/submission/serializers.py
+++ b/submission/serializers.py
@@ -26,3 +26,7 @@ class SubmissionhareSerializer(serializers.Serializer):
submission_id = serializers.CharField(max_length=40)
+class SubmissionRejudgeSerializer(serializers.Serializer):
+ submission_id = serializers.CharField(max_length=40)
+
+
diff --git a/submission/views.py b/submission/views.py
index 6eb69fae..396cdfe8 100644
--- a/submission/views.py
+++ b/submission/views.py
@@ -19,7 +19,8 @@ from announcement.models import Announcement
from utils.shortcuts import serializer_invalid_response, error_response, success_response, error_page, paginate
from .models import Submission
-from .serializers import CreateSubmissionSerializer, SubmissionSerializer, SubmissionhareSerializer
+from .serializers import (CreateSubmissionSerializer, SubmissionSerializer,
+ SubmissionhareSerializer, SubmissionRejudgeSerializer)
logger = logging.getLogger("app_info")
@@ -219,3 +220,30 @@ class SubmissionShareAPIView(APIView):
return success_response(submission.shared)
else:
return serializer_invalid_response(serializer)
+
+
+class SubmissionRejudgeAdminAPIView(APIView):
+ def post(self, request):
+ serializer = SubmissionRejudgeSerializer(data=request.data)
+ if serializer.is_valid():
+ submission_id = serializer.data["submission_id"]
+ try:
+ submission = Submission.objects.get(id=submission_id)
+ except Submission.DoesNotExist:
+ return error_response(u"提交不存在")
+ # 目前只考虑前台公开题目的重新判题
+ try:
+ problem = Problem.objects.get(id=submission.problem_id)
+ except Problem.DoesNotExist:
+ return error_response(u"题目不存在")
+ try:
+ judge.delay(submission_id, problem.time_limit, problem.memory_limit, problem.test_case_id)
+ except Exception as e:
+ logger.error(e)
+ return error_response(u"提交判题任务失败")
+
+ # 增加redis 中判题队列长度的计数器
+ r = redis.Redis(host=redis_config["host"], port=redis_config["port"], db=redis_config["db"])
+ r.incr("judge_queue_length")
+ else:
+ return serializer_invalid_response(serializer)
\ No newline at end of file
diff --git a/template/src/admin/problem/submission_list.html b/template/src/admin/problem/submission_list.html
index 28eaebd4..e0880af5 100644
--- a/template/src/admin/problem/submission_list.html
+++ b/template/src/admin/problem/submission_list.html
@@ -22,6 +22,7 @@
{{ results[el.result] }} |
详情
+ 重判
|