Search in sources :

Example 1 with Tag

use of top.hcode.hoj.pojo.entity.problem.Tag in project HOJ by HimitZH.

the class ImportQDUOJController method importQDOJProblem.

/**
 * @param file
 * @MethodName importQDOJProblem
 * @Description zip文件导入题目 仅超级管理员可操作
 * @Return
 * @Since 2021/5/27
 */
@RequiresRoles("root")
@RequiresAuthentication
@ResponseBody
@Transactional(rollbackFor = Exception.class)
@PostMapping("/import-qdoj-problem")
public CommonResult importQDOJProblem(@RequestParam("file") MultipartFile file, HttpServletRequest request) {
    String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".") + 1);
    if (!"zip".toUpperCase().contains(suffix.toUpperCase())) {
        return CommonResult.errorResponse("请上传zip格式的题目文件压缩包!");
    }
    String fileDirId = IdUtil.simpleUUID();
    String fileDir = Constants.File.TESTCASE_TMP_FOLDER.getPath() + File.separator + fileDirId;
    String filePath = fileDir + File.separator + file.getOriginalFilename();
    // 文件夹不存在就新建
    FileUtil.mkdir(fileDir);
    try {
        file.transferTo(new File(filePath));
    } catch (IOException e) {
        FileUtil.del(fileDir);
        return CommonResult.errorResponse("服务器异常:qduoj题目上传失败!");
    }
    // 将压缩包压缩到指定文件夹
    ZipUtil.unzip(filePath, fileDir);
    // 删除zip文件
    FileUtil.del(filePath);
    // 检查文件是否存在
    File testCaseFileList = new File(fileDir);
    File[] files = testCaseFileList.listFiles();
    if (files == null || files.length == 0) {
        FileUtil.del(fileDir);
        return CommonResult.errorResponse("评测数据压缩包里文件不能为空!");
    }
    HashMap<String, File> problemInfo = new HashMap<>();
    for (File tmp : files) {
        if (tmp.isDirectory()) {
            File[] problemAndTestcase = tmp.listFiles();
            if (problemAndTestcase == null || problemAndTestcase.length == 0) {
                FileUtil.del(fileDir);
                return CommonResult.errorResponse("编号为:" + tmp.getName() + "的文件夹为空!");
            }
            for (File problemFile : problemAndTestcase) {
                if (problemFile.isFile()) {
                    // 检查文件是否时json文件
                    if (!problemFile.getName().endsWith("json")) {
                        FileUtil.del(fileDir);
                        return CommonResult.errorResponse("编号为:" + tmp.getName() + "的文件夹里面的题目数据格式错误,请使用json文件!");
                    }
                    problemInfo.put(tmp.getName(), problemFile);
                }
            }
        }
    }
    // 读取json文件生成对象
    HashMap<String, QDOJProblemDto> problemVoMap = new HashMap<>();
    for (String key : problemInfo.keySet()) {
        try {
            FileReader fileReader = new FileReader(problemInfo.get(key));
            JSONObject problemJson = JSONUtil.parseObj(fileReader.readString());
            QDOJProblemDto qdojProblemDto = QDOJProblemToProblemVo(problemJson);
            problemVoMap.put(key, qdojProblemDto);
        } catch (Exception e) {
            FileUtil.del(fileDir);
            return CommonResult.errorResponse("请检查编号为:" + key + "的题目json文件的格式:" + e.getLocalizedMessage());
        }
    }
    QueryWrapper<Language> languageQueryWrapper = new QueryWrapper<>();
    languageQueryWrapper.eq("oj", "ME");
    List<Language> languageList = languageService.list(languageQueryWrapper);
    HashMap<String, Long> languageMap = new HashMap<>();
    for (Language language : languageList) {
        languageMap.put(language.getName(), language.getId());
    }
    // 获取当前登录的用户
    HttpSession session = request.getSession();
    UserRolesVo userRolesVo = (UserRolesVo) session.getAttribute("userInfo");
    List<Tag> tagList = tagService.list(new QueryWrapper<Tag>().eq("oj", "ME"));
    HashMap<String, Tag> tagMap = new HashMap<>();
    for (Tag tag : tagList) {
        tagMap.put(tag.getName().toUpperCase(), tag);
    }
    List<ProblemDto> problemDtos = new LinkedList<>();
    for (String key : problemInfo.keySet()) {
        QDOJProblemDto qdojProblemDto = problemVoMap.get(key);
        // 格式化题目语言
        List<Language> languages = new LinkedList<>();
        for (String lang : qdojProblemDto.getLanguages()) {
            Long lid = languageMap.getOrDefault(lang, null);
            languages.add(new Language().setId(lid).setName(lang));
        }
        // 格式化标签
        List<Tag> tags = new LinkedList<>();
        for (String tagStr : qdojProblemDto.getTags()) {
            Tag tag = tagMap.getOrDefault(tagStr.toUpperCase(), null);
            if (tag == null) {
                tags.add(new Tag().setName(tagStr).setOj("ME"));
            } else {
                tags.add(tag);
            }
        }
        Problem problem = qdojProblemDto.getProblem();
        if (problem.getAuthor() == null) {
            problem.setAuthor(userRolesVo.getUsername());
        }
        ProblemDto problemDto = new ProblemDto();
        String mode = Constants.JudgeMode.DEFAULT.getMode();
        if (qdojProblemDto.getIsSpj()) {
            mode = Constants.JudgeMode.SPJ.getMode();
        }
        problemDto.setJudgeMode(mode).setProblem(problem).setCodeTemplates(qdojProblemDto.getCodeTemplates()).setTags(tags).setLanguages(languages).setUploadTestcaseDir(fileDir + File.separator + key + File.separator + "testcase").setIsUploadTestCase(true).setSamples(qdojProblemDto.getSamples());
        problemDtos.add(problemDto);
    }
    for (ProblemDto problemDto : problemDtos) {
        problemService.adminAddProblem(problemDto);
    }
    return CommonResult.successResponse(null, "导入题目成功");
}
Also used : HashMap(java.util.HashMap) Language(top.hcode.hoj.pojo.entity.problem.Language) UserRolesVo(top.hcode.hoj.pojo.vo.UserRolesVo) FileReader(cn.hutool.core.io.file.FileReader) QDOJProblemDto(top.hcode.hoj.pojo.dto.QDOJProblemDto) ProblemDto(top.hcode.hoj.pojo.dto.ProblemDto) QueryWrapper(com.baomidou.mybatisplus.core.conditions.query.QueryWrapper) HttpSession(javax.servlet.http.HttpSession) QDOJProblemDto(top.hcode.hoj.pojo.dto.QDOJProblemDto) IOException(java.io.IOException) IOException(java.io.IOException) LinkedList(java.util.LinkedList) JSONObject(cn.hutool.json.JSONObject) Problem(top.hcode.hoj.pojo.entity.problem.Problem) Tag(top.hcode.hoj.pojo.entity.problem.Tag) File(java.io.File) MultipartFile(org.springframework.web.multipart.MultipartFile) PostMapping(org.springframework.web.bind.annotation.PostMapping) RequiresAuthentication(org.apache.shiro.authz.annotation.RequiresAuthentication) RequiresRoles(org.apache.shiro.authz.annotation.RequiresRoles) ResponseBody(org.springframework.web.bind.annotation.ResponseBody) Transactional(org.springframework.transaction.annotation.Transactional)

