修复导入qdoj题目数据出错
This commit is contained in:
parent
bf6fdaae26
commit
30f6022403
|
@ -8,8 +8,8 @@
|
|||
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
|
||||
<outputRelativeToContentRoot value="true" />
|
||||
<module name="api" />
|
||||
<module name="DataBackup" />
|
||||
<module name="JudgeServer" />
|
||||
<module name="DataBackup" />
|
||||
</profile>
|
||||
</annotationProcessing>
|
||||
</component>
|
||||
|
|
|
@ -414,7 +414,7 @@ public class FileController {
|
|||
|
||||
@GetMapping("/download-contest-ac-submission")
|
||||
@RequiresAuthentication
|
||||
@RequiresRoles(value = {"root", "admin","problem_admin"}, logical = Logical.OR)
|
||||
@RequiresRoles(value = {"root", "admin", "problem_admin"}, logical = Logical.OR)
|
||||
public void downloadContestACSubmission(@RequestParam("cid") Long cid,
|
||||
@RequestParam(value = "excludeAdmin", defaultValue = "false") Boolean excludeAdmin,
|
||||
HttpServletRequest request,
|
||||
|
@ -427,7 +427,7 @@ public class FileController {
|
|||
UserRolesVo userRolesVo = (UserRolesVo) session.getAttribute("userInfo");
|
||||
boolean isRoot = SecurityUtils.getSubject().hasRole("root");
|
||||
// 除非是root 其它管理员只能下载自己的比赛ac记录
|
||||
if (!userRolesVo.getUid().equals(contest.getUid())&&!isRoot){
|
||||
if (!userRolesVo.getUid().equals(contest.getUid()) && !isRoot) {
|
||||
response.reset();
|
||||
response.setContentType("application/json");
|
||||
response.setCharacterEncoding("utf-8");
|
||||
|
@ -460,7 +460,7 @@ public class FileController {
|
|||
.isNotNull(!isACM, "score") // OI模式取得分不为null的
|
||||
.between("submit_time", contest.getStartTime(), contest.getEndTime())
|
||||
.ne(excludeAdmin, "uid", contest.getUid()) // 排除比赛创建者和root
|
||||
.ne(excludeAdmin, "username","root")
|
||||
.ne(excludeAdmin, "username", "root")
|
||||
.orderByDesc("submit_time");
|
||||
|
||||
List<Judge> judgeList = judgeService.list(judgeQueryWrapper);
|
||||
|
@ -645,7 +645,7 @@ public class FileController {
|
|||
@RequestMapping(value = "/upload-md-file", method = RequestMethod.POST)
|
||||
@RequiresAuthentication
|
||||
@ResponseBody
|
||||
@RequiresRoles(value = {"root", "admin","problem_admin"}, logical = Logical.OR)
|
||||
@RequiresRoles(value = {"root", "admin", "problem_admin"}, logical = Logical.OR)
|
||||
public CommonResult uploadMd(@RequestParam("file") MultipartFile file, HttpServletRequest request) {
|
||||
if (file == null) {
|
||||
return CommonResult.errorResponse("上传的文件不能为空!");
|
||||
|
@ -844,7 +844,6 @@ public class FileController {
|
|||
for (ProblemDto problemDto : problemDtos) {
|
||||
problemService.adminAddProblem(problemDto);
|
||||
}
|
||||
FileUtil.del(fileDir);
|
||||
return CommonResult.successResponse(null, "导入题目成功");
|
||||
}
|
||||
|
||||
|
@ -979,7 +978,6 @@ public class FileController {
|
|||
for (ProblemDto problemDto : problemDtos) {
|
||||
problemService.adminAddProblem(problemDto);
|
||||
}
|
||||
FileUtil.del(fileDir);
|
||||
return CommonResult.successResponse(null, "导入题目成功");
|
||||
}
|
||||
|
||||
|
@ -988,10 +986,17 @@ public class FileController {
|
|||
QDOJProblemDto qdojProblemDto = new QDOJProblemDto();
|
||||
List<String> tags = (List<String>) problemJson.get("tags");
|
||||
qdojProblemDto.setTags(tags.stream().map(UnicodeUtil::toString).collect(Collectors.toList()));
|
||||
qdojProblemDto.setLanguages(Arrays.asList("C", "C++", "Java", "Python3", "Python2", "Golang", "C#"));
|
||||
JSONObject spj = problemJson.getJSONObject("spj");
|
||||
qdojProblemDto.setIsSpj(spj != null);
|
||||
qdojProblemDto.setLanguages(Arrays.asList("C", "C With O2", "C++", "C++ With O2", "Java", "Python3", "Python2", "Golang", "C#"));
|
||||
Object spj = problemJson.getObj("spj");
|
||||
boolean isSpj = !JSONUtil.isNull(spj);
|
||||
qdojProblemDto.setIsSpj(isSpj);
|
||||
|
||||
Problem problem = new Problem();
|
||||
if (isSpj) {
|
||||
JSONObject spjJson = JSONUtil.parseObj(spj);
|
||||
problem.setSpjCode(spjJson.getStr("code"))
|
||||
.setSpjLanguage(spjJson.getStr("language"));
|
||||
}
|
||||
problem.setAuth(1)
|
||||
.setIsUploadCase(true)
|
||||
.setSource(problemJson.getStr("source", null))
|
||||
|
@ -1009,11 +1014,6 @@ public class FileController {
|
|||
.setTimeLimit(problemJson.getInt("time_limit"))
|
||||
.setMemoryLimit(problemJson.getInt("memory_limit"));
|
||||
|
||||
if (qdojProblemDto.getIsSpj() && spj != null) {
|
||||
problem.setSpjCode(spj.getStr("code"))
|
||||
.setSpjLanguage(spj.getStr("language"));
|
||||
}
|
||||
|
||||
JSONArray samples = problemJson.getJSONArray("samples");
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < samples.size(); i++) {
|
||||
|
|
|
@ -451,7 +451,7 @@ public class ProblemServiceImpl extends ServiceImpl<ProblemMapper, Problem> impl
|
|||
jsonObject.set("inputName", problemCase.getInput());
|
||||
jsonObject.set("outputName", problemCase.getOutput());
|
||||
// 读取输出文件
|
||||
FileReader readFile = new FileReader(testCasesDir + "/" + problemCase.getOutput(), CharsetUtil.UTF_8);
|
||||
FileReader readFile = new FileReader(testCasesDir + File.separator + problemCase.getOutput(), CharsetUtil.UTF_8);
|
||||
String output = readFile.readString().replaceAll("\r\n", "\n");
|
||||
|
||||
// spj是根据特判程序输出判断结果,所以无需初始化测试数据
|
||||
|
@ -485,6 +485,7 @@ public class ProblemServiceImpl extends ServiceImpl<ProblemMapper, Problem> impl
|
|||
List<ProblemCase> problemCaseList) {
|
||||
|
||||
JSONObject result = new JSONObject();
|
||||
System.out.println(isSpj);
|
||||
result.set("isSpj", isSpj);
|
||||
result.set("version", version);
|
||||
result.set("testCasesSize", problemCaseList.size());
|
||||
|
|
|
@ -55,7 +55,7 @@ public class JudgeStrategy {
|
|||
// 对用户源代码进行编译 获取tmpfs中的fileId
|
||||
userFileId = Compiler.compile(Constants.CompileConfig.getCompilerByLanguage(judge.getLanguage()), judge.getCode(), judge.getLanguage());
|
||||
// 测试数据文件所在文件夹
|
||||
String testCasesDir = Constants.JudgeDir.TEST_CASE_DIR.getContent() + "/problem_" + problem.getId();
|
||||
String testCasesDir = Constants.JudgeDir.TEST_CASE_DIR.getContent() +File.separator+"problem_" + problem.getId();
|
||||
// 从文件中加载测试数据json
|
||||
JSONObject testCasesInfo = problemTestCaseUtils.loadTestCaseInfo(problem.getId(), testCasesDir, problem.getCaseVersion(), !StringUtils.isEmpty(problem.getSpjCode()));
|
||||
JSONArray testcaseList = (JSONArray) testCasesInfo.get("testCases");
|
||||
|
|
|
@ -16,6 +16,7 @@ import top.hcode.hoj.pojo.entity.ProblemCase;
|
|||
import top.hcode.hoj.service.impl.ProblemCaseServiceImpl;
|
||||
import top.hcode.hoj.util.Constants;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
|
@ -32,7 +33,7 @@ public class ProblemTestCaseUtils {
|
|||
@Autowired
|
||||
ProblemCaseServiceImpl problemCaseService;
|
||||
|
||||
// 初始化测试数据,写成json文件
|
||||
// 本地无文件初始化测试数据,写成json文件
|
||||
public JSONObject initTestCase(List<HashMap<String, Object>> testCases,
|
||||
Long problemId,
|
||||
String version,
|
||||
|
@ -86,30 +87,77 @@ public class ProblemTestCaseUtils {
|
|||
((JSONArray) result.get("testCases")).put(index, jsonObject);
|
||||
}
|
||||
|
||||
FileWriter infoFile = new FileWriter(testCasesDir + "/info", CharsetUtil.UTF_8);
|
||||
FileWriter infoFile = new FileWriter(testCasesDir + File.separator + "info", CharsetUtil.UTF_8);
|
||||
// 写入记录文件
|
||||
infoFile.write(JSONUtil.toJsonStr(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
// 本地有文件,进行数据初始化 生成json文件
|
||||
public JSONObject initLocalTestCase(Boolean isSpj,
|
||||
String version,
|
||||
String testCasesDir,
|
||||
List<ProblemCase> problemCaseList) {
|
||||
|
||||
JSONObject result = new JSONObject();
|
||||
result.set("isSpj", isSpj);
|
||||
result.set("version", version);
|
||||
result.set("testCasesSize", problemCaseList.size());
|
||||
result.set("testCases", new JSONArray());
|
||||
|
||||
|
||||
for (ProblemCase problemCase : problemCaseList) {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.set("caseId", null);
|
||||
jsonObject.set("score", problemCase.getScore());
|
||||
jsonObject.set("inputName", problemCase.getInput());
|
||||
jsonObject.set("outputName", problemCase.getOutput());
|
||||
// 读取输出文件
|
||||
FileReader readFile = new FileReader(testCasesDir + File.separator + problemCase.getOutput(), CharsetUtil.UTF_8);
|
||||
String output = readFile.readString().replaceAll("\r\n", "\n");
|
||||
|
||||
// spj是根据特判程序输出判断结果,所以无需初始化测试数据
|
||||
if (!isSpj) {
|
||||
// 原数据MD5
|
||||
jsonObject.set("outputMd5", DigestUtils.md5DigestAsHex(output.getBytes()));
|
||||
// 原数据大小
|
||||
jsonObject.set("outputSize", output.getBytes().length);
|
||||
// 去掉全部空格的MD5,用来判断pe
|
||||
jsonObject.set("allStrippedOutputMd5", DigestUtils.md5DigestAsHex(output.replaceAll("\\s+", "").getBytes()));
|
||||
// 默认去掉文末空格的MD5
|
||||
jsonObject.set("EOFStrippedOutputMd5", DigestUtils.md5DigestAsHex(rtrim(output).getBytes()));
|
||||
}
|
||||
|
||||
((JSONArray) result.get("testCases")).put(jsonObject);
|
||||
}
|
||||
|
||||
FileWriter infoFile = new FileWriter(testCasesDir + File.separator + "info", CharsetUtil.UTF_8);
|
||||
// 写入记录文件
|
||||
infoFile.write(JSONUtil.toJsonStr(result));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
// 获取指定题目的info数据
|
||||
public JSONObject loadTestCaseInfo(Long problemId, String testCasesDir, String version, Boolean isSpj) throws SystemError, UnsupportedEncodingException {
|
||||
if (FileUtil.exist(testCasesDir + "/info")) {
|
||||
FileReader fileReader = new FileReader(testCasesDir + "/info", CharsetUtil.UTF_8);
|
||||
if (FileUtil.exist(testCasesDir + File.separator + "info")) {
|
||||
FileReader fileReader = new FileReader(testCasesDir + File.separator + "info", CharsetUtil.UTF_8);
|
||||
String infoStr = fileReader.readString();
|
||||
JSONObject testcaseInfo = JSONUtil.parseObj(infoStr);
|
||||
// 测试样例被改动需要重新生成
|
||||
if (!testcaseInfo.getStr("version", null).equals(version)) {
|
||||
return tryInitTestCaseInfo(problemId, version, isSpj);
|
||||
return tryInitTestCaseInfo(testCasesDir, problemId, version, isSpj);
|
||||
}
|
||||
return testcaseInfo;
|
||||
} else {
|
||||
return tryInitTestCaseInfo(problemId, version, isSpj);
|
||||
return tryInitTestCaseInfo(testCasesDir, problemId, version, isSpj);
|
||||
}
|
||||
}
|
||||
|
||||
// 若没有测试数据,则尝试从数据库获取并且初始化到本地,如果数据库中该题目测试数据为空,rsync同步也出了问题,则直接判系统错误
|
||||
public JSONObject tryInitTestCaseInfo(Long problemId, String version, Boolean isSpj) throws SystemError, UnsupportedEncodingException {
|
||||
public JSONObject tryInitTestCaseInfo(String testCasesDir, Long problemId, String version, Boolean isSpj) throws SystemError, UnsupportedEncodingException {
|
||||
|
||||
QueryWrapper<ProblemCase> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("pid", problemId);
|
||||
List<ProblemCase> problemCases = problemCaseService.list(queryWrapper);
|
||||
|
@ -117,23 +165,30 @@ public class ProblemTestCaseUtils {
|
|||
if (problemCases.size() == 0) { // 数据库也为空的话
|
||||
throw new SystemError("problemID:[" + problemId + "] test case has not found.", null, null);
|
||||
}
|
||||
// 可能zip上传记录的是文件名,这是也是说明文件丢失了
|
||||
|
||||
// 可能是zip上传记录的是文件名,
|
||||
if (problemCases.get(0).getInput().endsWith(".in") && (problemCases.get(0).getOutput().endsWith(".out") ||
|
||||
problemCases.get(0).getOutput().endsWith(".ans"))) {
|
||||
throw new SystemError("problemID:[" + problemId + "] test case has not found.", null, null);
|
||||
}
|
||||
|
||||
List<HashMap<String, Object>> testCases = new LinkedList<>();
|
||||
for (ProblemCase problemCase : problemCases) {
|
||||
HashMap<String, Object> tmp = new HashMap<>();
|
||||
tmp.put("input", problemCase.getInput());
|
||||
tmp.put("output", problemCase.getOutput());
|
||||
tmp.put("caseId", problemCase.getId());
|
||||
tmp.put("score", problemCase.getScore());
|
||||
testCases.add(tmp);
|
||||
}
|
||||
if (FileUtil.isEmpty(new File(testCasesDir))) { //如果本地对应文件夹也为空,说明文件丢失了
|
||||
throw new SystemError("problemID:[" + problemId + "] test case has not found.", null, null);
|
||||
} else {
|
||||
return initLocalTestCase(isSpj, version, testCasesDir, problemCases);
|
||||
}
|
||||
} else {
|
||||
|
||||
return initTestCase(testCases, problemId, version, isSpj);
|
||||
List<HashMap<String, Object>> testCases = new LinkedList<>();
|
||||
for (ProblemCase problemCase : problemCases) {
|
||||
HashMap<String, Object> tmp = new HashMap<>();
|
||||
tmp.put("input", problemCase.getInput());
|
||||
tmp.put("output", problemCase.getOutput());
|
||||
tmp.put("caseId", problemCase.getId());
|
||||
tmp.put("score", problemCase.getScore());
|
||||
testCases.add(tmp);
|
||||
}
|
||||
|
||||
return initTestCase(testCases, problemId, version, isSpj);
|
||||
}
|
||||
}
|
||||
|
||||
// 去除末尾的空白符
|
||||
|
|
Loading…
Reference in New Issue