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)
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())
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)
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 )))
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)
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)
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)))
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)
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)
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)
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)))
#!/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:
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)))
def setUp(self): self.temp_dir = tempfile.mkdtemp() self.client = AtCoderClient()
def test_decorated(*args, **kwargs): client = AtCoderClient() prev = client._request func(*args, **kwargs) client._request = prev
#!/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(),
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:
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()
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)
#!/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))
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)
#!/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()))
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()
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)