Example 2 with Tag

use of top.hcode.hoj.pojo.entity.problem.Tag in project HOJ by HimitZH.

the class GroupProblemManager method addProblem.

public void addProblem(ProblemDto problemDto) throws StatusForbiddenException, StatusNotFoundException, StatusFailException {
    Session session = SecurityUtils.getSubject().getSession();
    UserRolesVo userRolesVo = (UserRolesVo) session.getAttribute("userInfo");
    boolean isRoot = SecurityUtils.getSubject().hasRole("root");
    Long gid = problemDto.getProblem().getGid();
    Group group = groupEntityService.getById(gid);
    if (group == null || group.getStatus() == 1 && !isRoot) {
        throw new StatusNotFoundException("该团队不存在或已被封禁!");
    }
    if (!isRoot && !groupValidator.isGroupAdmin(userRolesVo.getUid(), gid)) {
        throw new StatusForbiddenException("对不起,您无权限操作!");
    }
    problemDto.getProblem().setProblemId(group.getShortName() + problemDto.getProblem().getProblemId());
    QueryWrapper<Problem> problemQueryWrapper = new QueryWrapper<>();
    problemQueryWrapper.eq("problem_id", problemDto.getProblem().getProblemId().toUpperCase());
    int sameProblemIDCount = problemEntityService.count(problemQueryWrapper);
    if (sameProblemIDCount > 0) {
        throw new StatusFailException("该题目的Problem ID已存在,请更换!");
    }
    problemDto.getProblem().setIsGroup(true);
    List<Tag> tagList = new LinkedList<>();
    for (Tag tag : problemDto.getTags()) {
        if (tag.getGid() != null && tag.getGid().longValue() != gid) {
            throw new StatusForbiddenException("对不起,您无权限操作!");
        }
        if (tag.getId() == null) {
            tag.setGid(gid);
        }
        tagList.add(tag);
    }
    problemDto.setTags(tagList);
    boolean isOk = problemEntityService.adminAddProblem(problemDto);
    if (!isOk) {
        throw new StatusFailException("添加失败");
    }
}
Also used : Group(top.hcode.hoj.pojo.entity.group.Group) StatusForbiddenException(top.hcode.hoj.common.exception.StatusForbiddenException) QueryWrapper(com.baomidou.mybatisplus.core.conditions.query.QueryWrapper) StatusNotFoundException(top.hcode.hoj.common.exception.StatusNotFoundException) LinkedList(java.util.LinkedList) UserRolesVo(top.hcode.hoj.pojo.vo.UserRolesVo) Problem(top.hcode.hoj.pojo.entity.problem.Problem) StatusFailException(top.hcode.hoj.common.exception.StatusFailException) Tag(top.hcode.hoj.pojo.entity.problem.Tag) Session(org.apache.shiro.session.Session)

