package org.psjava.judgesubmit; import java.io.IOException; import org.psjava.ds.map.MutableMap; import org.psjava.goods.GoodMutableMapFactory; public class POJSubmitStatusReceiver implements SubmitStatusReceiver { public static final String SUBMIT_ID_PART_START = "<tr align=center><td>"; @Override public SubmitStatus receive(JudgeHttpClient client, String submitId) throws IOException, SiteParsingException, InvalidInputException, JudgeServiceException { int nextId = SiteParsingUtil.parseInt(submitId) + 1; String r = client.receiveGetBodyString("/status?top=" + nextId, POJ.ENCODING); if (!r.contains(SUBMIT_ID_PART_START)) throw InvalidSubmitIdException.create(submitId); // TODO add unit test String firstId = SiteParsingUtil.extractMiddleString(r, 0, SUBMIT_ID_PART_START, "</td>"); if (!firstId.equals(submitId)) throw InvalidSubmitIdException.create(submitId); int fontTagStart = SiteParsingUtil.getStrictIndexOf(r, "<font", r.indexOf(SUBMIT_ID_PART_START)); String codeString = SiteParsingUtil.extractMiddleString(r, fontTagStart, ">", "</font>"); SubmitStatusCode code = convertToCode(codeString); int memPartStart = SiteParsingUtil.getStrictIndexOf(r, "<td>", fontTagStart); String memString = SiteParsingUtil.extractMiddleString(r, memPartStart, "<td>", "</td>").trim(); long mem = parseMemory(memString); int timePartStart = SiteParsingUtil.getStrictIndexOf(r, "<td>", memPartStart + 1); String timeString = SiteParsingUtil.extractMiddleString(r, timePartStart, "<td>", "</td>").trim(); long time = parseTime(timeString); return new SubmitStatus(0, code, mem, time, null); } private static SubmitStatusCode convertToCode(String codeString) throws SiteParsingException { MutableMap<String, SubmitStatusCode> map = GoodMutableMapFactory.getInstance().create(); map.put("Accepted", SubmitStatusCode.ACCEPTED); map.put("Wrong Answer", SubmitStatusCode.WRONG_ANSWER); map.put("Compile Error", SubmitStatusCode.COMPILE_ERROR); map.put("Time Limit Exceeded", SubmitStatusCode.TIME_LIMIT_EXCEED); map.put("Runtime Error", SubmitStatusCode.RUNTIME_ERROR); map.put("Presentation Error", SubmitStatusCode.PRESENTATION_ERROR); map.put("Memory Limit Exceeded", SubmitStatusCode.MEMORY_LIMITE_EXCEED); map.put("Output Limit Exceeded", SubmitStatusCode.OUTPUT_LIMIT_EXCEED); map.put("System Error", SubmitStatusCode.SYSTEM_ERROR); map.put("Validate Error", SubmitStatusCode.SYSTEM_ERROR); map.put("Running & Judging", SubmitStatusCode.RUNNING); map.put("Compiling", SubmitStatusCode.COMPILING); map.put("Waiting", SubmitStatusCode.WAITING); if (!map.containsKey(codeString)) throw new SiteParsingException("Unknown code: " + codeString); return map.get(codeString); } private long parseTime(String timeString) throws SiteParsingException { if (timeString.length() == 0) { return 0; } else { SiteParsingUtil.assertTrue(timeString.endsWith("MS")); return SiteParsingUtil.parseInt(timeString.substring(0, timeString.length() - 2)); } } private long parseMemory(String memString) throws SiteParsingException { if (memString.length() == 0) { return 0; } else { SiteParsingUtil.assertTrue(memString.endsWith("K")); return SiteParsingUtil.parseInt(memString.substring(0, memString.length() - 1)) * 1024; } } }