diff --git a/README.md b/README.md index 2698f015..3c8a53d0 100644 --- a/README.md +++ b/README.md @@ -81,6 +81,7 @@ | 2021-02-20 | 测试HDU判题整套流程完成 | Himit_ZH | | 2021-02-22 | 修改前端编辑器样式以及md格式转换 | Himit_ZH | | 2021-02-24 | 完善测试比赛相关接口,验证权限及数据计算 | Himit_ZH | +| 2021-03-03 | 增加Codeforces的题目爬取 | Himit_ZH | # 二、系统架构 diff --git a/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/controller/admin/AdminProblemController.java b/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/controller/admin/AdminProblemController.java index 70686fe1..c39d2309 100644 --- a/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/controller/admin/AdminProblemController.java +++ b/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/controller/admin/AdminProblemController.java @@ -13,6 +13,7 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.*; import top.hcode.hoj.common.result.CommonResult; +import top.hcode.hoj.crawler.problem.ProblemStrategy; import top.hcode.hoj.pojo.dto.ProblemDto; import top.hcode.hoj.pojo.entity.*; import top.hcode.hoj.pojo.vo.UserRolesVo; @@ -41,9 +42,6 @@ public class AdminProblemController { @Autowired private ProblemCaseServiceImpl problemCaseService; - @Autowired - private ContestProblemServiceImpl contestProblemService; - @Autowired private ToJudgeService toJudgeService; @@ -186,6 +184,7 @@ public class AdminProblemController { @GetMapping("/import-remote-oj-problem") @RequiresAuthentication @RequiresRoles(value = {"root", "admin"}, logical = Logical.OR) + @Transactional public CommonResult importRemoteOJProblem(@RequestParam("name") String name, @RequestParam("problemId") String problemId, HttpServletRequest request) { @@ -200,14 +199,14 @@ public class AdminProblemController { HttpSession session = request.getSession(); UserRolesVo userRolesVo = (UserRolesVo) session.getAttribute("userInfo"); try { - Problem otherOJProblemInfo = problemService.getOtherOJProblemInfo(name.toUpperCase(), problemId, userRolesVo.getUsername()); + ProblemStrategy.RemoteProblemInfo otherOJProblemInfo = problemService.getOtherOJProblemInfo(name.toUpperCase(), problemId, userRolesVo.getUsername()); if (otherOJProblemInfo != null) { boolean result = problemService.adminAddOtherOJProblem(otherOJProblemInfo, name); if (!result) { return CommonResult.errorResponse("导入新题目失败!请重新尝试!"); } } else { - return CommonResult.errorResponse("导入新题目失败!原因:获取该OJ的题目数据失败!"); + return CommonResult.errorResponse("导入新题目失败!原因:获取该OJ的题目数据失败!可能是链接超时!"); } } catch (Exception e) { return CommonResult.errorResponse(e.getMessage()); diff --git a/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/controller/oj/ContestController.java b/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/controller/oj/ContestController.java index fac9bf95..fa5687d0 100644 --- a/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/controller/oj/ContestController.java +++ b/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/controller/oj/ContestController.java @@ -253,21 +253,27 @@ public class ContestController { } //查询题目详情,题目标签,题目语言,题目做题情况 + Problem problem = problemService.getById(contestProblem.getPid()); - QueryWrapper problemTagQueryWrapper = new QueryWrapper<>(); - problemTagQueryWrapper.eq("pid", contestProblem.getPid()); - // 获取该题号对应的标签id - List tidList = new LinkedList<>(); - problemTagService.list(problemTagQueryWrapper).forEach(problemTag -> { - tidList.add(problemTag.getTid()); - }); List tagsStr = new LinkedList<>(); - if (tidList.size() != 0) { - tagService.listByIds(tidList).forEach(tag -> { - tagsStr.add(tag.getName()); + // 比赛结束后才开放标签和source + if (contest.getStatus().intValue() != Constants.Contest.STATUS_ENDED.getCode()) { + problem.setSource(null); + QueryWrapper problemTagQueryWrapper = new QueryWrapper<>(); + problemTagQueryWrapper.eq("pid", contestProblem.getPid()); + // 获取该题号对应的标签id + List tidList = new LinkedList<>(); + problemTagService.list(problemTagQueryWrapper).forEach(problemTag -> { + tidList.add(problemTag.getTid()); }); + if (tidList.size() != 0) { + tagService.listByIds(tidList).forEach(tag -> { + tagsStr.add(tag.getName()); + }); + } } + // 获取题目提交的代码支持的语言 List languagesStr = new LinkedList<>(); QueryWrapper problemLanguageQueryWrapper = new QueryWrapper<>(); diff --git a/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/crawler/problem/CFProblemStrategy.java b/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/crawler/problem/CFProblemStrategy.java new file mode 100644 index 00000000..b5c31fa7 --- /dev/null +++ b/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/crawler/problem/CFProblemStrategy.java @@ -0,0 +1,92 @@ +package top.hcode.hoj.crawler.problem; + +import cn.hutool.core.util.ReUtil; +import org.jsoup.Connection; +import org.jsoup.nodes.Document; +import org.springframework.util.StringUtils; +import top.hcode.hoj.pojo.entity.Problem; +import top.hcode.hoj.pojo.entity.Tag; +import top.hcode.hoj.utils.JsoupUtils; + +import java.util.LinkedList; +import java.util.List; +import java.util.regex.Pattern; + +/** + * @Author: Himit_ZH + * @Date: 2021/3/3 15:00 + * @Description: + */ +public class CFProblemStrategy extends ProblemStrategy { + + public static final String JUDGE_NAME = "CF"; + public static final String HOST = "https://codeforces.com"; + public static final String PROBLEM_URL = "/problemset/problem/%s/%s"; + + @Override + public RemoteProblemInfo getProblemInfo(String problemId, String author) throws Exception { + + String contestId = ReUtil.get("([0-9]+)[A-Z]{1}[0-9]{0,1}", problemId, 1); + String problemNum = ReUtil.get("[0-9]+([A-Z]{1}[0-9]{0,1})", problemId, 1); + if (contestId == null || problemNum == null) { + throw new Exception("Codeforces的题号格式错误!"); + } + + String url = HOST + String.format(PROBLEM_URL, contestId, problemNum); + Connection connection = JsoupUtils.getConnectionFromUrl(url, null, null); + Document document = JsoupUtils.getDocument(connection, null); + String html = document.html(); + + + Problem info = new Problem(); + info.setProblemId(JUDGE_NAME + "-" + problemId); + + info.setTitle(ReUtil.get("
\\s*" + problemNum + "\\. ([\\s\\S]*?)
", html, 1).trim()); + + info.setTimeLimit(1000 * Integer.parseInt(ReUtil.get("([\\d\\.]+) (seconds?|s)\\s*", html, 1))); + + info.setMemoryLimit(Integer.parseInt(ReUtil.get("(\\d+) (megabytes|MB)\\s*", html, 1))); + + String tmpDesc = ReUtil.get("standard output\\s*
([\\s\\S]*?)
([\\s\\S]*?)
\\s*Input\\s*
([\\s\\S]*?)
", html, 1).replaceAll("\\$\\$\\$","\\$")); + + info.setOutput(ReUtil.get("
\\s*Output\\s*
([\\s\\S]*?)
", html, 1).replaceAll("\\$\\$\\$","\\$")); + + StringBuilder sb = new StringBuilder(""); + sb.append(ReUtil.get("
Input
([\\s\\S]*?)
", html, 1)); + sb.append(""); + sb.append(ReUtil.get("
Output
([\\s\\S]*?)
", html, 1)).append(""); + info.setExamples(sb.toString()); + + info.setHint(ReUtil.get("
\\s*Note\\s*
([\\s\\S]*?)
", html, 1).replaceAll("\\$\\$\\$","\\$")); + info.setIsRemote(true); + info.setSource(String.format("