Example 3 with Tag

use of top.hcode.hoj.pojo.entity.problem.Tag in project HOJ by HimitZH.

the class GroupProblemManager method getAllProblemTagsList.

public List<Tag> getAllProblemTagsList(Long gid) throws StatusNotFoundException, StatusForbiddenException {
    Session session = SecurityUtils.getSubject().getSession();
    UserRolesVo userRolesVo = (UserRolesVo) session.getAttribute("userInfo");
    boolean isRoot = SecurityUtils.getSubject().hasRole("root");
    Group group = groupEntityService.getById(gid);
    if (group == null || group.getStatus() == 1 && !isRoot) {
        throw new StatusNotFoundException("该团队不存在或已被封禁!");
    }
    if (!isRoot && !groupValidator.isGroupAdmin(userRolesVo.getUid(), gid)) {
        throw new StatusForbiddenException("对不起,您无权限操作!");
    }
    List<Tag> tagList;
    QueryWrapper<Tag> tagQueryWrapper = new QueryWrapper<>();
    tagQueryWrapper.isNull("gid").or().eq("gid", gid);
    tagList = tagEntityService.list(tagQueryWrapper);
    return tagList;
}
Also used : Group(top.hcode.hoj.pojo.entity.group.Group) StatusForbiddenException(top.hcode.hoj.common.exception.StatusForbiddenException) QueryWrapper(com.baomidou.mybatisplus.core.conditions.query.QueryWrapper) UserRolesVo(top.hcode.hoj.pojo.vo.UserRolesVo) StatusNotFoundException(top.hcode.hoj.common.exception.StatusNotFoundException) Tag(top.hcode.hoj.pojo.entity.problem.Tag) Session(org.apache.shiro.session.Session)

Example 4 with Tag

use of top.hcode.hoj.pojo.entity.problem.Tag in project HOJ by HimitZH.

the class AdminTagController method addProblem.

@PostMapping("")
@RequiresAuthentication
@RequiresRoles(value = { "root", "problem_admin" }, logical = Logical.OR)
public CommonResult addProblem(@RequestBody Tag tag) {
    QueryWrapper<Tag> tagQueryWrapper = new QueryWrapper<>();
    tagQueryWrapper.eq("name", tag.getName()).eq("oj", tag.getOj());
    Tag existTag = tagService.getOne(tagQueryWrapper, false);
    if (existTag != null) {
        return CommonResult.errorResponse("该标签名称已存在!请勿重复添加!", CommonResult.STATUS_FAIL);
    }
    boolean result = tagService.save(tag);
    if (result) {
        // 添加成功
        return CommonResult.successResponse(tag, "添加成功!");
    } else {
        return CommonResult.errorResponse("添加失败", CommonResult.STATUS_FAIL);
    }
}
Also used : QueryWrapper(com.baomidou.mybatisplus.core.conditions.query.QueryWrapper) Tag(top.hcode.hoj.pojo.entity.problem.Tag) RequiresAuthentication(org.apache.shiro.authz.annotation.RequiresAuthentication) RequiresRoles(org.apache.shiro.authz.annotation.RequiresRoles)

Example 5 with Tag

use of top.hcode.hoj.pojo.entity.problem.Tag in project HOJ by HimitZH.

the class CFProblemStrategy method getProblemInfo.

