Exemplo n.º 1
0
 def login(self, get_credentials, session=None):
     session = session or utils.new_default_session()
     url = "https://practice.contest.atcoder.jp/login"
     # get
     resp = utils.request("GET",
                          url,
                          session=session,
                          allow_redirects=False)
     msgs = AtCoderService._get_messages_from_cookie(resp.cookies)
     for msg in msgs:
         log.status("message: %s", msg)
     if msgs:
         return "login" not in resp.url
     # post
     username, password = get_credentials()
     resp = utils.request(
         "POST",
         url,
         session=session,
         data={
             "name": username,
             "password": password
         },
         allow_redirects=False,
     )
     msgs = AtCoderService._get_messages_from_cookie(resp.cookies)
     AtCoderService._report_messages(msgs)
     return "login" not in resp.url  # AtCoder redirects to the top page if success
Exemplo n.º 2
0
    def download_system(self, session: Optional[requests.Session] = None) -> List[TestCase]:
        session = session or utils.new_default_session()

        # get header
        # reference: http://developers.u-aizu.ac.jp/api?key=judgedat%2Ftestcases%2F%7BproblemId%7D%2Fheader_GET
        url = 'https://judgedat.u-aizu.ac.jp/testcases/{}/header'.format(self.problem_id)
        resp = utils.request('GET', url, session=session)
        header = json.loads(resp.content)

        # get testcases via the official API
        testcases: List[TestCase] = []
        for header in header['headers']:
            # reference: http://developers.u-aizu.ac.jp/api?key=judgedat%2Ftestcases%2F%7BproblemId%7D%2F%7Bserial%7D_GET
            url = 'https://judgedat.u-aizu.ac.jp/testcases/{}/{}'.format(self.problem_id, header['serial'])
            resp = utils.request('GET', url, session=session)
            testcase = json.loads(resp.content)
            skipped = False
            for type in ('in', 'out'):
                if testcase[type].endswith('..... (terminated because of the limitation)\n'):
                    log.error('AOJ API says: terminated because of the limitation')
                    skipped = True
            if skipped:
                log.warning("skipped due to the limitation of AOJ API")
                continue
            testcases += [ TestCase(
                LabeledString(header['name'],  testcase['in']),
                LabeledString(header['name'], testcase['out']),
                ) ]
        return testcases
Exemplo n.º 3
0
 def login(self, get_credentials, session=None):
     session = session or utils.new_default_session()
     url = 'https://practice.contest.atcoder.jp/login'
     # get
     resp = utils.request('GET',
                          url,
                          session=session,
                          allow_redirects=False)
     msgs = AtCoderService._get_messages_from_cookie(resp.cookies)
     for msg in msgs:
         log.status('message: %s', msg)
     if msgs:
         return 'login' not in resp.url
     # post
     username, password = get_credentials()
     resp = utils.request('POST',
                          url,
                          session=session,
                          data={
                              'name': username,
                              'password': password
                          },
                          allow_redirects=False)
     msgs = AtCoderService._get_messages_from_cookie(resp.cookies)
     AtCoderService._report_messages(msgs)
     return 'login' not in resp.url  # AtCoder redirects to the top page if success
Exemplo n.º 4
0
 def download_with_running_code(
         self,
         session: Optional[requests.Session] = None) -> List[TestCase]:
     session = session or utils.new_default_session()
     # get
     resp = utils.request('GET', self.get_url(), session=session)
     # parse
     soup = bs4.BeautifulSoup(resp.content.decode(resp.encoding),
                              utils.html_parser)
     csrftoken = soup.find('meta', attrs={
         'name': 'csrf-token'
     }).attrs['content']
     # post
     url = 'https://www.hackerrank.com/rest/contests/{}/challenges/{}/compile_tests'.format(
         self.contest_slug, self.challenge_slug)
     payload = {'code': ':', 'language': 'bash', 'customtestcase': False}
     log.debug('payload: %s', payload)
     resp = utils.request('POST',
                          url,
                          session=session,
                          json=payload,
                          headers={'X-CSRF-Token': csrftoken})
     # parse
     it = json.loads(resp.content.decode())
     log.debug('json: %s', it)
     if not it['status']:
         log.error('Run Code: failed')
         return []
     model_id = it['model']['id']
     now = datetime.datetime.now()
     unixtime = int(datetime.datetime.now().timestamp() * 10**3)
     url = 'https://www.hackerrank.com/rest/contests/{}/challenges/{}/compile_tests/{}?_={}'.format(
         self.contest_slug, self.challenge_slug, it['model']['id'],
         unixtime)
     # sleep
     log.status('sleep(3)')
     time.sleep(3)
     # get
     resp = utils.request('GET',
                          url,
                          session=session,
                          headers={'X-CSRF-Token': csrftoken})
     # parse
     it = json.loads(resp.content.decode())
     log.debug('json: %s', it)
     if not it['status']:
         log.error('Run Code: failed')
         return []
     samples: List[TestCase] = []
     for i, (inf, outf) in enumerate(
             zip(it['model']['stdin'], it['model']['expected_output'])):
         inname = 'Testcase {} Input'.format(i)
         outname = 'Testcase {} Expected Output'.format(i)
         samples += [
             TestCase(
                 LabeledString(inname, utils.textfile(inf)),
                 LabeledString(outname, utils.textfile(outf)),
             )
         ]
     return samples