Problem:%s

" + + "Contest:" + ReUtil.get("(]+/contest/\\d+\">.+?)", html, 1).replace("/contest", HOST + "/contest") + .replace("color: black", "color: #009688;") + "

", + contestId, problemNum, JUDGE_NAME + "-" + problemId)); + + info.setType(0) + .setAuth(1) + .setAuthor(author) + .setOpenCaseResult(false) + .setIsRemoveEndBlank(false) + .setDifficulty(1); // 默认为中等 + + List all = ReUtil.findAll(Pattern.compile("([\\s\\S]*?)"), html, 1); + + List tagList = new LinkedList<>(); + for (String tmp:all){ + tagList.add(new Tag().setName(tmp.trim())); + } + return new RemoteProblemInfo().setProblem(info).setTagList(tagList); + } + + +} \ No newline at end of file diff --git a/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/crawler/problem/HDUProblemStrategy.java b/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/crawler/problem/HDUProblemStrategy.java index 2eab7812..82bb8384 100644 --- a/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/crawler/problem/HDUProblemStrategy.java +++ b/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/crawler/problem/HDUProblemStrategy.java @@ -4,6 +4,7 @@ import cn.hutool.core.util.ReUtil; import org.jsoup.Connection; import org.jsoup.helper.Validate; import org.jsoup.nodes.Document; +import org.springframework.util.Assert; import top.hcode.hoj.pojo.entity.Problem; import top.hcode.hoj.utils.JsoupUtils; @@ -24,9 +25,9 @@ public class HDUProblemStrategy extends ProblemStrategy { * @throws Exception */ @Override - public Problem getProblemInfo(String problemId, String author) throws Exception { + public RemoteProblemInfo getProblemInfo(String problemId, String author) throws Exception { // 验证题号是否符合规范 - Validate.isTrue(problemId.matches("[1-9]\\d*")); + Assert.isTrue(problemId.matches("[1-9]\\d*"),"HDU题号格式错误!"); Problem info = new Problem(); String url = HOST + String.format(PROBLEM_URL, problemId); Connection connection = JsoupUtils.getConnectionFromUrl(url, null, null); @@ -52,7 +53,8 @@ public class HDUProblemStrategy extends ProblemStrategy { .setAuthor(author) .setOpenCaseResult(false) .setIsRemoveEndBlank(false) - .setDifficulty(0); // 默认为简单 - return info; + .setDifficulty(1); // 默认为简单 + + return new RemoteProblemInfo().setProblem(info).setTagList(null); } } \ No newline at end of file diff --git a/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/crawler/problem/ProblemContext.java b/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/crawler/problem/ProblemContext.java index 1623b9d5..49f4bfce 100644 --- a/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/crawler/problem/ProblemContext.java +++ b/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/crawler/problem/ProblemContext.java @@ -18,11 +18,10 @@ public class ProblemContext { } //上下文接口 - public Problem getProblemInfo(String problemId, String author) { - Problem problem; + public ProblemStrategy.RemoteProblemInfo getProblemInfo(String problemId, String author) { + try { - problem = problemStrategy.getProblemInfo(problemId, author); - return problem; + return problemStrategy.getProblemInfo(problemId, author); } catch (Exception e) { log.error("获取题目详情失败---------------->{}", e.getMessage()); } diff --git a/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/crawler/problem/ProblemStrategy.java b/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/crawler/problem/ProblemStrategy.java index e8c6a288..8954cfbc 100644 --- a/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/crawler/problem/ProblemStrategy.java +++ b/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/crawler/problem/ProblemStrategy.java @@ -1,8 +1,21 @@ package top.hcode.hoj.crawler.problem; +import lombok.Data; +import lombok.experimental.Accessors; import top.hcode.hoj.pojo.entity.Problem; +import top.hcode.hoj.pojo.entity.Tag; + +import java.util.List; public abstract class ProblemStrategy { - public abstract Problem getProblemInfo(String problemId,String author) throws Exception; + public abstract RemoteProblemInfo getProblemInfo(String problemId,String author) throws Exception; + + @Data + @Accessors(chain = true) + public static + class RemoteProblemInfo { + private Problem problem; + private List tagList; + } } diff --git a/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/service/ProblemService.java b/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/service/ProblemService.java index f4af491e..c8630ee6 100644 --- a/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/service/ProblemService.java +++ b/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/service/ProblemService.java @@ -1,6 +1,7 @@ package top.hcode.hoj.service; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import top.hcode.hoj.crawler.problem.ProblemStrategy; import top.hcode.hoj.pojo.dto.ProblemDto; import top.hcode.hoj.pojo.vo.ProblemVo; import top.hcode.hoj.pojo.entity.Problem; @@ -25,7 +26,7 @@ public interface ProblemService extends IService { boolean adminAddProblem(ProblemDto problemDto); - Problem getOtherOJProblemInfo(String OJName, String problemId, String author) throws Exception; + ProblemStrategy.RemoteProblemInfo getOtherOJProblemInfo(String OJName, String problemId, String author) throws Exception; - boolean adminAddOtherOJProblem(Problem problem,String OJName); + boolean adminAddOtherOJProblem(ProblemStrategy.RemoteProblemInfo remoteProblemInfo,String OJName); } diff --git a/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/service/impl/ProblemServiceImpl.java b/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/service/impl/ProblemServiceImpl.java index 43f71825..d9e80d0d 100644 --- a/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/service/impl/ProblemServiceImpl.java +++ b/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/service/impl/ProblemServiceImpl.java @@ -9,6 +9,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.StringUtils; import top.hcode.hoj.common.result.CommonResult; +import top.hcode.hoj.crawler.problem.CFProblemStrategy; import top.hcode.hoj.crawler.problem.HDUProblemStrategy; import top.hcode.hoj.crawler.problem.ProblemContext; import top.hcode.hoj.crawler.problem.ProblemStrategy; @@ -377,7 +378,7 @@ public class ProblemServiceImpl extends ServiceImpl impl } @Override - public Problem getOtherOJProblemInfo(String OJName, String problemId, String author) throws Exception { + public ProblemStrategy.RemoteProblemInfo getOtherOJProblemInfo(String OJName, String problemId, String author) throws Exception { ProblemStrategy problemStrategy; @@ -385,6 +386,9 @@ public class ProblemServiceImpl extends ServiceImpl impl case "HDU": problemStrategy = new HDUProblemStrategy(); break; + case "CF": + problemStrategy = new CFProblemStrategy(); + break; default: throw new Exception("未知的OJ的名字,暂时不支持!"); } @@ -394,7 +398,10 @@ public class ProblemServiceImpl extends ServiceImpl impl } @Override - public boolean adminAddOtherOJProblem(Problem problem, String OJName) { + @Transactional + public boolean adminAddOtherOJProblem(ProblemStrategy.RemoteProblemInfo remoteProblemInfo, String OJName) { + + Problem problem = remoteProblemInfo.getProblem(); boolean addProblemResult = problemMapper.insert(problem) == 1; // 为新的其它oj题目添加对应的language QueryWrapper languageQueryWrapper = new QueryWrapper<>(); @@ -410,16 +417,32 @@ public class ProblemServiceImpl extends ServiceImpl impl // 为新的题目初始化problem_count表 boolean initProblemCountResult = problemCountService.save(new ProblemCount().setPid(problem.getId())); - QueryWrapper tagQueryWrapper = new QueryWrapper<>(); - tagQueryWrapper.eq("name", OJName); - Tag OJNameTag = tagService.getOne(tagQueryWrapper, false); - if (OJNameTag == null) { - OJNameTag = new Tag(); - OJNameTag.setName(OJName); - tagService.saveOrUpdate(OJNameTag); + boolean addProblemTagResult = true; + List addTagList = remoteProblemInfo.getTagList(); + if (addTagList != null && addTagList.size() > 0) { + List tagList = tagService.list(); + // 已存在的tag不进行添加 + for (Tag hasTag:tagList){ + addTagList.removeIf(newTag -> newTag.getName().equals(hasTag.getName())); + } + tagService.saveOrUpdateBatch(addTagList); + List problemTagList = new LinkedList<>(); + for (Tag tmp : remoteProblemInfo.getTagList()) { + problemTagList.add(new ProblemTag().setTid(tmp.getId()).setPid(problem.getId())); + } + addProblemTagResult = problemTagService.saveOrUpdateBatch(problemTagList); + } else { + QueryWrapper tagQueryWrapper = new QueryWrapper<>(); + tagQueryWrapper.eq("name", OJName); + Tag OJNameTag = tagService.getOne(tagQueryWrapper, false); + if (OJNameTag == null) { + OJNameTag = new Tag(); + OJNameTag.setName(OJName); + tagService.saveOrUpdate(OJNameTag); + } + addProblemTagResult = problemTagService.saveOrUpdate(new ProblemTag().setTid(OJNameTag.getId()) + .setPid(problem.getId())); } - boolean addProblemTagResult = problemTagService.saveOrUpdate(new ProblemTag().setTid(OJNameTag.getId()) - .setPid(problem.getId())); return addProblemResult && addProblemTagResult && addProblemLanguageResult && initProblemCountResult; } diff --git a/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/utils/JsoupUtils.java b/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/utils/JsoupUtils.java index ed4dc68b..bb03a45c 100644 --- a/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/utils/JsoupUtils.java +++ b/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/utils/JsoupUtils.java @@ -36,8 +36,8 @@ public class JsoupUtils { Connection connection = Jsoup.connect(url); // 设置用户代理 connection.userAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36"); - // 设置超时时间10秒 - connection.timeout(10000); + // 设置超时时间15秒 + connection.timeout(15000); // 设置请求头 if (headers != null) { connection.headers(headers); diff --git a/hoj-springboot/DataBackup/src/test/java/top/hcode/hoj/DataBackupApplicationTests.java b/hoj-springboot/DataBackup/src/test/java/top/hcode/hoj/DataBackupApplicationTests.java index 9ae020a7..7b06cac0 100644 --- a/hoj-springboot/DataBackup/src/test/java/top/hcode/hoj/DataBackupApplicationTests.java +++ b/hoj-springboot/DataBackup/src/test/java/top/hcode/hoj/DataBackupApplicationTests.java @@ -23,6 +23,7 @@ import org.jsoup.nodes.Document; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.util.StringUtils; import org.springframework.web.client.RestTemplate; import top.hcode.hoj.common.result.CommonResult; import top.hcode.hoj.dao.*; @@ -34,6 +35,7 @@ import top.hcode.hoj.pojo.vo.UserRolesVo; import top.hcode.hoj.service.UserInfoService; import top.hcode.hoj.service.UserRoleService; import top.hcode.hoj.service.impl.AnnouncementServiceImpl; +import top.hcode.hoj.service.impl.LanguageServiceImpl; import top.hcode.hoj.service.impl.UserInfoServiceImpl; import top.hcode.hoj.service.impl.UserRoleServiceImpl; import top.hcode.hoj.utils.Constants; @@ -45,6 +47,7 @@ import java.io.IOException; import java.net.*; import java.text.MessageFormat; import java.util.*; +import java.util.regex.Pattern; /** * @Author: Himit_ZH @@ -199,5 +202,106 @@ public class DataBackupApplicationTests { System.out.println(info.getOutput()); } + @Test + public void Test7() throws IOException { + String JUDGE_NAME = "CF"; + String HOST = "https://codeforces.com"; + String PROBLEM_URL = "/problemset/problem/%s/%s"; + + String problemId = "1491F"; + String contestId = ReUtil.get("([0-9]+)[A-Z]{1}[0-9]{0,1}", problemId, 1); + String problemNum = ReUtil.get("[0-9]+([A-Z]{1}[0-9]{0,1})", problemId, 1); + + + String url = HOST + String.format(PROBLEM_URL, contestId, problemNum); + Connection connection = JsoupUtils.getConnectionFromUrl(url, null, null); + Document document = JsoupUtils.getDocument(connection, null); + String html = document.html(); + Problem info = new Problem(); + info.setProblemId(JUDGE_NAME + "-" + problemId); + + info.setTitle(ReUtil.get("
\\s*" + problemNum + "\\. ([\\s\\S]*?)
", html, 1).trim()); + + info.setTimeLimit(1000 * Integer.parseInt(ReUtil.get("([\\d\\.]+) (seconds?|s)\\s*", html, 1))); + + info.setMemoryLimit(Integer.parseInt(ReUtil.get("(\\d+) (megabytes|MB)\\s*", html, 1))); + + String tmpDesc = ReUtil.get("standard output\\s*
([\\s\\S]*?)
[\\s\\S]*?)
\\s*Input\\s*
([\\s\\S]*?)
", html, 1)); + + info.setOutput(ReUtil.get("
\\s*Output\\s*
([\\s\\S]*?)
", html, 1)); + + StringBuilder sb = new StringBuilder(""); + sb.append(ReUtil.get("
Input
([\\s\\S]*?)
", html, 1)); + sb.append(""); + sb.append(ReUtil.get("
Output
([\\s\\S]*?)
", html, 1)).append(""); + info.setExamples(sb.toString()); + + info.setHint(ReUtil.get("
\\s*Note\\s*
([\\s\\S]*?)
", html, 1)); + info.setIsRemote(true); + info.setSource(String.format("

