Ejemplo n.º 1
0
 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)
Ejemplo n.º 2
0
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
Ejemplo n.º 3
0
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))))
Ejemplo n.º 4
0
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))))
Ejemplo n.º 5
0
    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

""")
Ejemplo n.º 6
0
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)
Ejemplo n.º 7
0
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
Ejemplo n.º 8
0
    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)
Ejemplo n.º 9
0
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
Ejemplo n.º 10
0
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)
Ejemplo n.º 11
0
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)
Ejemplo n.º 12
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')