Exemplo n.º 5
0
 def submit(self, code, language, session=None):
     session = session or utils.new_default_session()
     # get
     resp = utils.request("GET", self.get_url(), session=session)
     # parse
     soup = bs4.BeautifulSoup(resp.content.decode(resp.encoding),
                              utils.html_parser)
     csrftoken = soup.find("meta", attrs={
         "name": "csrf-token"
     }).attrs["content"]
     # post
     url = "https://www.hackerrank.com/rest/contests/{}/challenges/{}/submissions".format(
         self.contest_slug, self.challenge_slug)
     payload = {"code": code, "language": language}
     log.debug("payload: %s", payload)
     resp = utils.request(
         "POST",
         url,
         session=session,
         json=payload,
         headers={"X-CSRF-Token": csrftoken},
     )
     # parse
     it = json.loads(resp.content.decode())
     log.debug("json: %s", it)
     if not it["status"]:
         log.failure("Submit Code: failed")
         return None
     model_id = it["model"]["id"]
     url = self.get_url().rstrip("/") + "/submissions/code/{}".format(
         model_id)
     log.success("success: result: %s", url)
     return onlinejudge.submission.CompatibilitySubmission(url,
                                                           problem=self)
Exemplo n.º 6
0
 def submit(self, code, language, session=None):
     session = session or utils.new_default_session()
     # get
     resp = utils.request('GET', self.get_url(), session=session)
     # parse
     soup = bs4.BeautifulSoup(resp.content.decode(resp.encoding),
                              utils.html_parser)
     csrftoken = soup.find('meta', attrs={
         'name': 'csrf-token'
     }).attrs['content']
     # post
     url = 'https://www.hackerrank.com/rest/contests/{}/challenges/{}/submissions'.format(
         self.contest_slug, self.challenge_slug)
     payload = {'code': code, 'language': language}
     log.debug('payload: %s', payload)
     resp = utils.request('POST',
                          url,
                          session=session,
                          json=payload,
                          headers={'X-CSRF-Token': csrftoken})
     # parse
     it = json.loads(resp.content.decode())
     log.debug('json: %s', it)
     if not it['status']:
         log.failure('Submit Code: failed')
         return None
     model_id = it['model']['id']
     url = self.get_url().rstrip('/') + '/submissions/code/{}'.format(
         model_id)
     log.success('success: result: %s', url)
     return onlinejudge.submission.CompatibilitySubmission(url,
                                                           problem=self)
Exemplo n.º 7
0
    def login(self,
              get_credentials: onlinejudge.type.CredentialsProvider,
              session: Optional[requests.Session] = None) -> bool:
        session = session or utils.new_default_session()
        url = 'https://toph.co/login'
        # get
        resp = utils.request('GET', url, session=session)
        if resp.url != url:  # redirected
            log.info('You are already logged in.')
            return True
        # parse
        soup = bs4.BeautifulSoup(resp.content.decode(resp.encoding),
                                 utils.html_parser)
        form = soup.find('form', class_='login-form')
        log.debug('form: %s', str(form))
        username, password = get_credentials()
        form[
            'action'] = '/login'  # to avoid KeyError inside form.request method as Toph does not have any defined action
        form = utils.FormSender(form, url=resp.url)
        form.set('handle', username)
        form.set('password', password)
        # post
        resp = form.request(session)
        resp.raise_for_status()

        resp = utils.request(
            'GET', url, session=session
        )  # Toph's Location header is not getting the expected value
        if resp.url != url:
            log.success('Welcome, %s.', username)
            return True
        else:
            log.failure('Invalid handle/email or password.')
            return False
