예제 #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)
예제 #2
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))))
예제 #3
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))))
예제 #4
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)
예제 #5
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
예제 #6
0
    def __init__(self, parent=None, *args):
        super().__init__(parent, *args)
        self.browser = CustomWebEngineView(self)
        self.browser.resize(1000, 600)
        self.browser.setWindowTitle("Task")
        self.url_edit = QtWidgets.QLineEdit()
        self.url_edit.returnPressed.connect(self.loadPage)
        self.browser.urlChanged.connect(self.updateCurrentUrl)
        session = new_session_with_our_user_agent()
        self.browser.page().profile().setHttpUserAgent(
            session.headers["User-Agent"])
        self.browser.page().profile().cookieStore().cookieAdded.connect(
            self.handleCookieAdded)
        self.browser.loadFinished.connect(self.download_task)

        grid = QtWidgets.QGridLayout()
        grid.addWidget(self.url_edit, 0, 0, 1, 15)
        grid.addWidget(self.browser, 1, 0, 5, 15)
        self.setLayout(grid)
        self.resize(800, 800)
예제 #7
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')