完善SPJ测试用例的上传

This commit is contained in:
virusdefender
2016-04-05 17:53:04 +08:00
parent db68e925f2
commit 247d356f7f
5 changed files with 104 additions and 57 deletions

View File

@@ -220,35 +220,61 @@ class TestCaseUploadAPIView(APIView):
if len(name_list) == 0: if len(name_list) == 0:
return error_response(u"压缩包内没有文件") return error_response(u"压缩包内没有文件")
for item in name_list:
if not self._is_legal_test_case_file_name(item):
return error_response(u"%s 文件名不符合规范" % item)
# 排序,这样name_list就是[1.in, 1.out, 2.in, 2.out]的形式了
name_list.sort()
spj = False
for item in name_list:
# 代表里面有.out文件,所以应该是普通题目的测试用例
if item.endswith(".out"):
break
else:
# 否则就应该是spj的测试用例
spj = True
print name_list, spj
if not spj:
if len(name_list) % 2 == 1: if len(name_list) % 2 == 1:
return error_response(u"测试用例文件格式错误,文件数目为奇数") return error_response(u"测试用例文件格式错误,文件数目为奇数")
for index in range(1, len(name_list) / 2 + 1): for index in range(1, len(name_list) / 2 + 1):
if not (str(index) + ".in" in name_list and str(index) + ".out" in name_list): if not (str(index) + ".in" in name_list and str(index) + ".out" in name_list):
return error_response(u"测试用例文件格式错误,缺少" + str(index) + u".in/.out文件") return error_response(u"测试用例文件格式错误,缺少" + str(index) + u".in/.out文件")
test_case_number = len(name_list) / 2
else:
for index in range(1, len(name_list) + 1):
if str(index) + ".in" not in name_list:
return error_response(u"测试用例文件格式错误,缺少" + str(index) + u".in文件")
test_case_number = len(name_list)
problem_test_dir = rand_str() problem_test_dir = rand_str()
test_case_dir = settings.TEST_CASE_DIR + problem_test_dir + "/" test_case_dir = os.path.join(settings.TEST_CASE_DIR, problem_test_dir)
# 得到了合法的测试用例文件列表 然后去解压缩 # 得到了合法的测试用例文件列表 然后去解压缩
os.mkdir(test_case_dir) os.mkdir(test_case_dir)
for name in name_list: for name in name_list:
f = open(test_case_dir + name, "wb") f = open(os.path.join(test_case_dir, name), "wb")
try: try:
f.write(test_case_file.read(name).replace("\r\n", "\n")) f.write(test_case_file.read(name).replace("\r\n", "\n"))
except MemoryError: except MemoryError:
return error_response(u"单个测试数据体积过大!") return error_response(u"单个测试数据体积过大!")
finally: finally:
f.close() f.close()
name_list.sort()
file_info = {"test_case_number": len(name_list) / 2, "test_cases": {}} file_info = {"test_case_number": test_case_number, "test_cases": {}, "spj": spj}
# 计算输出文件的md5 # 计算输出文件的md5
for i in range(1, len(name_list) / 2 + 1): for i in range(1, test_case_number + 1):
if not spj:
md5 = hashlib.md5() md5 = hashlib.md5()
striped_md5 = hashlib.md5() striped_md5 = hashlib.md5()
f = open(test_case_dir + str(i) + ".out", "r") f = open(os.path.join(test_case_dir, str(i) + ".out"), "r")
# 完整文件的md5 # 完整文件的md5
while True: while True:
data = f.read(2 ** 8) data = f.read(2 ** 8)
@@ -261,31 +287,39 @@ class TestCaseUploadAPIView(APIView):
f.seek(0) f.seek(0)
striped_md5.update(f.read().rstrip()) striped_md5.update(f.read().rstrip())
output_md5 = md5.hexdigest()
striped_output_md5 = striped_md5.hexdigest()
output_name = str(i) + ".out"
output_size = os.path.getsize(os.path.join(test_case_dir, output_name))
else:
output_md5 = striped_output_md5 = output_name = output_size = None
file_info["test_cases"][str(i)] = {"input_name": str(i) + ".in", file_info["test_cases"][str(i)] = {"input_name": str(i) + ".in",
"output_name": str(i) + ".out", "output_name": output_name,
"output_md5": md5.hexdigest(), "output_md5": output_md5,
"striped_output_md5": striped_md5.hexdigest(), "striped_output_md5": striped_output_md5,
"input_size": os.path.getsize(test_case_dir + str(i) + ".in"), "input_size": os.path.getsize(os.path.join(test_case_dir, str(i) + ".in")),
"output_size": os.path.getsize(test_case_dir + str(i) + ".out")} "output_size": output_size}
# 写入配置文件 # 写入配置文件
with open(test_case_dir + "info", "w") as f: with open(os.path.join(test_case_dir, "info"), "w") as f:
f.write(json.dumps(file_info)) f.write(json.dumps(file_info))
return success_response({"test_case_id": problem_test_dir, return success_response({"test_case_id": problem_test_dir,
"file_list": file_info["test_cases"]}) "file_list": file_info["test_cases"],
"spj": spj})
def get(self, request): def get(self, request):
test_case_id = request.GET.get("test_case_id", None) test_case_id = request.GET.get("test_case_id", None)
if not test_case_id: if not test_case_id:
return error_response(u"参数错误") return error_response(u"参数错误")
test_case_config = settings.TEST_CASE_DIR + test_case_id + "/info" test_case_config = os.path.join(settings.TEST_CASE_DIR, test_case_id, "info")
try: try:
f = open(test_case_config) f = open(test_case_config)
config = json.loads(f.read()) config = json.loads(f.read())
f.close() f.close()
except Exception as e: except Exception as e:
return error_response(u"读取测试用例出错") return error_response(u"读取测试用例出错")
return success_response({"file_list": config["test_cases"]}) return success_response({"file_list": config["test_cases"], "spj": config.get("spj", False)})
def problem_list_page(request, page=1): def problem_list_page(request, page=1):