Exemplo n.º 8
0
    def submit_code(self, code: bytes, language: str, session: Optional[requests.Session] = None, kind: str = 'example') -> onlinejudge.type.Submission:
        assert kind in [ 'example', 'full' ]
        session = session or utils.new_default_session()

        # module=MatchDetails
        url = 'https://community.topcoder.com/tc?module=MatchDetails&rd=%d' % self.rd
        resp = utils.request('GET', url, session=session)
        soup = bs4.BeautifulSoup(resp.content.decode(resp.encoding), utils.html_parser)
        path = soup.find('a', text='Register/Submit').attrs['href']
        assert path.startswith('/') and 'module=ViewReg' in path

        # module=ViewActiveContests
        url = 'https://community.topcoder.com' + path
        resp = utils.request('GET', url, session=session)
        soup = bs4.BeautifulSoup(resp.content.decode(resp.encoding), utils.html_parser)
        path = [ tag.attrs['href'] for tag in soup.find_all('a', text='Submit') if ('rd=%d' % self.rd) in tag.attrs['href'] ]
        if len(path) == 0:
            log.error('link to submit not found:  Are you logged in?  Are you registered?  Is the contest running?')
            raise onlinejudge.type.SubmissionError
        assert len(path) == 1
        path = path[0]
        assert path.startswith('/') and 'module=Submit' in path
        query = dict(urllib.parse.parse_qsl(urllib.parse.urlparse(path).query))
        self.cd     = query['cd']
        self.compid = query['compid']

        # module=Submit
        submit_url = 'https://community.topcoder.com' + path
        resp = utils.request('GET', submit_url, session=session)
        soup = bs4.BeautifulSoup(resp.content.decode(resp.encoding), utils.html_parser)

        # post
        url = 'https://community.topcoder.com/longcontest/'
        language_id = self.get_language_dict(session=session)[language]['value']
        data = {
            'module': 'Submit',
            'rd': self.rd,
            'cd': self.cd,
            'compid': self.compid,
            'Action': 'submit',
            'exOn': { 'example': 'true', 'full': 'false' }[kind],
            'lid': language_id,
            'code': code,
        }
        resp = utils.request('POST', url, session=session, data=data)

        # check if module=SubmitSuccess
        if 'module=SubmitSuccess' in resp.content.decode(resp.encoding):
            url = 'http://community.topcoder.com/longcontest/?module=SubmitSuccess&rd={}&cd={}&compid={}'.format(self.rd, self.cd, self.compid)
            log.success('success: result: %s', url)
            return onlinejudge.type.CompatibilitySubmission(url, self)
        else:
            # module=Submit to get error messages
            resp = utils.request('GET', submit_url, session=session)
            soup = bs4.BeautifulSoup(resp.content.decode(resp.encoding), utils.html_parser)
            messages = soup.find('textarea', { 'name': 'messages' }).text
            log.failure('%s', messages)
            raise onlinejudge.type.SubmissionError
Exemplo n.º 9
0
    def download(self, session: Optional[requests.Session] = None) -> List[TestCase]:
        session = session or utils.new_default_session()
        base_url = self.get_url()

        # get csrftoken
        resp = utils.request('GET', base_url, session=session)
        csrftoken = None
        for cookie in session.cookies:
            if cookie.name == 'csrftoken' and cookie.domain == 'csacademy.com':  # type: ignore
                csrftoken = cookie.value  # type: ignore
        if csrftoken is None:
            log.error('csrftoken is not found')
            return []

        # get config
        headers = {
                'x-csrftoken': csrftoken,
                'x-requested-with': 'XMLHttpRequest',
            }
        contest_url = 'https://csacademy.com/contest/{}/'.format(self.contest_name)
        resp = utils.request('GET', contest_url, session=session, headers=headers)
        # parse config
        assert resp.encoding is None
        config = json.loads( resp.content.decode() ) # NOTE: Should I memoize this? Is the CSAcademyRound class required?
        task_config = None
        for it in config['state']['contesttask']:
            if it['name'] == self.task_name:
                task_config = it
        if task_config is None:
            log.error('no such task: %s', self.task_name)
            return []

        # get
        get_contest_task_url = 'https://csacademy.com/contest/get_contest_task/'
        payload = { 'contestTaskId': ( None, str(task_config['id']))  }
        headers = {
                'x-csrftoken': csrftoken,
                'x-requested-with': 'XMLHttpRequest',
                'Referer': base_url,
            }
        resp = utils.request('POST', get_contest_task_url, session=session, files=payload, headers=headers)
        # parse
        assert resp.encoding is None
        contest_task = json.loads( resp.content.decode() ) # NOTE: Should I memoize this?
        if contest_task.get('title') == 'Page not found':
            log.error('something wrong')
            return []
        samples = []
        for test_number, example_test in enumerate(contest_task['state']['EvalTask'][0]['exampleTests']):
            inname  = 'Input {}'.format(test_number)
            outname = 'Output {}'.format(test_number)
            samples += [ TestCase(
                LabeledString( inname, example_test[ 'input']),
                LabeledString(outname, example_test['output']),
                ) ]
        return samples
