def fetch_testcases(url): print(" * Fetch testcase from url: {}".format(colored(url, "blue"))) # fetch html html = urllib.request.urlopen(url) soup = BeautifulSoup(html, "html.parser") res = [] input_list = soup.find_all("h3", text=re.compile("入力例")) output_list = soup.find_all("h3", text=re.compile("出力例")) # check length mismatch if not len(input_list) == len(output_list): writeerr_and_exit("Error! length of input and output mismatch.") # fetch input and output for inp, outp in zip(input_list, output_list): input_title = inp.text output_title = outp.text input_cont = inp.findNext('pre').text output_cont = outp.findNext('pre').text input_title = format_string(input_title) output_title = format_string(output_title) input_cont = format_string(input_cont) output_cont = format_string(output_cont) res.append({ "input_title": input_title, "output_title": output_title, "input": input_cont, "output": output_cont }) return res
def fetch_testcases_from_url(host, contest, problem, url): # create base directory for testcase current_path = os.path.abspath(".") testcase_dir = "{}/{}/{}".format(current_path, config.procon_dir, config.testcase_dir) testcase_json = "{}/{}".format(testcase_dir, config.testcase_json) testcase_dict = {} if os.path.exists(testcase_json): with open(testcase_json, 'r') as f: testcase_dict = json.load(f) os.makedirs(testcase_dir, exist_ok=True) # fetch testcases testcases = None if host.lower() == "atcoder": testcases = ac.fetch_testcases(url) elif host.lower() == "yukicoder": testcases = yk.fetch_testcases(url) else: writeerr_and_exit("Error! Not Implemented.") # write testcases if testcases is not None: if contest not in testcase_dict.keys(): testcase_dict[contest] = {} testcase_dict[contest][problem] = testcases f = open(testcase_json, 'w') json.dump(testcase_dict, f, indent=4) print(" * Testcases written to {}".format( colored(testcase_json, "blue")))
def assert_host_name(host): '''check if host is valid ''' host = str(host).lower() hosts = ["atcoder", "codeforces", "aoj", "yukicoder"] if host not in hosts: writeerr_and_exit( "Error! No support for contest host: {}.".format(host))
def assert_method(method): '''check if method exists ''' methods = [ "fetch", "fetchurl", "copy", "test", "run", "add", "interactive" ] if method not in methods: writeerr_and_exit("Error! No support for method: {}.".format(method))
def interactive(source, judge, fast=False, force=False): ext_source = source.split(".")[-1] ext_judge = judge.split(".")[-1] if ext_source == "cpp" or ext_source == "cc": b = compile_cpp_source(source, fast, force) if not b: return if ext_judge == "cpp" or ext_judge == "cc": b = compile_cpp_source(judge, fast, force) if not b: return exe_source = compose_command(ext_source, source, time=False) exe_judge = compose_command(ext_judge, judge, time=False) if exe_source is None or exe_judge is None: return proc_source = subprocess.Popen( exe_source, stdin=subprocess.PIPE, stdout=subprocess.PIPE, # stderr=subprocess.PIPE, encoding='utf-8', bufsize=1) proc_judge = subprocess.Popen( exe_judge, stdin=subprocess.PIPE, stdout=subprocess.PIPE, # stderr=subprocess.PIPE, encoding='utf-8', bufsize=1) flag = fcntl.fcntl(proc_source.stdout.fileno(), fcntl.F_GETFL) fcntl.fcntl(proc_source.stdout.fileno(), fcntl.F_SETFL, flag | os.O_NONBLOCK) flag = fcntl.fcntl(proc_judge.stdout.fileno(), fcntl.F_GETFL) fcntl.fcntl(proc_judge.stdout.fileno(), fcntl.F_SETFL, flag | os.O_NONBLOCK) while True: try: if proc_source.poll() is not None and proc_judge.poll( ) is not None: break buf_source = proc_source.stdout.readline() buf_judge = proc_judge.stdout.readline() if buf_source != "": print(" ** {} {}".format(colored("source output >>", "blue"), buf_source.strip())) proc_judge.stdin.write(buf_source) if buf_judge != "": print(" ** {} {}".format(colored("judge output >>", "green"), buf_judge.strip())) proc_source.stdin.write(buf_judge) time.sleep(default_timeout) except Exception as e: writeerr_and_exit("Error occurred: {}".format(e))
def get_problem(args, info): '''get problem name ''' problem = "" if args.problem is None: if "problem" in info.keys(): problem = info["problem"] else: writeerr_and_exit("Error! No problem specified.") else: problem = args.problem return problem
def get_contest(args, info): '''get contest name ''' contest = "" if args.contest is None: if "contest" in info.keys(): contest = info["contest"] else: if info["host"].lower() == "atcoder": writeerr_and_exit("Error! No contest specified.") else: contest = args.contest return contest
def run_source(source, fast=False, force=False, input_file=None): ext = source.split(".")[-1] if ext == "cpp" or ext == "cc": b = compile_cpp_source(source, fast, force) if not b: return # run command command = compose_command(ext, source) if command is None: return proc = None if input_file is None: proc = subprocess.Popen(command, stdin=subprocess.PIPE, stderr=subprocess.PIPE, encoding='utf-8', bufsize=1) else: with open(input_file, 'r') as f: proc = subprocess.Popen(command, stdin=f, stderr=subprocess.PIPE, encoding='utf-8', bufsize=1) print(" ** {}".format(colored("input>>", "blue"))) while True: try: inp = input_with_timeout() if inp is not None: proc.stdin.write(inp + "\n") proc.stdin.flush() if proc.poll() is not None: break except Exception as e: writeerr_and_exit("Error occurred: {}".format(e)) stdout_data, stderr_data = proc.communicate() stderr_data = stderr_data.strip().split("\n") if len(stderr_data) > 1: print(" ** {}".format(colored("Standard Error", "blue", attrs=["bold"]))) print_err_data = stderr_data[:-1] if len(print_err_data) > config.stderr_print_lines: print_err_data = print_err_data[:config.stderr_print_lines] print_err_data.append("...") print_fixed_line("\n".join(print_err_data)) mem, tim = stderr_data[-1][1:-1].split(" ") print("Time: {}s, Memory: {}KB".format(tim, mem))
def fetch_testcases(url): print(" * Fetch testcase from url: {}".format(colored(url, "blue"))) # fetch html html = urllib.request.urlopen(url) soup = BeautifulSoup(html, "html.parser") res = [] # replace br for br in soup.find_all("br"): br.replace_with("\n") input_list = soup.find_all("div", class_="input") output_list = soup.find_all("div", class_="output") # check length mismatch if not len(input_list) == len(output_list): writeerr_and_exit("Error! length of input and output mismatch.") # fetch input and output i = 0 for inp, outp in zip(input_list, output_list): i += 1 input_title = "input {}".format(i) output_title = "output {}".format(i) input_cont = inp.pre.text output_cont = outp.pre.text input_title = format_string(input_title) output_title = format_string(output_title) input_cont = format_string(input_cont) output_cont = format_string(output_cont) res.append({ "input_title": input_title, "output_title": output_title, "input": input_cont, "output": output_cont }) return res
def sigint_handler(signo, frame): writeerr_and_exit("\n * {}".format(colored("Execution canceled.", "red")))
def main(): # parse arguments parser = argparse.ArgumentParser() parser.add_argument("method", help="type of the method") parser.add_argument("--host", help="contest host") parser.add_argument("-c", "--contest", help="contest name") parser.add_argument("-p", "--problem", help="problem name") parser.add_argument("-s", "--source", help="source file") parser.add_argument("--url", help="problem url") parser.add_argument("--fast", action="store_true", help="compile without optimization option") parser.add_argument("--judge", help="judge file") parser.add_argument("--force", action="store_true", help="force compile") parser.add_argument("-i", "--input_file", help="input file") args = parser.parse_args() # create base directory current_path = os.path.abspath(".") os.makedirs("{}/{}".format(current_path, config.procon_dir), exist_ok=True) os.makedirs("{}/{}".format(config.procon_dir, config.info_dir), exist_ok=True) info_json = "{}/{}/{}".format(config.procon_dir, config.info_dir, config.info_json) if not os.path.exists(info_json): info = {} info["current_path"] = current_path write_info(info) # fetch basic info info = load_info() # method method = args.method assert_method(method) # host host = get_host(args, info) info["host"] = host assert_host_name(host) write_info(info) # contest no_contest = ["copy", "run"] if method not in no_contest: contest = get_contest(args, info) else: contest = "" # problem no_problem = ["copy", "run"] if method not in no_problem: problem = get_problem(args, info) if host.lower() == "yukicoder": contest = problem else: problem = "" # source source = get_source(args, info) # judge judge = get_judge(args, info) # url url = get_url(args, info) # input input_file = get_input_file(args, info) if method == "fetch": fetch_testcases(host, contest, problem) elif method == "fetchurl": if url == "": writeerr_and_exit("Error! No url specified.") fetch_testcases_from_url(host, contest, problem, url) elif method == "copy": if source == "": writeerr_and_exit("Error! No source file specified.") copy_source(source) elif method == "test": if source == "": writeerr_and_exit("Error! No source file specified.") check_testcases(source, contest, problem, fast=args.fast, force=args.force) elif method == "run": run_source(source, fast=args.fast, force=args.force, input_file=input_file) elif method == "add": add_new_testcase(contest, problem) elif method == "interactive": if source == "": writeerr_and_exit("Error! No source file specified.") if judge == "": writeerr_and_exit("Error! No judge file specified.") interactive(source, judge, fast=args.fast, force=args.force) if method not in no_contest: info["contest"] = contest if method not in no_problem: info["problem"] = problem info["source"] = source info["judge"] = judge write_info(info)