Exemplo n.º 1
0
def main(prog, args, output_file=sys.stdout):
    parser = argparse.ArgumentParser(
        prog=prog, formatter_class=argparse.RawTextHelpFormatter)

    parser.add_argument(
        "url",
        help="URL (e.g. https://atcoder.jp/contests/abc012/tasks/abc012_3)")

    parser.add_argument("--without-login",
                        action="store_true",
                        help="Download data without login")

    parser.add_argument(
        "--lang",
        help="Programming language of your template code, {}.\n".format(
            " or ".join([lang.name for lang in ALL_LANGUAGES])) +
        "[Default] {}".format(CPP.name))

    parser.add_argument("--template",
                        help="File path to your template code\n{}".format(
                            "\n".join([
                                "[Default ({dname})] {path}".format(
                                    dname=lang.display_name,
                                    path=lang.default_template_path)
                                for lang in ALL_LANGUAGES
                            ])))

    parser.add_argument("--save-no-session-cache",
                        action="store_true",
                        help="Save no session cache to avoid security risk",
                        default=None)

    parser.add_argument(
        "--config",
        help="File path to your config file\n{0}{1}".format(
            "[Default (Primary)] {}\n".format(USER_CONFIG_PATH),
            "[Default (Secondary)] {}\n".format(get_default_config_path())))

    args = parser.parse_args(args)

    args.workspace = DEFAULT_WORKSPACE_DIR_PATH  # dummy for get_config()
    args.parallel = False  # dummy for get_config()
    config = get_config(args)

    client = AtCoderClient()
    if not config.etc_config.download_without_login:
        try:
            client.login(
                save_session_cache=not config.etc_config.save_no_session_cache)
            logging.info("Login successful.")
        except LoginError:
            logging.error(
                "Failed to login (maybe due to wrong username/password combination?)"
            )
            sys.exit(-1)
    else:
        logging.info("Downloading data without login.")

    generate_code(client, args.url, config, output_file=output_file)
Exemplo n.º 2
0
class TestAtCoderClientMock(unittest.TestCase):
    def setUp(self):
        self.temp_dir = tempfile.mkdtemp()
        self.client = AtCoderClient()

    @restore_client_after_run
    def test_download_submission_list(self):
        contest = Contest("arc001")
        self.client._request = create_fake_request_func({
            contest.get_my_submissions_url(1):
            fake_resp("my_submissions/1.html"),
            contest.get_my_submissions_url(2):
            fake_resp("my_submissions/2.html"),
            contest.get_my_submissions_url(3):
            fake_resp("my_submissions/3.html")
        })
        submissions = self.client.download_submission_list(Contest("arc001"))
        submission_ids = [x.submission_id for x in submissions]
        self.assertEqual(33, len(submission_ids))
        self.assertEqual(sorted(submission_ids, reverse=True), submission_ids)

    @restore_client_after_run
    def test_submit_source_code(self):
        contest = Contest("arc001")
        problem = Problem(contest, "A", "arc001_1")

        self.client._request = create_fake_request_func(
            {contest.get_submit_url(): fake_resp("submit/after_get.html")},
            {contest.get_submit_url(): fake_resp("submit/after_post.html")})

        # test two patterns (str, Language object) for parameter lang
        for lang in [CPP, "C++14 (GCC 5.4.1)"]:
            submission = self.client.submit_source_code(
                contest, problem, lang, "x")
            self.assertEqual(3905485, submission.submission_id)
            self.assertEqual("arc001_1", submission.problem_id)

    @restore_client_after_run
    def test_login_success(self):
        self.client._request = create_fake_request_func(
            post_url_to_resp={
                "https://arc001.contest.atcoder.jp/login":
                fake_resp("after_login.html")
            })

        def fake_supplier():
            return "@@@ invalid user name @@@", "@@@ password @@@"

        self.client.login(credential_supplier=fake_supplier,
                          use_local_session_cache=False)

    @restore_client_after_run
    def test_check_logging_in_success(self):
        setting_url = "https://arc001.contest.atcoder.jp/settings"
        self.client._request = create_fake_request_func(
            {setting_url: MockResponse(url=setting_url)})
        self.assertTrue(self.client.check_logging_in())
Exemplo n.º 3
0
def prepare_contest(atcoder_client: AtCoderClient,
                    contest_id: str,
                    config: Config,
                    retry_delay_secs: float = 1.5,
                    retry_max_delay_secs: float = 60,
                    retry_max_tries: int = 10):
    attempt_count = 1
    while True:
        problem_list = atcoder_client.download_problem_list(
            Contest(contest_id=contest_id))
        if problem_list:
            break
        if 0 < retry_max_tries < attempt_count:
            raise EnvironmentInitializationError
        logger.warning(
            "Failed to fetch. Will retry in {} seconds. (Attempt {})".format(
                retry_delay_secs, attempt_count))
        time.sleep(retry_delay_secs)
        retry_delay_secs = min(retry_delay_secs * 2, retry_max_delay_secs)
        attempt_count += 1

    atcoder_client.download_contest_languages(problem_list)

    tasks = [(atcoder_client, problem, config) for problem in problem_list]

    output_splitter()

    if config.etc_config.parallel_download:
        thread_pool = Pool(processes=cpu_count())
        thread_pool.map(func, tasks)
    else:
        for argv in tasks:
            try:
                func(argv)
            except Exception:
                # Prevent the script from stopping
                print(traceback.format_exc(), file=sys.stderr)
                pass

    if config.postprocess_config.exec_cmd_on_contest_dir is not None:
        contest_dir_path = os.path.join(config.code_style_config.workspace_dir,
                                        contest_id)
        logger.info(
            _message_on_execution(
                contest_dir_path,
                config.postprocess_config.exec_cmd_on_contest_dir))
        config.postprocess_config.execute_on_contest_dir(contest_dir_path)