Exemplo n.º 10
0
 def download_samples(
         self,
         session: Optional[requests.Session] = None) -> List[TestCase]:
     session = session or utils.new_default_session()
     # get
     resp = utils.request('GET', self.get_url(), session=session)
     # parse
     soup = bs4.BeautifulSoup(
         resp.content, utils.html_parser
     )  # NOTE: resp.content is not decoded for workaround, see https://github.com/kmyk/online-judge-tools/pull/186
     samples = utils.SampleZipper()
     for pre in soup.find_all('pre'):
         log.debug('pre: %s', str(pre))
         hn = utils.previous_sibling_tag(pre)
         if hn is None:
             div = pre.parent
             if div is not None:
                 log.debug('div: %s', str(hn))
                 hn = utils.previous_sibling_tag(div)
         log.debug('hN: %s', str(hn))
         log.debug(hn)
         keywords = ['sample', 'example', '入力例', '出力例']
         if hn and hn.name in ['h2', 'h3'] and hn.string and any(
                 filter(lambda keyword: keyword in hn.string.lower(),
                        keywords)):
             s = utils.textfile(pre.string.lstrip())
             name = hn.string
             samples.add(s, name)
     return samples.get()
Exemplo n.º 11
0
 def download_system_cases(self, session: Optional[requests.Session] = None) -> List[TestCase]:
     session = session or utils.new_default_session()
     # get
     # example: https://www.hackerrank.com/rest/contests/hourrank-1/challenges/beautiful-array/download_testcases
     url = 'https://www.hackerrank.com/rest/contests/{}/challenges/{}/download_testcases'.format(self.contest_slug, self.challenge_slug)
     resp = utils.request('GET', url, session=session, raise_for_status=False)
     if resp.status_code != 200:
         log.error('response: %s', resp.content.decode())
         return []
     # parse
     with zipfile.ZipFile(io.BytesIO(resp.content)) as fh:
         # list names
         names = []  # type: List[str]
         pattern = re.compile(r'(in|out)put/\1put(\d+).txt')
         for filename in sorted(fh.namelist()):  # "input" < "output"
             if filename.endswith('/'):
                 continue
             log.debug('filename: %s', filename)
             m = pattern.match(filename)
             assert m
             if m.group(1) == 'in':
                 names += [m.group(2)]
         # zip samples
         samples = []  # type: List[TestCase]
         for name in names:
             inpath = 'input/input{}.txt'.format(name)
             outpath = 'output/output{}.txt'.format(name)
             indata = fh.read(inpath).decode()
             outdata = fh.read(outpath).decode()
             samples += [TestCase(LabeledString(inpath, indata), LabeledString(outpath, outdata))]
         return samples
