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 () {