Exemplo n.º 4
0
def generate_code(atcoder_client: AtCoderClient,
                  problem_url: str,
                  config: Config,
                  output_file: IOBase):
    problem = get_problem_from_url(problem_url)
    template_code_path = config.code_style_config.template_file
    lang = config.code_style_config.lang

    def emit_error(text):
        logging.error(with_color(text, Fore.RED))

    def emit_warning(text):
        logging.warning(text)

    def emit_info(text):
        logging.info(text)

    emit_info('{} is used for template'.format(template_code_path))

    # Fetch problem data from the statement
    try:
        content = atcoder_client.download_problem_content(problem)
    except InputFormatDetectionError as e:
        emit_error("Failed to download input format.")
        raise e
    except SampleDetectionError as e:
        emit_error("Failed to download samples.")
        raise e

    try:
        prediction_result = predict_format(content)
        emit_info(
            with_color("Format prediction succeeded", Fore.LIGHTGREEN_EX))
    except (NoPredictionResultError, MultiplePredictionResultsError) as e:
        prediction_result = FormatPredictionResult.empty_result()
        if isinstance(e, NoPredictionResultError):
            msg = "No prediction -- Failed to understand the input format"
        else:
            msg = "Too many prediction -- Failed to understand the input format"
        emit_warning(with_color(msg, Fore.LIGHTRED_EX))

    constants = predict_constants(content.original_html)
    code_generator = config.code_style_config.code_generator
    with open(template_code_path, "r") as f:
        template = f.read()

    output_splitter()

    output_file.write(code_generator(
        CodeGenArgs(
            template,
            prediction_result.format,
            constants,
            config.code_style_config
        )))
Exemplo n.º 5
0
 def test_backup(self):
     answer_data_dir_path = os.path.join(RESOURCE_DIR, "test_backup")
     # Prepare workspace twice
     for _ in range(2):
         prepare_contest(
             AtCoderClient(), "agc029",
             Config(code_style_config=CodeStyleConfig(
                 workspace_dir=self.temp_dir,
                 template_file=TEMPLATE_PATH,
                 lang="cpp",
             )))
     self.assertDirectoriesEqual(answer_data_dir_path, self.temp_dir)
Exemplo n.º 6
0
class TestAtCoderClientReal(unittest.TestCase):

    def setUp(self):
        self.temp_dir = tempfile.mkdtemp()
        self.client = AtCoderClient()

    def test_submit_source_code(self):
        problem_list = self.client.download_problem_list(Contest("arc002"))
        self.assertEqual(
            ['arc002_1',
             'arc002_2',
             'arc002_3',
             'arc002_4'],
            [p.problem_id for p in problem_list])

    def test_download_problem_content(self):
        content = self.client.download_problem_content(
            Problem(Contest("arc002"), "C", "arc002_3"))
        self.assertEqual("N\nc_{1}c_{2}...c_{N}\n", content.input_format_text)
        self.assertEqual(3, len(content.samples))

    def test_login_failed(self):
        def fake_supplier():
            return "@@@ invalid user name @@@", "@@@ password @@@"

        try:
            self.client.login(credential_supplier=fake_supplier,
                              use_local_session_cache=False)
            self.fail("Unexpectedly, this test succeeded to login.")
        except LoginError:
            pass

    def test_download_all_contests(self):
        contests = self.client.download_all_contests()
        # Check if the number of contests is more than the number when I wrote
        # this unit test.
        self.assertGreaterEqual(len(contests), 523)

        # Make sure there is no duplication
        self.assertEqual(
            len(set([c.get_id() for c in contests])),
            len(contests))

    def test_check_logging_in_is_false(self):
        self.assertFalse(self.client.check_logging_in())

    def test_cookie_save_and_load(self):
        cookie_path = os.path.join(self.temp_dir, "cookie.txt")

        session = requests.Session()

        loaded = load_cookie_to(session, cookie_path)
        self.assertFalse(loaded)

        save_cookie(session, cookie_path)

        new_session = requests.Session()
        loaded = load_cookie_to(new_session, cookie_path)
        self.assertTrue(loaded)