Exemplo n.º 12
0
 def login(self, get_credentials: onlinejudge.type.CredentialsProvider, session: Optional[requests.Session] = None) -> bool:
     session = session or utils.new_default_session()
     url = 'https://www.hackerrank.com/auth/login'
     # get
     resp = utils.request('GET', url, session=session)
     if resp.url != url:
         log.debug('redirected: %s', resp.url)
         log.info('You have already signed in.')
         return True
     # parse
     soup = bs4.BeautifulSoup(resp.content.decode(resp.encoding), utils.html_parser)
     csrftoken = soup.find('meta', attrs={'name': 'csrf-token'}).attrs['content']
     tag = soup.find('input', attrs={'name': 'username'})
     while tag.name != 'form':
         tag = tag.parent
     form = tag
     # post
     username, password = get_credentials()
     form = utils.FormSender(form, url=resp.url)
     form.set('login', username)
     form.set('password', password)
     form.set('remember_me', 'true')
     form.set('fallback', 'true')
     resp = form.request(session, method='POST', action='/rest/auth/login', headers={'X-CSRF-Token': csrftoken})
     resp.raise_for_status()
     log.debug('redirected: %s', resp.url)
     # result
     if '/auth' not in resp.url:
         log.success('You signed in.')
         return True
     else:
         log.failure('You failed to sign in. Wrong user ID or password.')
         return False
Exemplo n.º 13
0
 def submit_code(self, code: bytes, language: str, session: Optional['requests.Session'] = None) -> onlinejudge.type.Submission:  # or SubmissionError
     session = session or utils.new_default_session()
     # get
     resp = utils.request('GET', self.get_url(), session=session)
     # parse
     soup = bs4.BeautifulSoup(resp.content.decode(resp.encoding), utils.html_parser)
     form = soup.find('form', class_='submitForm')
     if form is None:
         log.error('not logged in')
         raise SubmissionError
     log.debug('form: %s', str(form))
     # make data
     form = utils.FormSender(form, url=resp.url)
     form.set('programTypeId', language)
     form.set_file('sourceFile', 'code', code)
     resp = form.request(session=session)
     resp.raise_for_status()
     # result
     if resp.url.endswith('/my'):
         # example: https://codeforces.com/contest/598/my
         log.success('success: result: %s', resp.url)
         return onlinejudge.type.DummySubmission(resp.url)
     else:
         log.failure('failure')
         log.debug('redirected to %s', resp.url)
         # parse error messages
         soup = bs4.BeautifulSoup(resp.content.decode(resp.encoding), utils.html_parser)
         for span in soup.findAll('span', class_='error'):
             log.warning('Codeforces says: "%s"', span.string)
         raise SubmissionError
Exemplo n.º 14
0
 def download_sample_cases(
     self,
     session: Optional[requests.Session] = None
 ) -> List[onlinejudge.type.TestCase]:
     session = session or utils.new_default_session()
     resp = utils.request('GET', self.get_url(), session=session)
     soup = bs4.BeautifulSoup(resp.content.decode(resp.encoding),
                              utils.html_parser)
     samples = utils.SampleZipper()
     for case in soup.find('table',
                           class_="samples").find('tbody').find_all('tr'):
         log.debug('case: %s', str(case))
         assert len(list(case.children))
         input_pre, output_pre = list(
             map(lambda td: td.find('pre'), list(case.children)))
         assert input_pre.name == 'pre'
         assert output_pre.name == 'pre'
         assert re.search("^preSample.*Input$", input_pre.attrs['id'])
         assert re.search("^preSample.*Output$", output_pre.attrs['id'])
         s = input_pre.get_text()
         s = s.lstrip()
         samples.add(s, "Input")
         s = output_pre.get_text()
         s = s.lstrip()
         samples.add(s, "Output")
     return samples.get()
Exemplo n.º 15
0
 def download(self, session=None):
     session = session or utils.new_default_session()
     # get
     resp = utils.request('GET', self.get_url(), session=session)
     msgs = AtCoderService._get_messages_from_cookie(resp.cookies)
     if AtCoderService._report_messages(msgs, unexpected=True):
         # example message: "message: You cannot see this page."
         log.warning('are you logged in?')
         return []
     # parse
     soup = bs4.BeautifulSoup(resp.content.decode(resp.encoding),
                              utils.html_parser)
     samples = utils.SampleZipper()
     lang = None
     for pre, h3 in self._find_sample_tags(soup):
         s = utils.textfile(utils.dos2unix(pre.string.lstrip()))
         name = h3.string
         l = self._get_tag_lang(pre)
         if lang is None:
             lang = l
         elif lang != l:
             log.info(
                 'skipped due to language: current one is %s, not %s: %s ',
                 lang, l, name)
             continue
         samples.add(s, name)
     return samples.get()