@Override
public RemoteProblemInfo getProblemInfo(String problemId, String author) throws Exception {
    String contestId;
    String problemNum;
    if (NumberUtil.isInteger(problemId)) {
        contestId = ReUtil.get("([0-9]+)[0-9]{2}", problemId, 1);
        problemNum = ReUtil.get("[0-9]+([0-9]{2})", problemId, 1);
    } else {
        contestId = ReUtil.get("([0-9]+)[A-Z]{1}[0-9]{0,1}", problemId, 1);
        problemNum = ReUtil.get("[0-9]+([A-Z]{1}[0-9]{0,1})", problemId, 1);
    }
    if (contestId == null || problemNum == null) {
        throw new IllegalArgumentException("Codeforces: Incorrect problem id format!");
    }
    String html = HttpRequest.get(getProblemUrl(contestId, problemNum)).header("cookie", "RCPC=" + CodeForcesUtils.getRCPC()).timeout(20000).execute().body();
    // 重定向失效,更新RCPC
    if (html.contains("Redirecting... Please, wait.")) {
        List<String> list = ReUtil.findAll("[a-z0-9]+[a-z0-9]{31}", html, 0, new ArrayList<>());
        CodeForcesUtils.updateRCPC(list);
        html = HttpRequest.get(getProblemUrl(contestId, problemNum)).header("cookie", "RCPC=" + CodeForcesUtils.getRCPC()).timeout(20000).execute().body();
    }
    Problem info = new Problem();
    info.setProblemId(getJudgeName() + "-" + problemId);
    info.setTitle(ReUtil.get("<div class=\"title\">\\s*" + problemNum + "\\. ([\\s\\S]*?)</div>", html, 1).trim());
    String timeLimitStr = ReUtil.get("</div>\\s*([\\d\\.]+) (seconds?|s)\\s*</div>", html, 1);
    if (StringUtils.isEmpty(timeLimitStr)) {
        timeLimitStr = ReUtil.get("</div>\\s*<span .*?>(\\d+) (seconds?|s)\\s*</span>\\s*</div>", html, 1);
    }
    double timeLimit = 1000 * Double.parseDouble(timeLimitStr);
    info.setTimeLimit((int) timeLimit);
    String memoryLimitStr = ReUtil.get("</div>\\s*(\\d+) (megabytes|MB)\\s*</div>", html, 1);
    if (StringUtils.isEmpty(memoryLimitStr)) {
        memoryLimitStr = ReUtil.get("</div>\\s*<span .*?>(\\d+) (megabytes|MB)\\s*</span>\\s*</div>", html, 1);
    }
    info.setMemoryLimit(Integer.parseInt(memoryLimitStr));
    String tmpDesc = ReUtil.get("standard output\\s*</div>\\s*</div>\\s*<div>([\\s\\S]*?)</div>\\s*<div class=\"input-specification", html, 1);
    if (StringUtils.isEmpty(tmpDesc)) {
        tmpDesc = ReUtil.get("<div class=\"input-file\">([\\s\\S]*?)</div><div class=\"input-specification", html, 1);
    }
    if (StringUtils.isEmpty(tmpDesc)) {
        // 交互题
        tmpDesc = ReUtil.get("standard output\\s*</div>\\s*</div>\\s*<div>([\\s\\S]*?)</div>\\s*<div>\\s*<div class=\"section-title", html, 1);
    }
    if (StringUtils.isEmpty(tmpDesc)) {
        // 单单只有题面描述
        tmpDesc = ReUtil.get("standard output\\s*</div>\\s*</div>\\s*<div>([\\s\\S]*?)</div>", html, 1);
    }
    if (!StringUtils.isEmpty(tmpDesc)) {
        tmpDesc = tmpDesc.replaceAll("\\$\\$\\$", "\\$").replaceAll("src=\"../../", "src=\"" + HOST + "/").trim();
    }
    info.setDescription(tmpDesc);
    String inputDesc = ReUtil.get("<div class=\"section-title\">\\s*Input\\s*</div>([\\s\\S]*?)</div>\\s*<div class=\"output-specification\">", html, 1);
    if (StringUtils.isEmpty(inputDesc)) {
        inputDesc = ReUtil.get("<div class=\"section-title\">\\s*Interaction\\s*</div>([\\s\\S]*?)</div>\\s*<div class=\"sample-tests\">", html, 1);
    }
    if (StringUtils.isEmpty(inputDesc)) {
        inputDesc = ReUtil.get("<div class=\"input-specification\">\\s*<div class=\"section-title\">\\s*Input\\s*</div>([\\s\\S]*?)</div>", html, 1);
    }
    if (!StringUtils.isEmpty(inputDesc)) {
        inputDesc = inputDesc.replaceAll("\\$\\$\\$", "\\$").trim();
    }
    info.setInput(inputDesc);
    String outputDesc = ReUtil.get("<div class=\"section-title\">\\s*Output\\s*</div>([\\s\\S]*?)</div>\\s*<div class=\"sample-tests\">", html, 1);
    if (!StringUtils.isEmpty(outputDesc)) {
        outputDesc = outputDesc.replaceAll("\\$\\$\\$", "\\$").trim();
    }
    info.setOutput(outputDesc);
    List<String> inputExampleList = ReUtil.findAll(Pattern.compile("<div class=\"input\">\\s*<div class=\"title\">\\s*Input\\s*</div>\\s*<pre>([\\s\\S]*?)</pre>\\s*</div>"), html, 1);
    List<String> outputExampleList = ReUtil.findAll(Pattern.compile("<div class=\"output\">\\s*<div class=\"title\">\\s*Output\\s*</div>\\s*<pre>([\\s\\S]*?)</pre>\\s*</div>"), html, 1);
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < inputExampleList.size() && i < outputExampleList.size(); i++) {
        sb.append("<input>");
        String input = inputExampleList.get(i).replaceAll("<br>", "\n").replaceAll("<br />", "\n").trim();
        sb.append(HtmlUtil.unescape(input)).append("</input>");
        sb.append("<output>");
        String output = outputExampleList.get(i).replaceAll("<br>", "\n").replaceAll("<br />", "\n").trim();
        sb.append(HtmlUtil.unescape(output)).append("</output>");
    }
    info.setExamples(sb.toString());
    String tmpHint = ReUtil.get("<div class=\"section-title\">\\s*Note\\s*</div>([\\s\\S]*?)</div>\\s*</div>", html, 1);
    if (tmpHint != null) {
        info.setHint(tmpHint.replaceAll("\\$\\$\\$", "\\$").trim());
    }
    info.setIsRemote(true);
    info.setSource(getProblemSource(html, problemId, contestId, problemNum));
    info.setType(0).setAuth(1).setAuthor(author).setOpenCaseResult(true).setIsRemoveEndBlank(false).setIsGroup(false).setDifficulty(// 默认为中等
    1);
    List<String> allTags = ReUtil.findAll(Pattern.compile("<span class=\"tag-box\" style=\"font-size:1\\.2rem;\" title=\"[\\s\\S]*?\">([\\s\\S]*?)</span>"), html, 1);
    List<Tag> tagList = new LinkedList<>();
    for (String tmp : allTags) {
        tagList.add(new Tag().setName(tmp.trim()));
    }
    return new RemoteProblemInfo().setProblem(info).setTagList(tagList).setRemoteOJ(Constants.RemoteOJ.CODEFORCES);
}
Also used : Problem(top.hcode.hoj.pojo.entity.problem.Problem) Tag(top.hcode.hoj.pojo.entity.problem.Tag) LinkedList(java.util.LinkedList)

