def main(prog, args): parser = argparse.ArgumentParser( prog=prog, formatter_class=argparse.RawTextHelpFormatter) parser.add_argument("-c", "--contest", help="Contest ID (e.g. arc001)" "[Default] Current directory name") parser.add_argument("--without-login", action="store_true", help="Download data without login") parser.add_argument( "--path", help="Path to example data directory. This script will create examples" " in path/\n" "[Default] Current directory") 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) config = get_config(args) contest_dir_path = os.getcwd() if args.contest: contest_id = args.contest else: contest_id = os.path.basename(os.path.normpath(contest_dir_path)) if args.path: contest_dir_path = args.path 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, contest_id, contest_dir_path, config)
def load_cookie_to(session: requests.Session, cookie_path: Optional[str] = None): cookie_path = cookie_path or default_cookie_path session.cookies = LWPCookieJar(cookie_path) if os.path.exists(cookie_path): session.cookies.load() logger.info("Loaded session from {}".format( os.path.abspath(cookie_path))) return True return False
def login(self, credential_supplier=None, use_local_session_cache=True, save_session_cache=True): if credential_supplier is None: credential_supplier = default_credential_supplier if use_local_session_cache: load_cookie_to(self._session) if self.check_logging_in(): logger.info( "Successfully Logged in using the previous session cache.") logger.info( "If you'd like to invalidate the cache, delete {}.".format( default_cookie_path)) return username, password = credential_supplier() soup = BeautifulSoup( self._session.get("https://atcoder.jp/login").text, "html.parser") token = soup.find_all("form")[1].find("input", type="hidden").get("value") resp = self._request("https://atcoder.jp/login", data={ 'username': username, "password": password, "csrf_token": token }, method='POST') if resp.text.find("パスワードを忘れた方はこちら") != -1: raise LoginError if use_local_session_cache and save_session_cache: save_cookie(self._session)
def save_cookie(session: requests.Session, cookie_path: Optional[str] = None): cookie_path = cookie_path or default_cookie_path os.makedirs(os.path.dirname(cookie_path), exist_ok=True) session.cookies.save() logger.info("Saved session into {}".format(os.path.abspath(cookie_path))) os.chmod(cookie_path, 0o600)
def emit_info(text): logger.info("Problem {}: {}".format(pid, text))
def _load(path: str) -> Config: logger.info("Going to load {} as config".format(path)) with open(path, 'r') as f: return Config.load(f, args)
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("file", help="提出するソースコードの PATH") parser.add_argument("-c", "--contest", help="コンテスト ID (e.g. abc270)" "[Default] カレントディレクトリ名") parser.add_argument("-p", "--problem", help="問題番号 (e.g. a)、大文字でも小文字でも可" "[Default] ファイル名の先頭文字") parser.add_argument( "--language", "-l", help="提出するプログラム言語\n" "python, pypy2, pypy3, cython の4つから選択" "[Default] file の拡張子が .py の場合は python、.pyx の場合は cython。") parser.add_argument("--timeout", '-t', help="Timeout for each test cases (sec) [Default] 1", type=int, default=1) parser.add_argument("--save-no-session-cache", action="store_true", help="Save no session cache to avoid security risk", default=False) args = parser.parse_args(args) 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 if args.contest: contest_id = args.contest else: contest_id = os.path.basename(os.path.normpath(os.getcwd())) if args.problem: p = args.problem.lower() else: p = os.path.basename(args.file)[0] problem = Problem(contest=contest_id, alphabet=p.upper(), problem_id=(contest_id + '_' + p)) if args.language: lang = args.language if lang not in ALL_LANGUAGES: logger.error("プログラム言語は、'python', 'pypy3', 'cython'にしか対応していません。") return False else: ext = os.path.splitext('ab/abc.py')[1] if ext == ".py": lang = 'python' elif ext == ".pyx": lang = 'cython' else: logger.error("対応している拡張子は .py 及び .pyx です。") return False with open(args.file, 'r') as f: source = f.read() logger.info("Submitting {} as {}".format(args.file, lang)) contest = Contest(contest_id) submission = client.submit_source_code(contest, problem, lang, source) logger.info("{} {}".format(with_color("Done!", Fore.LIGHTGREEN_EX), contest.get_submissions_url(submission)))