Problem:%s

" + + "Contest:" + ReUtil.get("(]+/contest/\\d+\">.+?)", html, 1).replace("/contest", HOST + "/contest") + .replace("color: black", "color: #009688;") + "

", + contestId, problemNum, JUDGE_NAME + "-" + problemId)); + + List all = ReUtil.findAll(Pattern.compile("([\\s\\S]*?)"), html, 1); + for (String tmp : all) { + System.out.println(tmp.trim()); + } + } + + + @Autowired + private LanguageServiceImpl languageService; + + @Test + public void Test8() throws IOException { + LinkedHashMap languageList = new LinkedHashMap<>(); + languageList.put("GNU GCC C11 5.1.0", "text/x-csrc"); + languageList.put("Clang++17 Diagnostics", "text/x-c++src"); + languageList.put("GNU G++11 5.1.0", "text/x-c++src"); + languageList.put("GNU G++14 6.4.0", "text/x-c++src"); + languageList.put("GNU G++17 7.3.0", "text/x-c++src"); + languageList.put("Microsoft Visual C++ 2010", "text/x-c++src"); + languageList.put("Microsoft Visual C++ 2017", "text/x-c++src"); + languageList.put("C# Mono 5.18", "text/x-csharp"); + languageList.put("D DMD32 v2.083.1", "text/x-d"); + languageList.put("Go 1.11.4", "text/x-go"); + languageList.put("Haskell GHC 8.6.3", "text/x-haskell"); + languageList.put("Java 1.8.0_162", "text/x-java"); + languageList.put("Kotlin 1.3.10", "text/x-java"); + languageList.put("OCaml 4.02.1", "text/x-ocaml"); + languageList.put("Delphi 7", "text/x-pascal"); + languageList.put("Free Pascal 3.0.2", "text/x-pascal"); + languageList.put("PascalABC.NET 3.4.2", "text/x-pascal"); + languageList.put("Perl 5.20.1", "text/x-perl"); + languageList.put("PHP 7.2.13", "text/x-php"); + languageList.put("Python 2.7.15", "text/x-python"); + languageList.put("Python 3.7.2", "text/x-python"); + languageList.put("PyPy 2.7 (6.0.0)", "text/x-python"); + languageList.put("PyPy 3.5 (6.0.0)", "text/x-python"); + languageList.put("Ruby 2.0.0p645", "text/x-ruby"); + languageList.put("Rust 1.31.1", "text/x-rustsrc"); + languageList.put("Scala 2.12.8", "text/x-scala"); + languageList.put("JavaScript V8 4.8.0", "text/javascript"); + languageList.put("Node.js 9.4.0", "text/javascript"); + + List languageList1 = new LinkedList<>(); + for (String key : languageList.keySet()) { + String tmp = languageList.get(key); + languageList1.add(new Language().setName(key).setDescription(key).setOj("CF").setIsSpj(false).setContentType(tmp)); + + } + boolean b = languageService.saveOrUpdateBatch(languageList1); + System.out.println(b); + } + } \ No newline at end of file diff --git a/hoj-springboot/DataBackup/target/classes/top/hcode/hoj/controller/admin/AdminProblemController.class b/hoj-springboot/DataBackup/target/classes/top/hcode/hoj/controller/admin/AdminProblemController.class index 455b3854..fdbdafbc 100644 Binary files a/hoj-springboot/DataBackup/target/classes/top/hcode/hoj/controller/admin/AdminProblemController.class and b/hoj-springboot/DataBackup/target/classes/top/hcode/hoj/controller/admin/AdminProblemController.class differ diff --git a/hoj-springboot/DataBackup/target/classes/top/hcode/hoj/controller/oj/ContestController.class b/hoj-springboot/DataBackup/target/classes/top/hcode/hoj/controller/oj/ContestController.class index bdd3b283..cf1605f4 100644 Binary files a/hoj-springboot/DataBackup/target/classes/top/hcode/hoj/controller/oj/ContestController.class and b/hoj-springboot/DataBackup/target/classes/top/hcode/hoj/controller/oj/ContestController.class differ diff --git a/hoj-springboot/DataBackup/target/classes/top/hcode/hoj/crawler/problem/CFProblemStrategy.class b/hoj-springboot/DataBackup/target/classes/top/hcode/hoj/crawler/problem/CFProblemStrategy.class new file mode 100644 index 00000000..fae5530c Binary files /dev/null and b/hoj-springboot/DataBackup/target/classes/top/hcode/hoj/crawler/problem/CFProblemStrategy.class differ diff --git a/hoj-springboot/DataBackup/target/classes/top/hcode/hoj/crawler/problem/HDUProblemStrategy.class b/hoj-springboot/DataBackup/target/classes/top/hcode/hoj/crawler/problem/HDUProblemStrategy.class index bf37095c..fb60593a 100644 Binary files a/hoj-springboot/DataBackup/target/classes/top/hcode/hoj/crawler/problem/HDUProblemStrategy.class and b/hoj-springboot/DataBackup/target/classes/top/hcode/hoj/crawler/problem/HDUProblemStrategy.class differ diff --git a/hoj-springboot/DataBackup/target/classes/top/hcode/hoj/crawler/problem/ProblemContext.class b/hoj-springboot/DataBackup/target/classes/top/hcode/hoj/crawler/problem/ProblemContext.class index 225296de..3447d74e 100644 Binary files a/hoj-springboot/DataBackup/target/classes/top/hcode/hoj/crawler/problem/ProblemContext.class and b/hoj-springboot/DataBackup/target/classes/top/hcode/hoj/crawler/problem/ProblemContext.class differ diff --git a/hoj-springboot/DataBackup/target/classes/top/hcode/hoj/crawler/problem/ProblemStrategy$RemoteProblemInfo.class b/hoj-springboot/DataBackup/target/classes/top/hcode/hoj/crawler/problem/ProblemStrategy$RemoteProblemInfo.class new file mode 100644 index 00000000..aa1b751e Binary files /dev/null and b/hoj-springboot/DataBackup/target/classes/top/hcode/hoj/crawler/problem/ProblemStrategy$RemoteProblemInfo.class differ diff --git a/hoj-springboot/DataBackup/target/classes/top/hcode/hoj/crawler/problem/ProblemStrategy.class b/hoj-springboot/DataBackup/target/classes/top/hcode/hoj/crawler/problem/ProblemStrategy.class index 9b2432d0..6614668e 100644 Binary files a/hoj-springboot/DataBackup/target/classes/top/hcode/hoj/crawler/problem/ProblemStrategy.class and b/hoj-springboot/DataBackup/target/classes/top/hcode/hoj/crawler/problem/ProblemStrategy.class differ diff --git a/hoj-springboot/DataBackup/target/classes/top/hcode/hoj/service/ProblemService.class b/hoj-springboot/DataBackup/target/classes/top/hcode/hoj/service/ProblemService.class index d41f2289..3a8d54bf 100644 Binary files a/hoj-springboot/DataBackup/target/classes/top/hcode/hoj/service/ProblemService.class and b/hoj-springboot/DataBackup/target/classes/top/hcode/hoj/service/ProblemService.class differ diff --git a/hoj-springboot/DataBackup/target/classes/top/hcode/hoj/service/impl/ProblemServiceImpl.class b/hoj-springboot/DataBackup/target/classes/top/hcode/hoj/service/impl/ProblemServiceImpl.class index 5a256ca2..a0188757 100644 Binary files a/hoj-springboot/DataBackup/target/classes/top/hcode/hoj/service/impl/ProblemServiceImpl.class and b/hoj-springboot/DataBackup/target/classes/top/hcode/hoj/service/impl/ProblemServiceImpl.class differ diff --git a/hoj-springboot/DataBackup/target/classes/top/hcode/hoj/utils/JsoupUtils.class b/hoj-springboot/DataBackup/target/classes/top/hcode/hoj/utils/JsoupUtils.class index ad731177..c5fc171a 100644 Binary files a/hoj-springboot/DataBackup/target/classes/top/hcode/hoj/utils/JsoupUtils.class and b/hoj-springboot/DataBackup/target/classes/top/hcode/hoj/utils/JsoupUtils.class differ diff --git a/hoj-springboot/DataBackup/target/test-classes/top/hcode/hoj/DataBackupApplicationTests.class b/hoj-springboot/DataBackup/target/test-classes/top/hcode/hoj/DataBackupApplicationTests.class index 802a7283..04abdbee 100644 Binary files a/hoj-springboot/DataBackup/target/test-classes/top/hcode/hoj/DataBackupApplicationTests.class and b/hoj-springboot/DataBackup/target/test-classes/top/hcode/hoj/DataBackupApplicationTests.class differ diff --git a/hoj-vue/src/App.vue b/hoj-vue/src/App.vue index 1ab7f05e..4dc024d9 100644 --- a/hoj-vue/src/App.vue +++ b/hoj-vue/src/App.vue @@ -80,8 +80,6 @@ export default { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; - touch-action: none !important; - -ms-touch-action: none; } body { background-color: #eee !important; @@ -282,4 +280,96 @@ a:hover { .v-note-wrapper .v-note-panel { height: 460px !important; } + +.tex-formula { + font-family: times new roman, sans-serif; + vertical-align: middle; + margin: 0; + border: medium none; + position: relative; + bottom: 2px; +} + +.tex-span { + font-size: 125%; + font-family: times new roman, sans-serif; + white-space: nowrap; +} + +.tex-font-size-tiny { + font-size: 70%; +} + +.tex-font-size-script { + font-size: 75%; +} + +.tex-font-size-footnotes { + font-size: 85%; +} + +.tex-font-size-small { + font-size: 85%; +} + +.tex-font-size-normal { + font-size: 100%; +} + +.tex-font-size-large-1 { + font-size: 115%; +} + +.tex-font-size-large-2 { + font-size: 130%; +} + +.tex-font-size-large-3 { + font-size: 145%; +} + +.tex-font-size-huge-1 { + font-size: 175%; +} + +.tex-font-size-huge-2 { + font-size: 200%; +} + +.tex-font-style-sf { + font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; +} + +.tex-font-style-tt { + font-size: 110%; + font-family: courier new, monospace; +} + +.tex-font-style-bf { + font-weight: bold; +} + +.tex-font-style-it { + font-style: italic; +} + +.tex-font-style-sl { + font-style: italic; +} + +.tex-font-style-sc { + text-transform: uppercase; +} + +.tex-font-style-striked { + text-decoration: line-through; +} + +.tex-font-style-underline { + text-decoration: underline; +} + +.tex-graphics { + display: block; +} diff --git a/hoj-vue/src/common/constants.js b/hoj-vue/src/common/constants.js index ae7eb50b..2ce29f08 100644 --- a/hoj-vue/src/common/constants.js +++ b/hoj-vue/src/common/constants.js @@ -141,7 +141,10 @@ export const PROBLEM_LEVEL_RESERVE={ export const OJ_NAME = 'HOJ' -export const REMOTE_OJ = ['HDU'] +export const REMOTE_OJ = [ + {name:'HDU',key:"HDU"}, + {name:"Codeforces",key:"CF"} +] export const CONTEST_STATUS = { 'SCHEDULED': -1, diff --git a/hoj-vue/src/components/oj/common/CodeMirror.vue b/hoj-vue/src/components/oj/common/CodeMirror.vue index 9c7be87b..08630f94 100644 --- a/hoj-vue/src/components/oj/common/CodeMirror.vue +++ b/hoj-vue/src/components/oj/common/CodeMirror.vue @@ -84,7 +84,16 @@ import 'codemirror/theme/material.css'; // mode import 'codemirror/mode/clike/clike.js'; import 'codemirror/mode/python/python.js'; -import 'codemirror/mode/pascal/pascal.js'; +import 'codemirror/mode/pascal/pascal.js'; //pascal +import 'codemirror/mode/go/go.js'; //go +import 'codemirror/mode/d/d.js'; //d +import 'codemirror/mode/haskell/haskell.js'; //haskell +import 'codemirror/mode/mllike/mllike.js'; //OCaml +import 'codemirror/mode/perl/perl.js'; //perl +import 'codemirror/mode/php/php.js'; //php +import 'codemirror/mode/ruby/ruby.js'; //ruby +import 'codemirror/mode/rust/rust.js'; //rust +import 'codemirror/mode/javascript/javascript.js'; //javascript // active-line.js import 'codemirror/addon/selection/active-line.js'; diff --git a/hoj-vue/src/views/admin/problem/ProblemList.vue b/hoj-vue/src/views/admin/problem/ProblemList.vue index 56cd7d01..277cf7fd 100644 --- a/hoj-vue/src/views/admin/problem/ProblemList.vue +++ b/hoj-vue/src/views/admin/problem/ProblemList.vue @@ -151,9 +151,9 @@ @@ -204,7 +204,7 @@ export default { addRemoteOJproblemLoading: false, otherOJName: 'HDU', otherOJProblemId: '', - REMOTE_OJ: [], + REMOTE_OJ: {}, }; }, mounted() { diff --git a/hoj-vue/src/views/oj/problem/Problem.vue b/hoj-vue/src/views/oj/problem/Problem.vue index baa0dc25..0681536b 100644 --- a/hoj-vue/src/views/oj/problem/Problem.vue +++ b/hoj-vue/src/views/oj/problem/Problem.vue @@ -8,7 +8,10 @@
{{ problemData.problem.title }}
- 比赛题目 + {{ tag }} + 暂无标签
-
+

Source

diff --git a/hoj-vue/src/views/oj/problem/ProblemList.vue b/hoj-vue/src/views/oj/problem/ProblemList.vue index ac1d1b64..25da0f89 100644 --- a/hoj-vue/src/views/oj/problem/ProblemList.vue +++ b/hoj-vue/src/views/oj/problem/ProblemList.vue @@ -98,7 +98,7 @@ min-width="100" > - + - +