View File

@@ -109,7 +109,7 @@ require(["jquery", "avalon", "editor", "uploader", "bsAlert",
vm.source = ""; vm.source = "";
vm.uploadProgress = 0; vm.uploadProgress = 0;
} }
else else {
var vm = avalon.define({ var vm = avalon.define({
$id: "addProblem", $id: "addProblem",
title: "", title: "",
@@ -153,6 +153,7 @@ require(["jquery", "avalon", "editor", "uploader", "bsAlert",
return "展开"; return "展开";
} }
}); });
}
var tagAutoCompleteList = []; var tagAutoCompleteList = [];

View File

@@ -96,7 +96,7 @@ require(["jquery", "avalon", "editor", "uploader", "bsAlert",
if (avalon.vmodels.editProblem) { if (avalon.vmodels.editProblem) {
var vm = avalon.vmodels.editProblem; var vm = avalon.vmodels.editProblem;
} }
else else {
var vm = avalon.define({ var vm = avalon.define({
$id: "editProblem", $id: "editProblem",
title: "", title: "",
@@ -142,6 +142,7 @@ require(["jquery", "avalon", "editor", "uploader", "bsAlert",
avalon.vmodels.admin.template_url = "template/problem/problem_list.html"; avalon.vmodels.admin.template_url = "template/problem/problem_list.html";
} }
}); });
}
$.ajax({ $.ajax({
url: "/api/admin/problem/?problem_id=" + avalon.vmodels.admin.problemId, url: "/api/admin/problem/?problem_id=" + avalon.vmodels.admin.problemId,

View File

@@ -1,30 +1,39 @@
define("spj", ["avalon"], function (avalon) { define("spj", ["avalon", "bsAlert"], function (avalon, bsAlert) {
avalon.component("ms:spj", { avalon.component("ms:spj", {
$template: '<div class="col-md-6">'+ $template: '<div class="col-md-6">' +
'<label>Special Judge</label>'+ '<label>Special Judge</label>' +
'<div class="form-group">'+ '<div class="form-group">' +
'<label class="text"><input type="checkbox" ms-duplex-checked="spj">'+ '<label class="text"><input type="checkbox" ms-duplex-checked="spj" ms-attr-disabled="checkboxDisabled">' +
'<small> Special Judge用于答案不唯一的情况,需要自己上传判题代码。'+ '<small> Special Judge用于答案不唯一的情况,需要自己上传判题代码。上传测试用后如需要修改, 必须重新上传对应类型的新测试用例。' +
'<a href="#" target="_blank">帮助和示例</a></small>'+ '<a href="#" target="_blank">帮助和示例</a></small>' +
'</label></div></div>'+ '</label></div></div>' +
'<div class="col-md-6" ms-if="spj">'+ '<div class="col-md-6" ms-if="spj">' +
'<label>SPJ代码语言</label>'+ '<label>SPJ代码语言</label>' +
'<div class="form-group">'+ '<div class="form-group">' +
'<label class="text">'+ '<label class="text">' +
'<input type="radio" name="spjLanguage" value="1" ms-duplex-string="spjLanguage"> C '+ '<input type="radio" name="spjLanguage" value="1" ms-duplex-string="spjLanguage"> C ' +
'<input type="radio" name="spjLanguage" value="2" ms-duplex-string="spjLanguage"> C++'+ '<input type="radio" name="spjLanguage" value="2" ms-duplex-string="spjLanguage"> C++' +
'</label>'+ '</label>' +
'</div>'+ '</div>' +
'</div>'+ '</div>' +
'<div class="col-md-12" ms-if="spj">'+ '<div class="col-md-12" ms-if="spj">' +
'<label>SPJ代码</label>'+ '<label>SPJ代码</label>' +
'<textarea class="form-control" rows="5" ms-duplex="spjCode"></textarea>'+ '<textarea class="form-control" rows="5" ms-duplex="spjCode"></textarea>' +
'</div>', '</div>',
spj: false, spj: false,
spjLanguage: 1, spjLanguage: 1,
spjCode: "", spjCode: "",
checkboxDisabled: false,
$init: function(vm, el) {
vm.$watch("testCaseUploadFinished", function (spj) {
console.log("watch" + spj);
vm.spj = spj;
vm.checkboxDisabled = true;
});
},
$ready: function (vm, el) { $ready: function (vm, el) {
el.msRetain = true; el.msRetain = true;
} }
}) })
}); });

View File

@@ -48,6 +48,8 @@ define("testCaseUploader", ["avalon", "uploader", "bsAlert", "jquery"], function
} }
vm.uploaded = true; vm.uploaded = true;
vm.uploadProgress = 100; vm.uploadProgress = 100;
console.log(data.data.spj);
vm.$fire("all!testCaseUploadFinished", data.data.spj);
} }
} }
}); });
@@ -72,7 +74,7 @@ define("testCaseUploader", ["avalon", "uploader", "bsAlert", "jquery"], function
output: response.data.file_list[key].output_name output: response.data.file_list[key].output_name
}) })
} }
bsAlert("测试数据添加成功!共添加" + vm.testCaseList.length + "组测试数据"); vm.$fire("all!testCaseUploadFinished", response.data.spj);
} }
}, },
function (file, percentage) { function (file, percentage) {