def handleCookieAdded(self, cookie: QNetworkCookie): url = self.browser.url().toString() if service_from_url(url): py_cookie = toPyCookie(cookie) with with_cookiejar(new_session_with_our_user_agent(), path=default_cookie_path) as sess: sess.cookies.set_cookie(py_cookie)
def generate_scanner(args: 'argparse.Namespace') -> None: if not args.silent: log.warning('This feature is ' + log.red('experimental') + '.') if args.silent: for handler in log.logger.handlers: log.removeHandler(handler) problem = onlinejudge.dispatch.problem_from_url(args.url) if problem is None: sys.exit(1) with utils.with_cookiejar(utils.new_default_session(), path=args.cookie) as sess: it = problem.get_input_format(session=sess) # type: Any if not it: log.error('input format not found') sys.exit(1) try: log.debug('original data: %s', repr(it)) it = list(tokenize(it)) log.debug('tokenized: %s', str(it)) it = list(parse(it)) log.debug('parsed: %s', str(it)) it = postprocess(it) log.debug('postprocessed: %s', str(it)) it = export(it, use_scanf=args.scanf, repeat_macro=args.repeat_macro) log.debug('result: %s', repr(it)) except: log.error('something wrong') raise log.success('success:') print(log.bold(it.rstrip())) # to stdout
def download(args: 'argparse.Namespace') -> None: # prepare values problem = onlinejudge.dispatch.problem_from_url(args.url) if problem is None: raise requests.exceptions.InvalidURL('The contest "%s" is not supported' % args.url) is_default_format = args.format is None and args.directory is None # must be here since args.directory and args.format are overwritten if args.directory is None: args.directory = pathlib.Path('test') if args.format is None: args.format = '%b.%e' # get samples from the server with utils.with_cookiejar(utils.new_session_with_our_user_agent(), path=args.cookie) as sess: if args.yukicoder_token and isinstance(problem, YukicoderProblem): sess.headers['Authorization'] = 'Bearer {}'.format(args.yukicoder_token) if args.system: samples = problem.download_system_cases(session=sess) else: samples = problem.download_sample_cases(session=sess) if not samples: raise onlinejudge.type.SampleParseError("Sample not found") # append the history for submit command if not args.dry_run and is_default_format: history = onlinejudge._implementation.download_history.DownloadHistory() history.add(problem) # write samples to files for i, sample in enumerate(samples): log.emit('') log.info('sample %d', i) for ext in ['in', 'out']: data = getattr(sample, ext + 'put_data') if data is None: continue name = sample.name table = {} table['i'] = str(i + 1) table['e'] = ext table['n'] = name table['b'] = os.path.basename(name) table['d'] = os.path.dirname(name) path = args.directory / format_utils.percentformat(args.format, table) # type: pathlib.Path log.status('%sput: %s', ext, name) if not args.silent: log.emit(utils.snip_large_file_content(data, limit=40, head=20, tail=10, bold=True)) if args.dry_run: continue if path.exists(): raise FileExistsError('Failed to download since file already exists: ' + str(path)) path.parent.mkdir(parents=True, exist_ok=True) with path.open('wb') as fh: fh.write(data) log.success('saved to: %s', path) # print json if args.json: print(json.dumps(list(map(convert_sample_to_dict, samples))))
def download(args: 'argparse.Namespace') -> None: # prepare values problem = onlinejudge.dispatch.problem_from_url(args.url) if problem is None: sys.exit(1) is_default_format = args.format is None and args.directory is None # must be here since args.directory and args.format are overwritten if args.directory is None: args.directory = pathlib.Path('test') if args.format is None: args.format = '%b.%e' # get samples from the server with utils.with_cookiejar(utils.new_session_with_our_user_agent(), path=args.cookie) as sess: if args.system: samples = problem.download_system_cases(session=sess) # type: ignore else: samples = problem.download_sample_cases(session=sess) # type: ignore # append the history for submit command if not args.dry_run and is_default_format: history = onlinejudge._implementation.download_history.DownloadHistory() history.add(problem) # write samples to files for i, sample in enumerate(samples): log.emit('') log.info('sample %d', i) for ext in ['in', 'out']: data = getattr(sample, ext + 'put_data') if data is None: continue name = sample.name table = {} table['i'] = str(i + 1) table['e'] = ext table['n'] = name table['b'] = os.path.basename(name) table['d'] = os.path.dirname(name) path = args.directory / format_utils.percentformat(args.format, table) # type: pathlib.Path log.status('%sput: %s', ext, name) if not args.silent: log.emit(utils.snip_large_file_content(data, limit=40, head=20, tail=10, bold=True)) if args.dry_run: continue if path.exists(): log.warning('file already exists: %s', path) if not args.overwrite: log.warning('skipped') continue path.parent.mkdir(parents=True, exist_ok=True) with path.open('wb') as fh: fh.write(data) log.success('saved to: %s', path) # print json if args.json: print(json.dumps(list(map(convert_sample_to_dict, samples))))
def test_download_system_test(self): with utils.with_cookiejar(utils.get_default_session()): url = 'https://community.topcoder.com/longcontest/?module=ViewProblemStatement&rd=17143&pm=14889' tid = 33800773 problem = TopcoderLongContestProblem.from_url(url) self.assertEqual(problem.download_system_test(tid), 'seed = 1919427468645\nH = 85\nW = 88\nC = 2\n') with utils.with_cookiejar(utils.get_default_session()): url = 'https://community.topcoder.com/longcontest/?module=ViewProblemStatement&rd=17092&pm=14853' tid = 33796324 problem = TopcoderLongContestProblem.from_url(url) self.assertEqual( problem.download_system_test(tid), """\ Seed = 2917103922548 Coins: 5372 Max Time: 2988 Note Time: 5 Num Machines: 3 Machine 0... Wheel 0: ACEEDEDBDGBADCDFGD Wheel 1: GGFEFBFDFFDEECFEAG Wheel 2: EFCCCAADBDGEGBDCDD Expected payout rate: 1.5775034293552812 Machine 1... Wheel 0: CDFFDEEEAGGGGGFGGBEFCCFFFD Wheel 1: EDCGBGFBBCCGGFGDFBFECGGEFC Wheel 2: GEDECEGFDCGDGGCDDCEDGBGEBG Expected payout rate: 0.7345243513882568 Machine 2... Wheel 0: ABEEDDDCGBG Wheel 1: EDEEDADGEAF Wheel 2: EBEGEFEGEBF Expected payout rate: 0.6160781367392938 """)
def login(args: 'argparse.Namespace') -> None: service = onlinejudge.dispatch.service_from_url(args.url) if service is None: sys.exit(1) with utils.with_cookiejar(utils.new_session_with_our_user_agent(), path=args.cookie) as session: if is_logged_in_with_message(service, session=session): return else: if args.check: sys.exit(1) if args.use_browser in ('always', 'auto'): try: login_with_browser(service, session=session) except ImportError: log.error( 'Selenium is not installed: try $ pip3 install selenium') pass except WebDriverException as e: log.error('%s', e) pass else: if is_logged_in_with_message(service, session=session): return else: sys.exit(1) if args.use_browser in ('never', 'auto'): if args.use_browser == 'auto': log.warning('use CUI login since Selenium fails') try: login_with_password(service, username=args.username, password=args.password, session=session) except NotImplementedError as e: log.error('%s', e) pass except onlinejudge.type.LoginError: sys.exit(1) else: if is_logged_in_with_message(service, session=session): return else: sys.exit(1) sys.exit(1)
def get_standings(contest_slug: str = 'arc121', contest_category: str = 'arc') -> bool: filepath: str = get_local_json_path(contest_slug=contest_slug, contest_category=contest_category) if os.path.exists(filepath): return False sess: Session with with_cookiejar(get_default_session(), path=default_cookie_path) as sess: res: Response = sess.get( f'https://atcoder.jp/contests/{contest_slug}/standings/json') with open(filepath, mode='w') as f: f.write(res.text) return True
def submit(self, config: Config, language: str) -> None: contest_site = self.oj_problem_class.get_service().get_name() if language == 'auto-detect': try: lang_id = config.pref['submit']['default_lang'][contest_site][ self.extension] except KeyError as e: click.secho( f'{self.extension} not found in possible self.extensions. if you want to add {self.extension}, you can add it in ~/.config/pcm/config.toml', fg='red') print('current possible self.extensions') print(config.pref['submit']['default_lang'][contest_site]) return try: service = self.oj_problem_class.get_service().get_name() lang_id = config.pref['submit']['language'][service][lang_id] except: pass else: try: lang_id = config.pref['submit']['language'][contest_site][ language] except KeyError as e: click.secho( f'{language} not found in possible language. if you want to add {language}, you can add it in ~/.config/pcm/config.toml', fg='red') print('current possible language') print(config.pref['submit']['language'][contest_site]) return code_string = self.bundle( config, expand_acl=(False if (contest_site == 'AtCoder' and lang_id in ['4003', '4004']) else True)).encode() with oj_utils.with_cookiejar( oj_utils.get_default_session()) as session: try: res = self.oj_problem_class.submit_code(code_string, language_id=lang_id, session=session) except AssertionError as e: click.secho('maybe language_id is not valid.', fg='yellow') print(e) exit() else: print(res)
def login(args: 'argparse.Namespace') -> None: # get service service = onlinejudge.dispatch.service_from_url(args.url) if service is None: sys.exit(1) # configure kwargs = {} if isinstance(service, onlinejudge.service.yukicoder.YukicoderService): if not args.method: args.method = 'github' if args.method not in ['github', 'twitter']: log.failure('login for yukicoder: invalid option: --method %s', args.method) sys.exit(1) kwargs['method'] = args.method else: if args.method: log.failure('login for %s: invalid option: --method %s', service.get_name(), args.method) sys.exit(1) with utils.with_cookiejar(utils.new_session_with_our_user_agent(), path=args.cookie) as sess: if args.check: if service.is_logged_in(session=sess): log.info('You have already signed in.') else: log.info('You are not signed in.') sys.exit(1) else: # login def get_credentials() -> Tuple[str, str]: if args.username is None: args.username = input('Username: '******'If you don\'t want to give your password to this program, you can give only your session tokens.') log.info('see: https://github.com/kmyk/online-judge-tools/blob/master/LOGIN_WITH_COOKIES.md') try: service.login(get_credentials, session=sess, **kwargs) # type: ignore except onlinejudge.type.LoginError: pass
def pp(config: Config, contest_id_or_url: str, current_dir: bool, work_dir_name: str, force: bool): contest_url = "" if contest_id_or_url[:3] in ("abc", "arc", "agc"): contest_url = f"https://atcoder.jp/contests/{contest_id_or_url}" else: contest_url = contest_id_or_url contest = onlinejudge.dispatch.contest_from_url(contest_url) if not contest: click.secho(f"{contest_id_or_url} is not valid.", fg='yellow') return 0 problems: Sequence[Problem] with oj_utils.with_cookiejar(oj_utils.get_default_session()) as session: problems = contest.list_problems(session=session) if current_dir: config.pref['contest_root_dir'] = '.' work_dir = get_work_directory(config, problems[0], from_pp=True).parent if work_dir_name: work_dir.name = work_dir_name already_exist = False try: os.makedirs(work_dir) except OSError: if force: shutil.rmtree(work_dir) os.makedirs(work_dir) else: click.secho('The specified direcotry already exists.', fg='red') already_exist = True if not already_exist: for problem in problems: _prepare_problem(config, problem.get_url(), from_pp=True) try: cstr = config.pref['prepare']['custom_hook_command']['after'].format(dirname=work_dir.resolve()) print(cstr) subprocess.run(cstr, shell=True) except Exception as e: if config.verbose: print(e)
def main(args: Optional[List[str]] = None, *, debug: bool = False) -> Dict[str, Any]: parser = get_parser() parsed = parser.parse_args(args=args) if parsed.verbose: basicConfig(level=DEBUG) else: basicConfig(level=INFO) # do sleep to prevent impolite scraping logger.info('sleep %f sec', parsed.wait) time.sleep(parsed.wait) # parse the URL problem = dispatch.problem_from_url(getattr(parsed, 'url', '')) contest = dispatch.contest_from_url(getattr(parsed, 'url', '')) service = dispatch.service_from_url(getattr(parsed, 'url', '')) # prepare a session session = requests.Session() session.headers['User-Agent'] = parsed.user_agent # set yukicoder's token if parsed.yukicoder_token is not None: parser.error("don't use --yukicoder-token. use $YUKICODER_TOKEN") else: parsed.yukicoder_token = os.environ.get('YUKICODER_TOKEN') is_yukicoder = isinstance(problem, YukicoderProblem) or isinstance( service, YukicoderService) if parsed.yukicoder_token and is_yukicoder: session.headers['Authorization'] = 'Bearer {}'.format( parsed.yukicoder_token) # set password to login from the environment variable if parsed.subcommand == 'login-service': if parsed.password is not None: parser.error("don't use --password. use $PASSWORD") else: parsed.password = os.environ.get('PASSWORD') try: with utils.with_cookiejar(session, path=parsed.cookie) as session: result = None # type: Optional[Dict[str, Any]] schema = {} # type: Dict[str, Any] if parsed.subcommand == 'get-problem': if problem is None: raise ValueError("unsupported URL: {}".format( repr(parsed.url))) result = get_problem.main( problem, is_system=parsed.system, is_full=parsed.full, is_compatibility=parsed.compatibility, session=session) if parsed.compatibility: schema = get_problem.schema_compatibility else: schema = get_problem.schema elif parsed.subcommand == 'get-contest': if contest is None: raise ValueError("unsupported URL: {}".format( repr(parsed.url))) result = get_contest.main(contest, is_full=parsed.full, session=session) schema = get_contest.schema elif parsed.subcommand == 'get-service': if service is None: raise ValueError("unsupported URL: {}".format( repr(parsed.url))) result = get_service.main( service, does_list_contests=parsed.list_contests, session=session) schema = get_service.schema elif parsed.subcommand == 'login-service': if service is None: raise ValueError("unsupported URL: {}".format( repr(parsed.url))) result = login_service.main(service, username=parsed.username, password=parsed.password, check_only=parsed.check, session=session) schema = login_service.schema elif parsed.subcommand == 'submit-code': if problem is None: raise ValueError("unsupported URL: {}".format( repr(parsed.url))) result = submit_code.main(problem, file=parsed.file, language_id=parsed.language, session=session) schema = submit_code.schema elif parsed.subcommand is None: parser.print_help() result = None else: assert False except: etype, evalue, _ = sys.exc_info() logger.exception('%s', evalue) wrapped = { "status": "error", "messages": [ *map(lambda line: line.strip(), traceback.format_exception_only(etype, evalue)) ], "result": None, } # type: Dict[str, Any] if debug: return wrapped else: print(json.dumps(wrapped)) raise SystemExit(1) else: if result is None: # no subcommand given if debug: return { "status": "ok", "messages": [], "result": None, } else: raise SystemExit(0) wrapped = { "status": "ok", "messages": [], "result": result, } if not debug: print(json.dumps(wrapped)) try: jsonschema.validate(result, schema) except jsonschema.exceptions.ValidationError as e: logger.debug('%s', e) if debug: return wrapped else: raise SystemExit(0)
def submit(args: 'argparse.Namespace') -> None: # guess url history = onlinejudge._implementation.download_history.DownloadHistory() if args.file.parent.resolve() == pathlib.Path.cwd(): guessed_urls = history.get() else: log.warning( 'cannot guess URL since the given file is not in the current directory' ) guessed_urls = [] if args.url is None: if len(guessed_urls) == 1: args.url = guessed_urls[0] log.info('guessed problem: %s', args.url) else: log.error('failed to guess the URL to submit') log.info('please manually specify URL as: $ oj submit URL FILE') sys.exit(1) # parse url problem = onlinejudge.dispatch.problem_from_url(args.url) if problem is None: sys.exit(1) # read code with args.file.open('rb') as fh: code = fh.read() # type: bytes format_config = { 'dos2unix': args.format_dos2unix or args.golf, 'rstrip': args.format_dos2unix or args.golf, } code = format_code(code, **format_config) # report code log.info('code (%d byte):', len(code)) log.emit( utils.snip_large_file_content(code, limit=30, head=10, tail=10, bold=True)) with utils.with_cookiejar(utils.new_session_with_our_user_agent(), path=args.cookie) as sess: # guess or select language ids langs = { language.id: { 'description': language.name } for language in problem.get_available_languages(session=sess) } # type: Dict[LanguageId, Dict[str, str]] matched_lang_ids = None # type: Optional[List[str]] if args.language in langs: matched_lang_ids = [args.language] else: if args.guess: kwargs = { 'language_dict': langs, 'cxx_latest': args.guess_cxx_latest, 'cxx_compiler': args.guess_cxx_compiler, 'python_version': args.guess_python_version, 'python_interpreter': args.guess_python_interpreter, } matched_lang_ids = guess_lang_ids_of_file( args.file, code, **kwargs) if not matched_lang_ids: log.info('failed to guess languages from the file name') matched_lang_ids = list(langs.keys()) if args.language is not None: log.info( 'you can use `--no-guess` option if you want to do an unusual submission' ) matched_lang_ids = select_ids_of_matched_languages( args.language.split(), matched_lang_ids, language_dict=langs) else: if args.language is None: matched_lang_ids = None else: matched_lang_ids = select_ids_of_matched_languages( args.language.split(), list(langs.keys()), language_dict=langs) # report selected language ids if matched_lang_ids is not None and len(matched_lang_ids) == 1: args.language = matched_lang_ids[0] log.info('chosen language: %s (%s)', args.language, langs[LanguageId(args.language)]['description']) else: if matched_lang_ids is None: log.error('language is unknown') log.info('supported languages are:') elif len(matched_lang_ids) == 0: log.error('no languages are matched') log.info('supported languages are:') else: log.error('Matched languages were not narrowed down to one.') log.info('You have to choose:') for lang_id in sorted(matched_lang_ids or langs.keys()): log.emit('%s (%s)', lang_id, langs[LanguageId(lang_id)]['description']) sys.exit(1) # confirm guessed_unmatch = ([problem.get_url()] != guessed_urls) if guessed_unmatch: samples_text = ('samples of "{}'.format('", "'.join(guessed_urls)) if guessed_urls else 'no samples') log.warning( 'the problem "%s" is specified to submit, but %s were downloaded in this directory. this may be mis-operation', problem.get_url(), samples_text) if args.wait: log.status('sleep(%.2f)', args.wait) time.sleep(args.wait) if not args.yes: if guessed_unmatch: problem_id = problem.get_url().rstrip('/').split( '/')[-1].split('?')[-1] # this is too ad-hoc key = problem_id[:3] + (problem_id[-1] if len(problem_id) >= 4 else '') sys.stdout.write('Are you sure? Please type "{}" '.format(key)) sys.stdout.flush() c = sys.stdin.readline().rstrip() if c != key: log.info('terminated.') return else: sys.stdout.write('Are you sure? [y/N] ') sys.stdout.flush() c = sys.stdin.read(1) if c.lower() != 'y': log.info('terminated.') return # submit kwargs = {} if isinstance(problem, onlinejudge.service.topcoder.TopcoderLongContestProblem): if args.full_submission: kwargs['kind'] = 'full' else: kwargs['kind'] = 'example' try: submission = problem.submit_code(code, language_id=LanguageId( args.language), session=sess, **kwargs) except NotLoggedInError: log.failure('login required') sys.exit(1) except SubmissionError: log.failure('submission failed') sys.exit(1) # show result if args.open: browser = webbrowser.get() log.status('open the submission page with: %s', browser.name) opened = browser.open_new_tab(submission.get_url()) if not opened: log.failure( 'failed to open the url. please set the $BROWSER envvar')