예제 #1
0
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
예제 #2
0
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")))
예제 #3
0
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))
예제 #4
0
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))
예제 #6
0
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
예제 #7
0
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
예제 #8
0
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))
예제 #9
0
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
예제 #10
0
def sigint_handler(signo, frame):
    writeerr_and_exit("\n * {}".format(colored("Execution canceled.", "red")))
예제 #11
0
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)