Exemplo n.º 16
0
 def get_language_dict(self, session=None):
     session = session or utils.new_default_session()
     # get
     url = 'http://{}.contest.atcoder.jp/submit'.format(self.contest_id)
     resp = utils.request('GET', url, session=session)
     msgs = AtCoderService._get_messages_from_cookie(resp.cookies)
     if AtCoderService._report_messages(msgs, unexpected=True):
         return {}
     # check whether logged in
     path = utils.normpath(urllib.parse.urlparse(resp.url).path)
     if path.startswith('/login'):
         log.error('not logged in')
         return {}
     # parse
     soup = bs4.BeautifulSoup(resp.content.decode(resp.encoding),
                              utils.html_parser)
     select = soup.find(
         'select', class_='submit-language-selector'
     )  # NOTE: AtCoder can vary languages depending on tasks, even in one contest. here, ignores this fact.
     language_dict = {}
     for option in select.find_all('option'):
         language_dict[option.attrs['value']] = {
             'description': option.string
         }
     return language_dict
Exemplo n.º 17
0
    def get_standings(self, session: Optional[requests.Session] = None) -> onlinejudge.type.Standings:
        session = session or utils.new_default_session()

        header = None  # type: Optional[List[str]]
        rows = []  # type: List[Dict[str, str]]
        for start in itertools.count(1, 100):
            # get
            url = 'https://community.topcoder.com/longcontest/?sc=&sd=&nr=100&sr={}&rd={}&module=ViewStandings'.format(start, self.rd)
            resp = utils.request('GET', url, session=session)

            # parse
            soup = bs4.BeautifulSoup(resp.content.decode(resp.encoding), utils.html_parser)
            table = soup.find('table', class_='statTable')
            trs = table.find_all('tr')
            if header is None:
                tr = trs[1]
                header = [ td.text.strip() for td in tr.find_all('td') ]
            for tr in trs[2 :]:
                row = collections.OrderedDict()  # type: Dict[str, str]
                for key, td in zip(header, tr.find_all('td')):
                    value = td.text.strip()
                    if not value:
                        value = None
                    elif value.isdigit():
                        value = int(value)
                    row[key] = value
                rows += [ row ]

            # check whether the next page exists
            link = soup.find('a', text='next >>')
            if link is None:
                break

        assert header is not None
        return header, rows
Exemplo n.º 18
0
 def download_samples(self, session=None):
     session = session or utils.new_default_session()
     # get
     resp = utils.request('GET', self.get_url(), session=session)
     # parse
     soup = bs4.BeautifulSoup(resp.content.decode(resp.encoding),
                              utils.html_parser)
     samples = utils.SampleZipper()
     for pre in soup.find_all('pre'):
         log.debug('pre: %s', str(pre))
         hn = utils.previous_sibling_tag(pre)
         if hn is None:
             div = pre.parent
             if div is not None:
                 log.debug('div: %s', str(hn))
                 hn = utils.previous_sibling_tag(div)
         log.debug('hN: %s', str(hn))
         log.debug(hn)
         keywords = ['sample', 'example', '入力例', '出力例']
         if hn and hn.name in ['h2', 'h3'] and hn.string and any(
                 filter(lambda keyword: keyword in hn.string.lower(),
                        keywords)):
             s = utils.textfile(pre.string.lstrip())
             name = hn.string
             samples.add(s, name)
     return samples.get()
Exemplo n.º 19
0
 def login_with_github(self, get_credentials, session=None):
     session = session or utils.new_default_session()
     url = "https://yukicoder.me/auth/github"
     # get
     resp = utils.request("GET", url, session=session)
     if urllib.parse.urlparse(resp.url).hostname == "yukicoder.me":
         log.info("You have already signed in.")
         return True
     # redirect to github.com
     # parse
     soup = bs4.BeautifulSoup(resp.content.decode(resp.encoding), utils.html_parser)
     form = soup.find("form")
     if not form:
         log.error("form not found")
         log.info("Did you logged in?")
         return False
     log.debug("form: %s", str(form))
     # post
     username, password = get_credentials()
     form = utils.FormSender(form, url=resp.url)
     form.set("login", username)
     form.set("password", password)
     resp = form.request(session)
     resp.raise_for_status()
     if urllib.parse.urlparse(resp.url).hostname == "yukicoder.me":
         log.success("You signed in.")
         return True
     else:
         log.failure("You failed to sign in. Wrong user ID or password.")
         return False