Exemplo n.º 7
0
def generate_code(atcoder_client: AtCoderClient, problem_url: str,
                  config: Config, output_file: IOBase):
    problem = get_problem_from_url(problem_url)
    template_code_path = config.code_style_config.template_file
    lang = config.code_style_config.lang

    def emit_error(text):
        logging.error(with_color(text, Fore.RED))

    def emit_warning(text):
        logging.warning(text)

    def emit_info(text):
        logging.info(text)

    emit_info('{} is used for template'.format(template_code_path))

    # Fetch problem data from the statement
    try:
        content = atcoder_client.download_problem_content(problem)
    except InputFormatDetectionError as e:
        emit_error("Failed to download input format.")
        raise e
    except SampleDetectionError as e:
        emit_error("Failed to download samples.")
        raise e

    try:
        prediction_result = predict_format(content)
        emit_info(with_color("Format prediction succeeded",
                             Fore.LIGHTGREEN_EX))
    except (NoPredictionResultError, MultiplePredictionResultsError) as e:
        prediction_result = FormatPredictionResult.empty_result()
        if isinstance(e, NoPredictionResultError):
            msg = "No prediction -- Failed to understand the input format"
        else:
            msg = "Too many prediction -- Failed to understand the input format"
        emit_warning(with_color(msg, Fore.LIGHTRED_EX))

    constants = predict_constants(content.original_html)
    code_generator = config.code_style_config.code_generator
    with open(template_code_path, "r") as f:
        template = f.read()

    output_splitter()

    output_file.write(
        code_generator(
            CodeGenArgs(template, prediction_result.format, constants,
                        config.code_style_config)))
Exemplo n.º 8
0
def main(lang='ja'):

    alphabet = str(Path('.').absolute().name)
    contest_id = str(Path('.').absolute().parent.name)

    client = AtCoderClient()
    client.login()
    ic(client.check_logging_in())

    contest = Contest(ic(contest_id))
    ic(contest.get_url())
    problem_list = client.download_problem_list(ic(contest))
    problem = problem_list[['A', 'B', 'C', 'D', 'E', 'F'].index(ic(alphabet))]

    html_doc = client.download_problem_content(problem).original_html
    soup = BeautifulSoup(html_doc, 'html.parser')

    title = soup.find(class_="h2").get_text()
    task_statement = soup.find(id="task-statement")

    if lang == 'ja':
        task_statement = task_statement.find(class_='lang-ja')

    def sanitize_html_for_ipynb(html_doc):
        replace_dict = {
            '<var>': '$',
            '</var>': '$',
            '<pre>': '<pre><code>',
            '</pre>': '</code></pre>'
        }
        for old_word, new_word in replace_dict.items():
            html_doc = html_doc.replace(old_word, new_word)
        return ic(html_doc)

    title = str(sanitize_html_for_ipynb(str(title)))
    title = title.lstrip().split('\n')[0]

    task_statement = Tomd(sanitize_html_for_ipynb(str(task_statement)))
    with open('problem.md', 'w+') as f:
        f.write(f"## {ic(title)}\n")
        f.write('---\n')
        f.write(task_statement.markdown)
Exemplo n.º 9
0
def prepare_contest(atcoder_client: AtCoderClient,
                    contest_id: str,
                    config: Config):
    retry_duration = 1.5
    while True:
        problem_list = atcoder_client.download_problem_list(
            Contest(contest_id=contest_id))
        if problem_list:
            break
        sleep(retry_duration)
        logging.warning(
            "Failed to fetch. Will retry in {} seconds".format(retry_duration))

    tasks = [(atcoder_client,
              problem,
              config) for
             problem in problem_list]

    output_splitter()

    if config.etc_config.parallel_download:
        thread_pool = Pool(processes=cpu_count())
        thread_pool.map(func, tasks)
    else:
        for argv in tasks:
            try:
                func(argv)
            except Exception:
                # Prevent the script from stopping
                print(traceback.format_exc(), file=sys.stderr)
                pass

    if config.postprocess_config.exec_cmd_on_contest_dir is not None:
        contest_dir_path = os.path.join(
            config.code_style_config.workspace_dir, contest_id)
        logging.info(_message_on_execution(contest_dir_path,
                                           config.postprocess_config.exec_cmd_on_contest_dir))
        config.postprocess_config.execute_on_contest_dir(
            contest_dir_path)
Exemplo n.º 10
0
def prepare_contest(atcoder_client: AtCoderClient,
                    contest_id: str,
                    config: Config):
    retry_duration = 1.5
    while True:
        problem_list = atcoder_client.download_problem_list(
            Contest(contest_id=contest_id))
        if problem_list:
            break
        sleep(retry_duration)
        logging.warning(
            "Failed to fetch. Will retry in {} seconds".format(retry_duration))

    tasks = [(atcoder_client,
              problem,
              config) for
             problem in problem_list]

    output_splitter()

    if config.etc_config.parallel_download:
        thread_pool = Pool(processes=cpu_count())
        thread_pool.map(func, tasks)
    else:
        for argv in tasks:
            try:
                func(argv)
            except Exception:
                # Prevent the script from stopping
                print(traceback.format_exc(), file=sys.stderr)
                pass

    if config.postprocess_config.exec_cmd_on_contest_dir is not None:
        contest_dir_path = os.path.join(
            config.code_style_config.workspace_dir, contest_id)
        logging.info(_message_on_execution(contest_dir_path,
                                           config.postprocess_config.exec_cmd_on_contest_dir))
        config.postprocess_config.execute_on_contest_dir(
            contest_dir_path)
