From 18abd6a465db58b33e4cdbb3b44489a11c6bc0a0 Mon Sep 17 00:00:00 2001
From: virusdefender <1670873886@qq.com>
Date: Sat, 19 Sep 2015 15:07:31 +0800
Subject: [PATCH 1/6] =?UTF-8?q?=E8=AE=B0=E5=BD=95=E7=94=A8=E6=88=B7?=
=?UTF-8?q?=E8=BE=93=E5=87=BA=20md5?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
judge/judger/client.py | 40 ++++++++++++++++++++--------------------
1 file changed, 20 insertions(+), 20 deletions(-)
diff --git a/judge/judger/client.py b/judge/judger/client.py
index a5a1f47..53164e5 100644
--- a/judge/judger/client.py
+++ b/judge/judger/client.py
@@ -98,36 +98,34 @@ class JudgeClient(object):
def _compare_output(self, test_case_id):
test_case_config = self._test_case_info["test_cases"][str(test_case_id)]
- test_case_md5 = test_case_config["output_md5"]
output_path = judger_workspace + str(test_case_id) + ".out"
try:
f = open(output_path, "rb")
except IOError:
# 文件不存在等引发的异常 返回结果错误
- return False
+ return "", False
- # 计算输出文件的md5 和之前测试用例文件的md5进行比较
- # 现在比较的是完整的文件
- md5 = hashlib.md5()
- while True:
- data = f.read(2 ** 8)
- if not data:
- break
- md5.update(data)
+ if "striped_output_md5" not in test_case_config:
+ # 计算输出文件的md5 和之前测试用例文件的md5进行比较
+ # 兼容之前没有striped_output_md5的测试用例
+ # 现在比较的是完整的文件
+ md5 = hashlib.md5()
+ while True:
+ data = f.read(2 ** 8)
+ if not data:
+ break
+ md5.update(data)
+ output_md5 = md5.hexdigest()
- if md5.hexdigest() == test_case_md5:
- return True
+ return output_md5, output_md5 == test_case_config["output_md5"]
else:
# 这时候需要去除用户输出最后的空格和换行 再去比较md5
- # 兼容之前没有striped_output_md5的测试用例
- if "striped_output_md5" not in test_case_config:
- return False
- f.seek(0)
- striped_md5 = hashlib.md5()
+ md5 = hashlib.md5()
# 比较和返回去除空格后的md5比较结果
- striped_md5.update(f.read().rstrip())
- return striped_md5.hexdigest() == test_case_config["striped_output_md5"]
+ md5.update(f.read().rstrip())
+ output_md5 = md5.hexdigest()
+ return output_md5, output_md5 == test_case_config["striped_output_md5"]
def _judge_one(self, test_case_id):
# 运行lrun程序 接收返回值
@@ -157,10 +155,12 @@ class JudgeClient(object):
return run_result
# 下面就是代码正常运行了 需要判断代码的输出是否正确
- if self._compare_output(test_case_id):
+ output_md5, r = self._compare_output(test_case_id)
+ if r:
run_result["result"] = result["accepted"]
else:
run_result["result"] = result["wrong_answer"]
+ run_result["output_md5"] = output_md5
return run_result
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 2/6] =?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 f60e9ca..c2852a3 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 8a3414f..c482aea 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 3/6] =?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 0b9d605..3c9a153 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 4/6] =?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 c1c1958..b38161a 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 6d556fc..6f16acf 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 5/6] =?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 fe51417..6b31a72 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 6/6] =?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 6b31a72..b018f52 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 () {