Exemplo n.º 20
0
 def login(self,
           get_credentials: onlinejudge.service.CredentialsProvider,
           session: Optional[requests.Session] = None) -> bool:
     session = session or utils.new_default_session()
     url = 'https://codeforces.com/enter'
     # get
     resp = utils.request('GET', url, session=session)
     if resp.url != url:  # redirected
         log.info('You have already signed in.')
         return True
     # parse
     soup = bs4.BeautifulSoup(resp.content.decode(resp.encoding),
                              utils.html_parser)
     form = soup.find('form', id='enterForm')
     log.debug('form: %s', str(form))
     username, password = get_credentials()
     form = utils.FormSender(form, url=resp.url)
     form.set('handleOrEmail', username)
     form.set('password', password)
     form.set('remember', 'on')
     # post
     resp = form.request(session)
     resp.raise_for_status()
     if resp.url != url:  # redirected
         log.success('Welcome, %s.', username)
         return True
     else:
         log.failure('Invalid handle or password.')
         return False
Exemplo n.º 21
0
 def download(
     self,
     session: Optional[requests.Session] = None
 ) -> List[onlinejudge.problem.TestCase]:
     session = session or utils.new_default_session()
     # get
     resp = utils.request('GET', self.get_url(), session=session)
     # parse
     soup = bs4.BeautifulSoup(resp.content.decode(resp.encoding),
                              utils.html_parser)
     samples = utils.SampleZipper()
     for tag in soup.find_all('div', class_=re.compile(
             '^(in|out)put$')):  # Codeforces writes very nice HTML :)
         log.debug('tag: %s', str(tag))
         assert len(list(tag.children))
         title, pre = list(tag.children)
         assert 'title' in title.attrs['class']
         assert pre.name == 'pre'
         s = ''
         for it in pre.children:
             if it.name == 'br':
                 s += '\n'
             else:
                 s += it.string
         s = s.lstrip()
         samples.add(s, title.string)
     return samples.get()
Exemplo n.º 22
0
 def login_with_github(
         self,
         get_credentials: onlinejudge.type.CredentialsProvider,
         session: Optional[requests.Session] = None) -> bool:
     session = session or utils.new_default_session()
     url = 'https://yukicoder.me/auth/github'
     # get
     resp = utils.request('GET', url, session=session)
     if urllib.parse.urlparse(resp.url).hostname == 'yukicoder.me':
         log.info('You have already signed in.')
         return True
     # redirect to github.com
     # parse
     soup = bs4.BeautifulSoup(resp.content.decode(resp.encoding),
                              utils.html_parser)
     form = soup.find('form')
     if not form:
         log.error('form not found')
         log.info('Did you logged in?')
         return False
     log.debug('form: %s', str(form))
     # post
     username, password = get_credentials()
     form = utils.FormSender(form, url=resp.url)
     form.set('login', username)
     form.set('password', password)
     resp = form.request(session)
     resp.raise_for_status()
     if urllib.parse.urlparse(resp.url).hostname == 'yukicoder.me':
         log.success('You signed in.')
         return True
     else:
         log.failure('You failed to sign in. Wrong user ID or password.')
         return False
Exemplo n.º 23
0
 def download_system_cases(
         self,
         session: Optional[requests.Session] = None) -> List[TestCase]:
     session = session or utils.new_default_session()
     # get
     url = 'https://yukicoder.me/problems/no/{}/testcase.zip'.format(
         self.problem_no)
     resp = utils.request('GET', url, session=session)
     # parse
     basenames = collections.defaultdict(
         dict)  # type: Dict[str, Dict[str, LabeledString]]
     with zipfile.ZipFile(io.BytesIO(resp.content)) as fh:
         for filename in sorted(fh.namelist()):  # "test_in" < "test_out"
             dirname = os.path.dirname(filename)
             basename = os.path.basename(filename)
             kind = {'test_in': 'input', 'test_out': 'output'}[dirname]
             content = fh.read(filename).decode()
             name = basename
             if os.path.splitext(
                     name)[1] == '.in':  # ".in" extension is confusing
                 name = os.path.splitext(name)[0]
             basenames[basename][kind] = LabeledString(name, content)
     samples = []  # type: List[TestCase]
     for basename in sorted(basenames.keys()):
         data = basenames[basename]
         if 'input' not in data or 'output' not in data or len(data) != 2:
             log.error('dangling sample found: %s', str(data))
         else:
             samples += [TestCase(data['input'], data['output'])]
     return samples