Exemplo n.º 11
0
def main(prog, args, credential_supplier=None, use_local_session_cache=True) -> bool:
    parser = argparse.ArgumentParser(
        prog=prog,
        formatter_class=argparse.RawTextHelpFormatter)

    parser.add_argument("--exec", '-e',
                        help="File path to the execution target. [Default] Automatically detected exec file",
                        default=None)

    parser.add_argument("--dir", '-d',
                        help="Target directory to test. [Default] Current directory",
                        default=".")

    parser.add_argument("--timeout", '-t',
                        help="Timeout for each test cases (sec) [Default] 1",
                        type=int,
                        default=1)

    parser.add_argument("--code", '-c',
                        help="Path to the source code to submit [Default] Code path written in metadata.json",
                        type=str,
                        default=None)

    parser.add_argument("--force", "-f",
                        action="store_true",
                        help="Submit the code regardless of the local test result [Default] False",
                        default=False)

    parser.add_argument("--save-no-session-cache",
                        action="store_true",
                        help="Save no session cache to avoid security risk",
                        default=False)

    parser.add_argument("--unlock-safety", "-u",
                        action="store_true",
                        help="By default, this script only submits the first code per problem. However, you can remove"
                             " the safety by this option in order to submit codes twice or more.",
                        default=False)

    args = parser.parse_args(args)

    metadata_file = os.path.join(args.dir, "metadata.json")
    try:
        metadata = Metadata.load_from(metadata_file)
    except IOError:
        logging.error(
            "{0} is not found! You need {0} to use this submission functionality.".format(metadata_file))
        return False

    try:
        client = AtCoderClient()
        client.login(save_session_cache=args.save_no_session_cache,
                     credential_supplier=credential_supplier,
                     use_local_session_cache=use_local_session_cache,
                     )
    except LoginError:
        logging.error("Login failed. Try again.")
        return False

    tester_args = []
    if args.exec:
        tester_args += ["-e", args.exec]
    if args.dir:
        tester_args += ["-d", args.dir]
    if args.timeout:
        tester_args += ["-t", str(args.timeout)]

    if args.force or tester.main("", tester_args):
        submissions = client.download_submission_list(metadata.problem.contest)
        if not args.unlock_safety:
            for submission in submissions:
                if submission.problem_id == metadata.problem.problem_id:
                    logging.error(with_color("Cancel submitting because you already sent some code to the problem. Please "
                                             "specify -u to send the code. {}".format(
                                                 metadata.problem.contest.get_submissions_url(submission)), Fore.LIGHTRED_EX))
                    return False

        code_path = args.code or os.path.join(args.dir, metadata.code_filename)
        with open(code_path, 'r') as f:
            source = f.read()
        logging.info(
            "Submitting {} as {}".format(code_path, metadata.lang.name))
        submission = client.submit_source_code(
            metadata.problem.contest, metadata.problem, metadata.lang, source)
        logging.info("{} {}".format(
            with_color("Done!", Fore.LIGHTGREEN_EX),
            metadata.problem.contest.get_submissions_url(submission)))
Exemplo n.º 12
0
#!/usr/bin/env python3
from atcodertools.client.models.contest import Contest
from atcodertools.client.atcoder import AtCoderClient
import sys

# write contest id here
cid = sys.argv[1]

print('Contest ID = {}'.format(cid))

try:
    at = AtCoderClient()
    at.login()
    cn = Contest(cid)
    pls = at.download_problem_list(cn)

except Exception as e:
    print('ログイン/問題取得でエラー Exception = {}'.format(e))

else:
    from subprocess import run
    from glob import glob

    run(['rm', '-r', 'tests'])
    run(['mkdir', 'tests'])

    for pl in pls:
        k = pl.alphabet
        v = pl.get_url()

        try:
