Accept Merge Request #257 增加比赛倒计时 api;修复小 bug : (virusdefender-dev -> dev)
Merge Request: 增加比赛倒计时 api;修复小 bug Created By: @virusdefender Accepted By: @virusdefender URL: https://coding.net/u/virusdefender/p/qduoj/git/merge/257
This commit is contained in:
@@ -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):
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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"),
|
||||
]
|
||||
|
||||
@@ -86,7 +86,7 @@ require(["jquery", "codeMirror", "csrfToken", "bsAlert", "ZeroClipboard"],
|
||||
function getResult() {
|
||||
if (counter++ > 10) {
|
||||
hideLoading();
|
||||
bsAlert("抱歉,服务器可能出现了故障,请稍后到我的提交列表中查看");
|
||||
bsAlert("抱歉,服务器正在紧张判题中,请稍后到我的提交列表中查看");
|
||||
counter = 0;
|
||||
return;
|
||||
}
|
||||
@@ -130,6 +130,39 @@ 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();
|
||||
var minutes = parseInt(time / (1000 * 60));
|
||||
if(minutes == 0){
|
||||
bsAlert("比赛即将结束");
|
||||
}
|
||||
else if(minutes > 0 && minutes <= 5){
|
||||
bsAlert("比赛还剩" + minutes.toString() + "分钟");
|
||||
}
|
||||
}, 1000 * 60);
|
||||
}
|
||||
|
||||
$("#submit-code-button").click(function () {
|
||||
|
||||
var code = codeEditor.getValue();
|
||||
|
||||
@@ -45,7 +45,9 @@ java -cp {exe_path} Main</pre>
|
||||
<li>C/C++ 的64位整数类型,请使用 <code>long long</code> 声明,使用 <code>cin/cout</code> 或 <code>%lld</code> 输入输出。
|
||||
使用<code>__int64</code>会导致编译错误。</li>
|
||||
<li>程序执行时间指CPU时间,占用内存按执行过程中内存消耗的峰值计,有多组测试数据时以最大的时间和内存消耗为准</li>
|
||||
|
||||
<li>判题的时候会去除你的输出的最后的换行和空格,然后与去除最后的换行和空格的答案做比较,如果不一致就是 Wrong Answer。
|
||||
其余的行末空格和空行不去除,看清楚题目的要求。没有格式错误。
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user