Exemplo n.º 24
0
 def login(self, get_credentials, session=None):
     session = session or utils.new_default_session()
     url = "http://codeforces.com/enter"
     # get
     resp = utils.request("GET", url, session=session)
     if resp.url != url:  # redirected
         log.info("You have already signed in.")
         return True
     # parse
     soup = bs4.BeautifulSoup(resp.content.decode(resp.encoding),
                              utils.html_parser)
     form = soup.find("form", id="enterForm")
     log.debug("form: %s", str(form))
     username, password = get_credentials()
     form = utils.FormSender(form, url=resp.url)
     form.set("handleOrEmail", username)
     form.set("password", password)
     form.set("remember", "on")
     # post
     resp = form.request(session)
     resp.raise_for_status()
     if resp.url != url:  # redirected
         log.success("Welcome, %s.", username)
         return True
     else:
         log.failure("Invalid handle or password.")
         return False
Exemplo n.º 25
0
 def download_sample_cases(
     self,
     session: Optional[requests.Session] = None
 ) -> List[onlinejudge.type.TestCase]:
     session = session or utils.new_default_session()
     # get
     url = self.get_url(contests=False) + '/file/statement/samples.zip'
     resp = utils.request('GET',
                          url,
                          session=session,
                          raise_for_status=False)
     if resp.status_code == 404:
         log.warning('samples.zip not found')
         log.info(
             'this 404 happens in both cases: 1. no sample cases as intended; 2. just an error'
         )
         return []
     resp.raise_for_status()
     # parse
     with zipfile.ZipFile(io.BytesIO(resp.content)) as fh:
         samples = []  # type: List[TestCase]
         for filename in sorted(fh.namelist()):
             log.debug('filename: %s', filename)
             if filename.endswith('.in'):
                 inpath = filename
                 outpath = filename[:-3] + '.ans'
                 indata = fh.read(inpath).decode()
                 outdata = fh.read(outpath).decode()
                 samples += [
                     TestCase(LabeledString(inpath, indata),
                              LabeledString(outpath, outdata))
                 ]
         return samples
Exemplo n.º 26
0
 def is_logged_in(self, session: Optional[requests.Session] = None) -> bool:
     session = session or utils.new_default_session()
     url = 'https://toph.co/login'
     resp = utils.request('GET',
                          url,
                          session=session,
                          allow_redirects=False)
     return resp.status_code != 200
Exemplo n.º 27
0
 def get_input_format(self, session=None):
     session = session or utils.new_default_session()
     # get
     resp = utils.request("GET", self.get_url(), session=session)
     # parse
     soup = bs4.BeautifulSoup(resp.content.decode(resp.encoding), utils.html_parser)
     for h4 in soup.find_all("h4"):
         if h4.string == "入力":
             return h4.parent.find("pre").string
Exemplo n.º 28
0
 def get_input_format(self, session: Optional[requests.Session] = None) -> Optional[str]:
     session = session or utils.new_default_session()
     # get
     resp = utils.request('GET', self.get_url(), session=session)
     # parse
     soup = bs4.BeautifulSoup(resp.content.decode(resp.encoding), utils.html_parser)
     for h4 in soup.find_all('h4'):
         if h4.string == '入力':
             return h4.parent.find('pre').string
     return None
Exemplo n.º 29
0
 def is_logged_in(self,
                  session: Optional[requests.Session] = None,
                  method: Optional[str] = None) -> bool:
     session = session or utils.new_default_session()
     url = 'https://yukicoder.me/auth/github'
     resp = utils.request('GET',
                          url,
                          session=session,
                          allow_redirects=False)
     assert resp.status_code == 302
     return 'oauth' not in resp.headers['Location']
Exemplo n.º 30
0
 def _get_model(self, session: Optional[requests.Session] = None) -> Dict[str, Any]:
     session = session or utils.new_default_session()
     # get
     url = 'https://www.hackerrank.com/rest/contests/{}/challenges/{}'.format(self.contest_slug, self.challenge_slug)
     resp = utils.request('GET', url, session=session)
     # parse
     it = json.loads(resp.content.decode())
     log.debug('json: %s', it)
     if not it['status']:
         log.error('get model: failed')
         raise onlinejudge.type.SubmissionError
     return it['model']