Exemplo n.º 13
0
def main(prog,
         args,
         credential_supplier=None,
         use_local_session_cache=True) -> bool:
    parser = argparse.ArgumentParser(
        prog=prog, formatter_class=argparse.RawTextHelpFormatter)

    parser.add_argument(
        "--exec",
        '-e',
        help=
        "File path to the execution target. [Default] Automatically detected exec file",
        default=None)

    parser.add_argument(
        "--dir",
        '-d',
        help="Target directory to test. [Default] Current directory",
        default=".")

    parser.add_argument("--timeout",
                        '-t',
                        help="Timeout for each test cases (sec) [Default] 1",
                        type=int,
                        default=1)

    parser.add_argument(
        "--code",
        '-c',
        help=
        "Path to the source code to submit [Default] Code path written in metadata.json",
        type=str,
        default=None)

    parser.add_argument(
        "--force",
        "-f",
        action="store_true",
        help=
        "Submit the code regardless of the local test result [Default] False",
        default=False)

    parser.add_argument("--save-no-session-cache",
                        action="store_true",
                        help="Save no session cache to avoid security risk",
                        default=False)

    parser.add_argument(
        "--unlock-safety",
        "-u",
        action="store_true",
        help=
        "By default, this script only submits the first code per problem. However, you can remove"
        " the safety by this option in order to submit codes twice or more.",
        default=False)

    args = parser.parse_args(args)

    metadata_file = os.path.join(args.dir, "metadata.json")
    try:
        metadata = Metadata.load_from(metadata_file)
    except IOError:
        logger.error(
            "{0} is not found! You need {0} to use this submission functionality."
            .format(metadata_file))
        return False

    try:
        client = AtCoderClient()
        client.login(
            save_session_cache=args.save_no_session_cache,
            credential_supplier=credential_supplier,
            use_local_session_cache=use_local_session_cache,
        )
    except LoginError:
        logger.error("Login failed. Try again.")
        return False

    tester_args = []
    if args.exec:
        tester_args += ["-e", args.exec]
    if args.dir:
        tester_args += ["-d", args.dir]
    if args.timeout:
        tester_args += ["-t", str(args.timeout)]

    if args.force or tester.main("", tester_args):
        submissions = client.download_submission_list(metadata.problem.contest)
        if not args.unlock_safety:
            for submission in submissions:
                if submission.problem_id == metadata.problem.problem_id:
                    logger.error(
                        with_color(
                            "Cancel submitting because you already sent some code to the problem. Please "
                            "specify -u to send the code. {}".format(
                                metadata.problem.contest.get_submissions_url(
                                    submission)), Fore.LIGHTRED_EX))
                    return False

        code_path = args.code or os.path.join(args.dir, metadata.code_filename)
        with open(code_path, 'r') as f:
            source = f.read()
        logger.info("Submitting {} as {}".format(code_path,
                                                 metadata.lang.name))
        submission = client.submit_source_code(metadata.problem.contest,
                                               metadata.problem, metadata.lang,
                                               source)
        logger.info("{} {}".format(
            with_color("Done!", Fore.LIGHTGREEN_EX),
            metadata.problem.contest.get_submissions_url(submission)))
Exemplo n.º 14
0
 def setUp(self):
     self.temp_dir = tempfile.mkdtemp()
     self.client = AtCoderClient()
Exemplo n.º 15
0
 def test_decorated(*args, **kwargs):
     client = AtCoderClient()
     prev = client._request
     func(*args, **kwargs)
     client._request = prev
Exemplo n.º 16
0
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import errno
import os

from atcodertools.client.atcoder import AtCoderClient


class NoPatternFoundError(Exception):
    pass


atcoder = AtCoderClient()


def mkdirs(path):
    try:
        os.makedirs(path)
    except OSError as exc:
        if exc.errno == errno.EEXIST and os.path.isdir(path):
            pass