Aggregations

Tag (top.hcode.hoj.pojo.entity.problem.Tag)10 QueryWrapper (com.baomidou.mybatisplus.core.conditions.query.QueryWrapper)8 Problem (top.hcode.hoj.pojo.entity.problem.Problem)7 UserRolesVo (top.hcode.hoj.pojo.vo.UserRolesVo)6 LinkedList (java.util.LinkedList)5 Session (org.apache.shiro.session.Session)5 StatusFailException (top.hcode.hoj.common.exception.StatusFailException)5 StatusForbiddenException (top.hcode.hoj.common.exception.StatusForbiddenException)4 StatusNotFoundException (top.hcode.hoj.common.exception.StatusNotFoundException)4 Group (top.hcode.hoj.pojo.entity.group.Group)4 FileReader (cn.hutool.core.io.file.FileReader)2 JSONObject (cn.hutool.json.JSONObject)2 File (java.io.File)2 IOException (java.io.IOException)2 HashMap (java.util.HashMap)2 RequiresAuthentication (org.apache.shiro.authz.annotation.RequiresAuthentication)2 RequiresRoles (org.apache.shiro.authz.annotation.RequiresRoles)2 Transactional (org.springframework.transaction.annotation.Transactional)2 MultipartFile (org.springframework.web.multipart.MultipartFile)2 ProblemDto (top.hcode.hoj.pojo.dto.ProblemDto)2