if __name__ == "__main__":
    htmls_dir = "./problem_htmls/"
    mkdirs(htmls_dir)
    for contest in atcoder.download_all_contests():
        for problem in atcoder.download_problem_list(contest):
            html_path = os.path.join(
                htmls_dir, "{contest}-{problem_id}.html".format(
                    contest=contest.get_id(),
Exemplo n.º 17
0
import sys
import tempfile
import threading

from atcodertools.client.atcoder import AtCoderClient
from atcodertools.client.models.problem import Problem
from atcodertools.client.models.problem_content import InputFormatDetectionError, SampleDetectionError, ProblemContent
from atcodertools.codegen.code_style_config import CodeStyleConfig
from atcodertools.codegen.models.code_gen_args import CodeGenArgs
from atcodertools.common.language import RUST, CPP, JAVA, PYTHON, DLANG, NIM
from atcodertools.constprediction.constants_prediction import predict_modulo, predict_yes_no
from atcodertools.constprediction.models.problem_constant_set import ProblemConstantSet
from atcodertools.fileutils.load_text_file import load_text_file
from atcodertools.fmtprediction.predict_format import predict_format as predict

atcoder = AtCoderClient()
CACHE_DIR = "./.cache/"


class Skipped(Exception):
    pass


def get_and_set_cache(key, func):
    filepath = os.path.join(CACHE_DIR, key)
    if os.path.exists(os.path.join(CACHE_DIR, key)):
        with open(filepath, 'rb') as f:
            return pickle.load(f)
    res = func()
    os.makedirs(os.path.dirname(filepath), exist_ok=True)
    with open(filepath, 'wb') as f:
Exemplo n.º 18
0
def prepare_procedure(atcoder_client: AtCoderClient, problem: Problem,
                      config: Config):
    workspace_root_path = config.code_style_config.workspace_dir
    template_code_path = config.code_style_config.template_file
    lang = config.code_style_config.lang

    pid = problem.get_alphabet()
    problem_dir_path = os.path.join(workspace_root_path,
                                    problem.get_contest().get_id(), pid)

    def emit_error(text):
        logger.error(with_color("Problem {}: {}".format(pid, text), Fore.RED))

    def emit_warning(text):
        logger.warning("Problem {}: {}".format(pid, text))

    def emit_info(text):
        logger.info("Problem {}: {}".format(pid, text))

    emit_info('{} is used for template'.format(template_code_path))

    original_html = atcoder_client.download_problem_content_raw_html(problem)
    constants = predict_constants(original_html)

    if constants.judge_method.judge_type != JudgeType.Interactive:
        # Fetch problem data from the statement
        try:
            content = get_problem_content(original_html)
        except InputFormatDetectionError as e:
            emit_error("Failed to download input format.")
            raise e
        except SampleDetectionError as e:
            emit_error("Failed to download samples.")
            raise e

        # Store examples to the directory path
        if len(content.get_samples()) == 0:
            emit_info("No samples.")
        else:
            os.makedirs(problem_dir_path, exist_ok=True)
            create_examples(content.get_samples(), problem_dir_path,
                            config.etc_config.in_example_format,
                            config.etc_config.out_example_format)
            emit_info("Created examples.")

    code_file_path = os.path.join(problem_dir_path,
                                  "main.{}".format(lang.extension))

    # If there is an existing code, just create backup
    if os.path.exists(code_file_path):
        backup_id = 1
        while True:
            backup_name = "{}.{}".format(code_file_path, backup_id)
            if not os.path.exists(backup_name):
                new_path = backup_name
                shutil.copy(code_file_path, backup_name)
                break
            backup_id += 1
        emit_info("Backup for existing code '{}' -> '{}'".format(
            code_file_path, new_path))

    if constants.judge_method.judge_type != JudgeType.Interactive:
        try:
            prediction_result = predict_format(content)
            emit_info(
                with_color("Format prediction succeeded", Fore.LIGHTGREEN_EX))
        except (NoPredictionResultError, MultiplePredictionResultsError) as e:
            prediction_result = FormatPredictionResult.empty_result()
            if isinstance(e, NoPredictionResultError):
                msg = "No prediction -- Failed to understand the input format"
            else:
                msg = "Too many prediction -- Failed to understand the input format"
            emit_warning(with_color(msg, Fore.LIGHTRED_EX))
    else:
        prediction_result = FormatPredictionResult.empty_result()

    code_generator = config.code_style_config.code_generator
    with open(template_code_path, "r") as f:
        template = f.read()

    create_code(
        code_generator(
            CodeGenArgs(template, prediction_result.format, constants,
                        config.code_style_config)), code_file_path)
    emit_info("Saved code to {}".format(code_file_path))

    # Save metadata
    metadata_path = os.path.join(problem_dir_path, "metadata.json")
    Metadata(
        problem,
        os.path.basename(code_file_path),
        config.etc_config.in_example_format.replace("{}", "*"),
        config.etc_config.out_example_format.replace("{}", "*"),
        lang,
        constants.judge_method,
    ).save_to(metadata_path)
    emit_info("Saved metadata to {}".format(metadata_path))

    if config.postprocess_config.exec_cmd_on_problem_dir is not None:
        emit_info(
            _message_on_execution(
                problem_dir_path,
                config.postprocess_config.exec_cmd_on_problem_dir))
        config.postprocess_config.execute_on_problem_dir(problem_dir_path)

    output_splitter()
Exemplo n.º 19
0
def main(prog, args):
    parser = argparse.ArgumentParser(
        prog=prog, formatter_class=argparse.RawTextHelpFormatter)

    parser.add_argument("contest_id", help="Contest ID (e.g. arc001)")

    parser.add_argument("--without-login",
                        action="store_true",
                        help="Download data without login")

    parser.add_argument(
        "--workspace",
        help="Path to workspace's root directory. This script will create files"
        " in {{WORKSPACE}}/{{contest_name}}/{{alphabet}}/ e.g. ./your-workspace/arc001/A/\n"
        "[Default] {}".format(DEFAULT_WORKSPACE_DIR_PATH))

    parser.add_argument(
        "--lang",
        help="Programming language of your template code, {}.\n".format(
            " or ".join([lang.name for lang in ALL_LANGUAGES])) +
        "[Default] {}".format(CPP.name))

    parser.add_argument("--template",
                        help="File path to your template code\n{}".format(
                            "\n".join([
                                "[Default ({dname})] {path}".format(
                                    dname=lang.display_name,
                                    path=lang.default_template_path)
                                for lang in ALL_LANGUAGES
                            ])))

    # Deleted functionality
    parser.add_argument('--replacement', help=argparse.SUPPRESS)

    parser.add_argument(
        "--parallel",
        action="store_true",
        help=
        "Prepare problem directories asynchronously using multi processors.",
        default=None)

    parser.add_argument("--save-no-session-cache",
                        action="store_true",
                        help="Save no session cache to avoid security risk",
                        default=None)

    parser.add_argument(
        "--config",
        help="File path to your config file\n{0}{1}".format(
            "[Default (Primary)] {}\n".format(USER_CONFIG_PATH),
            "[Default (Secondary)] {}\n".format(get_default_config_path())))

    args = parser.parse_args(args)

    if args.replacement is not None:
        logger.error(
            with_color(
                "Sorry! --replacement argument no longer exists"
                " and you can only use --template."
                " See the official document for details.", Fore.LIGHTRED_EX))
        raise DeletedFunctionalityError

    config = get_config(args)

    try:
        import AccountInformation  # noqa
        raise BannedFileDetectedError(
            "We abolished the logic with AccountInformation.py. Please delete the file."
        )
    except ImportError:
        pass

    client = AtCoderClient()
    if not config.etc_config.download_without_login:
        try:
            client.login(
                save_session_cache=not config.etc_config.save_no_session_cache)
            logger.info("Login successful.")
        except LoginError:
            logger.error(
                "Failed to login (maybe due to wrong username/password combination?)"
            )
            sys.exit(-1)
    else:
        logger.info("Downloading data without login.")

    prepare_contest(client, args.contest_id, config)
Exemplo n.º 20
0
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import errno
import os

from atcodertools.client.atcoder import AtCoderClient
from atcodertools.client.models.problem_content import SampleDetectionError, InputFormatDetectionError


class NoPatternFoundError(Exception):
    pass


atcoder = AtCoderClient()


def mkdirs(path):
    try:
        os.makedirs(path)
    except OSError as exc:
        if exc.errno == errno.EEXIST and os.path.isdir(path):
            pass


if __name__ == "__main__":
    for contest in atcoder.download_all_contests():
        for problem in atcoder.download_problem_list(contest):
            path = "./test_data/{contest}-{problem_id}".format(contest=contest.get_id(),
                                                               problem_id=problem.get_alphabet())
            if os.path.exists(path) and len(os.listdir(path)) != 0:
                print("{} already exists -- skipping download".format(path))
Exemplo n.º 21
0
def main(prog, args, output_file=sys.stdout):
    parser = argparse.ArgumentParser(
        prog=prog,
        formatter_class=argparse.RawTextHelpFormatter)

    parser.add_argument("url",
                        help="URL (e.g. https://atcoder.jp/contests/abc012/tasks/abc012_3)")

    parser.add_argument("--without-login",
                        action="store_true",
                        help="Download data without login")

    parser.add_argument("--lang",
                        help="Programming language of your template code, {}.\n"
                        .format(" or ".join([lang.name for lang in ALL_LANGUAGES])) + "[Default] {}".format(CPP.name))

    parser.add_argument("--template",
                        help="File path to your template code\n{}".format(
                            "\n".join(
                                ["[Default ({dname})] {path}".format(
                                    dname=lang.display_name,
                                    path=lang.default_template_path
                                ) for lang in ALL_LANGUAGES]
                            ))
                        )

    parser.add_argument("--save-no-session-cache",
                        action="store_true",
                        help="Save no session cache to avoid security risk",
                        default=None)

    parser.add_argument("--config",
                        help="File path to your config file\n{0}{1}".format("[Default (Primary)] {}\n".format(
                            USER_CONFIG_PATH),
                            "[Default (Secondary)] {}\n".format(
                                get_default_config_path()))
                        )

    args = parser.parse_args(args)

    args.workspace = DEFAULT_WORKSPACE_DIR_PATH  # dummy for get_config()
    args.parallel = False  # dummy for get_config()
    config = get_config(args)

    client = AtCoderClient()
    if not config.etc_config.download_without_login:
        try:
            client.login(
                save_session_cache=not config.etc_config.save_no_session_cache)
            logging.info("Login successful.")
        except LoginError:
            logging.error(
                "Failed to login (maybe due to wrong username/password combination?)")
            sys.exit(-1)
    else:
        logging.info("Downloading data without login.")

    generate_code(client,
                  args.url,
                  config,
                  output_file=output_file)
Exemplo n.º 22
0
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import errno
import os

from atcodertools.client.atcoder import AtCoderClient


class NoPatternFoundError(Exception):
    pass


atcoder = AtCoderClient()


def mkdirs(path):
    try:
        os.makedirs(path)
    except OSError as exc:
        if exc.errno == errno.EEXIST and os.path.isdir(path):
            pass


if __name__ == "__main__":
    htmls_dir = "./problem_htmls/"
    mkdirs(htmls_dir)
    for contest in atcoder.download_all_contests():
        for problem in atcoder.download_problem_list(contest):
            html_path = os.path.join(htmls_dir, "{contest}-{problem_id}.html".format(
                contest=contest.get_id(), problem_id=problem.get_alphabet()))
Exemplo n.º 23
0
def prepare_procedure(atcoder_client: AtCoderClient,
                      problem: Problem,
                      config: Config):
    workspace_root_path = config.code_style_config.workspace_dir
    template_code_path = config.code_style_config.template_file
    lang = config.code_style_config.lang

    pid = problem.get_alphabet()
    problem_dir_path = os.path.join(
        workspace_root_path,
        problem.get_contest().get_id(),
        pid)

    def emit_error(text):
        logging.error(with_color("Problem {}: {}".format(pid, text), Fore.RED))

    def emit_warning(text):
        logging.warning("Problem {}: {}".format(pid, text))

    def emit_info(text):
        logging.info("Problem {}: {}".format(pid, text))

    emit_info('{} is used for template'.format(template_code_path))

    # Fetch problem data from the statement
    try:
        content = atcoder_client.download_problem_content(problem)
    except InputFormatDetectionError as e:
        emit_error("Failed to download input format.")
        raise e
    except SampleDetectionError as e:
        emit_error("Failed to download samples.")
        raise e

    # Store examples to the directory path
    if len(content.get_samples()) == 0:
        emit_info("No samples.")
    else:
        os.makedirs(problem_dir_path, exist_ok=True)
        create_examples(content.get_samples(), problem_dir_path,
                        IN_EXAMPLE_FORMAT, OUT_EXAMPLE_FORMAT)
        emit_info("Created examples.")

    code_file_path = os.path.join(
        problem_dir_path,
        "main.{}".format(lang.extension))

    # If there is an existing code, just create backup
    if os.path.exists(code_file_path):
        backup_id = 1
        while True:
            backup_name = "{}.{}".format(code_file_path, backup_id)
            if not os.path.exists(backup_name):
                new_path = backup_name
                shutil.copy(code_file_path, backup_name)
                break
            backup_id += 1
        emit_info(
            "Backup for existing code '{}' -> '{}'".format(
                code_file_path,
                new_path))

    try:
        prediction_result = predict_format(content)
        emit_info(
            with_color("Format prediction succeeded", Fore.LIGHTGREEN_EX))
    except (NoPredictionResultError, MultiplePredictionResultsError) as e:
        prediction_result = FormatPredictionResult.empty_result()
        if isinstance(e, NoPredictionResultError):
            msg = "No prediction -- Failed to understand the input format"
        else:
            msg = "Too many prediction -- Failed to understand the input format"
        emit_warning(with_color(msg, Fore.LIGHTRED_EX))

    constants = predict_constants(content.original_html)
    code_generator = config.code_style_config.code_generator
    with open(template_code_path, "r") as f:
        template = f.read()

    create_code(code_generator(
        CodeGenArgs(
            template,
            prediction_result.format,
            constants,
            config.code_style_config
        )),
        code_file_path)
    emit_info("Saved code to {}".format(code_file_path))

    # Save metadata
    metadata_path = os.path.join(problem_dir_path, "metadata.json")
    Metadata(problem,
             os.path.basename(code_file_path),
             IN_EXAMPLE_FORMAT.replace("{}", "*"),
             OUT_EXAMPLE_FORMAT.replace("{}", "*"),
             lang,
             ).save_to(metadata_path)
    emit_info("Saved metadata to {}".format(metadata_path))

    if config.postprocess_config.exec_cmd_on_problem_dir is not None:
        emit_info(_message_on_execution(problem_dir_path,
                                        config.postprocess_config.exec_cmd_on_problem_dir))
        config.postprocess_config.execute_on_problem_dir(
            problem_dir_path)

    output_splitter()
Exemplo n.º 24
0
def main(prog, args):
    parser = argparse.ArgumentParser(
        prog=prog,
        formatter_class=argparse.RawTextHelpFormatter)

    parser.add_argument("contest_id",
                        help="Contest ID (e.g. arc001)")

    parser.add_argument("--without-login",
                        action="store_true",
                        help="Download data without login")

    parser.add_argument("--workspace",
                        help="Path to workspace's root directory. This script will create files"
                             " in {{WORKSPACE}}/{{contest_name}}/{{alphabet}}/ e.g. ./your-workspace/arc001/A/\n"
                             "[Default] {}".format(DEFAULT_WORKSPACE_DIR_PATH))

    parser.add_argument("--lang",
                        help="Programming language of your template code, {}.\n"
                        .format(" or ".join([lang.name for lang in ALL_LANGUAGES])) + "[Default] {}".format(CPP.name))

    parser.add_argument("--template",
                        help="File path to your template code\n{}".format(
                            "\n".join(
                                ["[Default ({dname})] {path}".format(
                                    dname=lang.display_name,
                                    path=lang.default_template_path
                                ) for lang in ALL_LANGUAGES]
                            ))
                        )

    # Deleted functionality
    parser.add_argument('--replacement', help=argparse.SUPPRESS)

    parser.add_argument("--parallel",
                        action="store_true",
                        help="Prepare problem directories asynchronously using multi processors.",
                        default=None)

    parser.add_argument("--save-no-session-cache",
                        action="store_true",
                        help="Save no session cache to avoid security risk",
                        default=None)

    parser.add_argument("--config",
                        help="File path to your config file\n{0}{1}".format("[Default (Primary)] {}\n".format(
                            USER_CONFIG_PATH),
                            "[Default (Secondary)] {}\n".format(
                                get_default_config_path()))
                        )

    args = parser.parse_args(args)

    if args.replacement is not None:
        logging.error(with_color("Sorry! --replacement argument no longer exists"
                                 " and you can only use --template."
                                 " See the official document for details.", Fore.LIGHTRED_EX))
        raise DeletedFunctionalityError

    config = get_config(args)

    try:
        import AccountInformation  # noqa
        raise BannedFileDetectedError(
            "We abolished the logic with AccountInformation.py. Please delete the file.")
    except ImportError:
        pass

    client = AtCoderClient()
    if not config.etc_config.download_without_login:
        try:
            client.login(
                save_session_cache=not config.etc_config.save_no_session_cache)
            logging.info("Login successful.")
        except LoginError:
            logging.error(
                "Failed to login (maybe due to wrong username/password combination?)")
            sys.exit(-1)
    else:
        logging.info("Downloading data without login.")

    prepare_contest(client,
                    args.contest_id,
                    config)