def from_url(cls, s: str) -> Optional['AtCoderProblem']:
        # example: http://agc012.contest.atcoder.jp/tasks/agc012_d
        result = urllib.parse.urlparse(s)
        dirname, basename = posixpath.split(utils.normpath(result.path))
        if result.scheme in ('', 'http', 'https') \
                and result.netloc.count('.') == 3 \
                and result.netloc.endswith('.contest.atcoder.jp') \
                and result.netloc.split('.')[0] \
                and dirname == '/tasks' \
                and basename:
            contest_id = result.netloc.split('.')[0]
            problem_id = basename
            return cls(contest_id, problem_id)

        # example: https://beta.atcoder.jp/contests/abc073/tasks/abc073_a
        m = re.match(r'^/contests/([\w\-_]+)/tasks/([\w\-_]+)$',
                     utils.normpath(result.path))
        if result.scheme in ('', 'http', 'https') \
                and result.netloc in ('atcoder.jp', 'beta.atcoder.jp') \
                and m:
            contest_id = m.group(1)
            problem_id = m.group(2)
            return cls(contest_id, problem_id)

        return None
Beispiel #2
0
    def from_url(cls, s: str) -> Optional['AtCoderSubmission']:
        submission_id = None  # type: Optional[int]

        # example: http://agc001.contest.atcoder.jp/submissions/1246803
        result = urllib.parse.urlparse(s)
        dirname, basename = posixpath.split(utils.normpath(result.path))
        if result.scheme in ('', 'http', 'https') \
                and result.netloc.count('.') == 3 \
                and result.netloc.endswith('.contest.atcoder.jp') \
                and result.netloc.split('.')[0] \
                and dirname == '/submissions':
            contest_id = result.netloc.split('.')[0]
            try:
                submission_id = int(basename)
            except ValueError:
                pass
                submission_id = None
            if submission_id is not None:
                return cls(contest_id=contest_id, submission_id=submission_id)

        # example: https://beta.atcoder.jp/contests/abc073/submissions/1592381
        m = re.match(r'^/contests/([\w\-_]+)/submissions/(\d+)$', utils.normpath(result.path))
        if result.scheme in ('', 'http', 'https') \
                and result.netloc in ('atcoder.jp', 'beta.atcoder.jp') \
                and m:
            contest_id = m.group(1)
            try:
                submission_id = int(m.group(2))
            except ValueError:
                submission_id = None
            if submission_id is not None:
                return cls(contest_id=contest_id, submission_id=submission_id)

        return None
Beispiel #3
0
 def from_url(cls, url: str) -> Optional['TopcoderProblem']:
     # example: https://arena.topcoder.com/index.html#/u/practiceCode/14230/10838/10760/1/303803
     # example: https://community.topcoder.com/stat?c=problem_statement&pm=10760
     result = urllib.parse.urlparse(url)
     if result.scheme in ('', 'http', 'https'):
         if result.netloc == 'arena.topcoder.com' and utils.normpath(
                 result.path) in ('/', '/index.html'):
             dirs = utils.normpath(result.fragment).split('/')
             if len(dirs) == 8 and dirs[0] == '' and dirs[
                     1] == 'u' and dirs[2] == 'practiceCode':
                 try:
                     _ = int(dirs[3])  # round_id
                     _ = int(dirs[4])  # component_id
                     problem_id = int(dirs[5])
                     _ = int(dirs[6])  # division_id
                     _ = int(dirs[7])  # room_id
                 except ValueError:
                     pass
                 else:
                     return cls(problem_id=problem_id)
         if result.netloc == 'community.topcoder.com' and utils.normpath(
                 result.path) == '/stat':
             query = urllib.parse.parse_qs(result.query)
             if query.get('c') == ['problem_statement'] and len(
                     query.get('pm', [])) == 1:
                 try:
                     problem_id = int(query['pm'][0])
                 except ValueError:
                     pass
                 else:
                     return cls(problem_id=problem_id)
     return None
Beispiel #4
0
    def from_url(cls, url: str) -> Optional['FacebookHackerCupProblem']:
        # removed format
        # example: https://www.facebook.com/hackercup/problem/448364075989193/
        result = urllib.parse.urlparse(url)
        if result.scheme in ('', 'http', 'https') \
                and result.netloc == 'www.facebook.com' \
                and utils.normpath(result.path).startswith('/hackercup/problem/'):
            dirs = utils.normpath(result.path).split('/')
            if len(dirs) > 3 and dirs[3].isdigit():
                logger.warning(
                    'The old platform of Facebook Hacker Cup has been replaced. See https://github.com/online-judge-tools/api-client/issues/84'
                )

        # new format
        # example: https://www.facebook.com/codingcompetitions/hacker-cup/2020/qualification-round/problems/A
        dirs = utils.normpath(result.path).split('/')
        if result.scheme in ('', 'http', 'https') \
                and result.netloc == 'www.facebook.com' \
                and len(dirs) >= 7 and dirs[1] == 'codingcompetitions' and dirs[5] == 'problems':
            return cls(
                series_vanity=dirs[2],
                season_vanity=dirs[3],
                contest_vanity=dirs[4],
                display_index=dirs[6],
            )
        return None
Beispiel #5
0
    def from_url(cls, url: str) -> Optional['AOJProblem']:
        result = urllib.parse.urlparse(url)

        # example: http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=1169
        # example: http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_1_A&lang=jp
        querystring = urllib.parse.parse_qs(result.query)
        if result.scheme in ('', 'http', 'https') \
                and result.netloc == 'judge.u-aizu.ac.jp' \
                and utils.normpath(result.path) == '/onlinejudge/description.jsp' \
                and querystring.get('id') \
                and len(querystring['id']) == 1:
            n, = querystring['id']
            return cls(n)

        # example: https://onlinejudge.u-aizu.ac.jp/challenges/sources/JAG/Prelim/2881
        # example: https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/3/CGL_3_B
        m = re.match(
            r'^/(challenges|courses)/(sources|library/\d+|lesson/\d+)/(\w+)/(\w+)/(\w+)$',
            utils.normpath(result.path))
        if result.scheme in ('', 'http', 'https') \
                and result.netloc == 'onlinejudge.u-aizu.ac.jp' \
                and m:
            n = m.group(5)
            return cls(n)

        # example: https://onlinejudge.u-aizu.ac.jp/services/room.html#RitsCamp18Day3/problems/B
        # NOTE: I don't know how to retrieve the problem id

        return None
Beispiel #6
0
 def from_url(cls, url: str) -> Optional['FacebookHackerCupProblem']:
     # example: https://www.facebook.com/hackercup/problem/448364075989193/
     result = urllib.parse.urlparse(url)
     if result.scheme in ('', 'http', 'https') \
             and result.netloc == 'www.facebook.com' \
             and utils.normpath(result.path).startswith('/hackercup/problem/'):
         dirs = utils.normpath(result.path).split('/')
         if 3 < len(dirs) and dirs[3].isdigit():
             problem_id = int(dirs[3])
             return cls(problem_id=problem_id)
     return None
Beispiel #7
0
    def from_url(cls, url: str) -> Optional['FacebookHackerCupService']:
        # old format
        # example: https://www.facebook.com/hackercup/
        result = urllib.parse.urlparse(url)
        if result.scheme in ('', 'http', 'https') \
                and result.netloc == 'www.facebook.com' \
                and utils.normpath(result.path).startswith('/hackercup'):
            return cls()

        # new format
        # example: https://www.facebook.com/codingcompetitions/
        if result.scheme in ('', 'http', 'https') \
                and result.netloc == 'www.facebook.com' \
                and utils.normpath(result.path).startswith('/codingcompetitions'):
            return cls()
        return None
Beispiel #8
0
 def from_url(cls, url: str) -> Optional['CodeforcesProblem']:
     result = urllib.parse.urlparse(url)
     if result.scheme in ('', 'http', 'https') \
             and result.netloc in _CODEFORCES_DOMAINS:
         # "0" is needed. example: https://codeforces.com/contest/1000/problem/0
         # "[1-9]?" is sometime used. example: https://codeforces.com/contest/1133/problem/F2
         re_for_index = r'(0|[A-Za-z][1-9]?)'
         table = {}
         table['contest'] = r'^/contest/([0-9]+)/problem/{}$'.format(
             re_for_index
         )  # example: https://codeforces.com/contest/538/problem/H
         table['problemset'] = r'^/problemset/problem/([0-9]+)/{}$'.format(
             re_for_index
         )  # example: https://codeforces.com/problemset/problem/700/B
         table['gym'] = r'^/gym/([0-9]+)/problem/{}$'.format(
             re_for_index
         )  # example: https://codeforces.com/gym/101021/problem/A
         for kind, expr in table.items():
             m = re.match(expr, utils.normpath(result.path))
             if m:
                 if m.group(2) == '0':
                     index = 'A'  # NOTE: This is broken if there was "A1".
                 else:
                     index = m.group(2).upper()
                 return cls(contest_id=int(m.group(1)),
                            index=index,
                            kind=kind)
     return None
 def get_available_languages(
         self,
         session: Optional[requests.Session] = None) -> List[Language]:
     """
     :raises NotLoggedInError:
     """
     session = session or utils.new_default_session()
     # get
     url = 'http://{}.contest.atcoder.jp/submit'.format(self.contest_id)
     resp = _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')
         raise NotLoggedInError
     # 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.
     languages = []  # type: List[Language]
     for option in select.find_all('option'):
         languages += [Language(option.attrs['value'], option.string)]
     return languages
Beispiel #10
0
 def from_url(cls, url: str) -> Optional['GoogleCodeJamProblem']:
     # example: https://codingcompetitions.withgoogle.com/codejam/round/000000000019fd27/000000000020993c
     # example: https://codingcompetitions.withgoogle.com/kickstart/round/000000000019ffc7/00000000001d3f56
     # example: https://code.google.com/codejam/contest/7234486/dashboard
     # example: https://code.google.com/codejam/contest/7234486/dashboard#s=p0
     result = urllib.parse.urlparse(url)
     if result.scheme in ('', 'http', 'https'):
         dirs = utils.normpath(result.path).split('/')
         if result.netloc == 'codingcompetitions.withgoogle.com':
             if len(dirs) >= 5 and dirs[2] == 'round' and all(
                     c in string.hexdigits
                     for c in dirs[3]) and all(c in string.hexdigits
                                               for c in dirs[4]):
                 return cls(domain=result.netloc,
                            kind=dirs[1],
                            contest_id=dirs[3],
                            problem_id=dirs[4])
         if result.netloc == 'code.google.com':
             if len(dirs) >= 5 and dirs[2] == 'contest' and dirs[3].isdigit(
             ) and dirs[4] == 'dashboard':
                 if result.fragment == '' or re.match(
                         r'^s=p\d+$', result.fragment):
                     problem_id = (result.fragment or 's=p0')[2:]
                     return cls(domain=result.netloc,
                                kind=dirs[1],
                                contest_id=dirs[3],
                                problem_id=problem_id)
     return None
    def from_url(cls, url: str) -> Optional['AtCoderContest']:
        """
        :param url: example:

        -   https://kupc2014.contest.atcoder.jp/tasks/kupc2014_d
        -   https://atcoder.jp/contests/agc030
        """

        result = urllib.parse.urlparse(url)

        # example: https://kupc2014.contest.atcoder.jp/tasks/kupc2014_d
        if result.scheme in (
                '', 'http',
                'https') and result.hostname.endswith('.contest.atcoder.jp'):
            contest_id = utils.remove_suffix(result.hostname,
                                             '.contest.atcoder.jp')
            return cls(contest_id)

        # example: https://atcoder.jp/contests/agc030
        if result.scheme in ('', 'http', 'https') and result.hostname in (
                'atcoder.jp', 'beta.atcoder.jp'):
            m = re.match(r'/contests/([\w\-_]+)/?.*',
                         utils.normpath(result.path))
            if m:
                contest_id = m.group(1)
                return cls(contest_id)

        return None
Beispiel #12
0
 def from_url(cls, url: str) -> Optional['HackerRankProblem']:
     # example: https://www.hackerrank.com/contests/university-codesprint-2/challenges/the-story-of-a-tree
     # example: https://www.hackerrank.com/challenges/fp-hello-world
     result = urllib.parse.urlparse(url)
     if result.scheme in ('', 'http', 'https') \
             and result.netloc in ('hackerrank.com', 'www.hackerrank.com'):
         m = re.match(
             r'^/contests/([0-9A-Za-z-]+)/challenges/([0-9A-Za-z-]+)$',
             utils.normpath(result.path))
         if m:
             return cls(m.group(1), m.group(2))
         m = re.match(r'^/challenges/([0-9A-Za-z-]+)$',
                      utils.normpath(result.path))
         if m:
             return cls('master', m.group(1))
     return None
 def submit_code(self,
                 code: bytes,
                 language_id: LanguageId,
                 filename: Optional[str] = None,
                 session: Optional[requests.Session] = None) -> Submission:
     """
     :raises NotLoggedInError:
     :raises SubmissionError:
     """
     assert language_id in [
         language.id
         for language in self.get_available_languages(session=session)
     ]
     session = session or utils.new_default_session()
     # get
     url = 'http://{}.contest.atcoder.jp/submit'.format(
         self.contest_id)  # TODO: use beta.atcoder.jp
     resp = _request('GET', url, session=session)
     msgs = AtCoderService._get_messages_from_cookie(resp.cookies)
     if AtCoderService._report_messages(msgs, unexpected=True):
         raise SubmissionError
     # check whether logged in
     path = utils.normpath(urllib.parse.urlparse(resp.url).path)
     if path.startswith('/login'):
         log.error('not logged in')
         raise NotLoggedInError
     # parse
     soup = bs4.BeautifulSoup(resp.content.decode(resp.encoding),
                              utils.html_parser)
     form = soup.find('form', action=re.compile(r'^/submit\?task_id='))
     if not form:
         log.error('form not found')
         raise SubmissionError
     log.debug('form: %s', str(form))
     # post
     task_id = self._get_task_id(session=session)
     form = utils.FormSender(form, url=resp.url)
     form.set('task_id', str(task_id))
     form.set('source_code', code)
     form.set('language_id_{}'.format(task_id), str(language_id))
     resp = form.request(session=session)
     resp.raise_for_status()
     # result
     msgs = AtCoderService._get_messages_from_cookie(resp.cookies)
     AtCoderService._report_messages(msgs)
     if '/submissions/me' in resp.url:
         # example: https://practice.contest.atcoder.jp/submissions/me#32174
         # CAUTION: this URL is not a URL of the submission
         log.success('success: result: %s', resp.url)
         # NOTE: ignore the returned legacy URL and use beta.atcoder.jp's one
         url = 'https://beta.atcoder.jp/contests/{}/submissions/me'.format(
             self.contest_id)
         return utils.DummySubmission(url, problem=self)
     else:
         log.failure('failure')
         log.debug('redirected to %s', resp.url)
         raise SubmissionError('it may be a rate limit')
Beispiel #14
0
 def from_url(cls, url: str) -> Optional['AnarchyGolfProblem']:
     # example: http://golf.shinh.org/p.rb?The+B+Programming+Language
     result = urllib.parse.urlparse(url)
     if result.scheme in ('', 'http', 'https') \
             and result.netloc == 'golf.shinh.org' \
             and utils.normpath(result.path) == '/p.rb' \
             and result.query:
         return cls(problem_id=result.query)
     return None
Beispiel #15
0
 def from_url(cls, url: str) -> Optional['AOJArenaProblem']:
     # example: https://onlinejudge.u-aizu.ac.jp/services/room.html#RitsCamp19Day2/problems/A
     result = urllib.parse.urlparse(url)
     if result.scheme in ('', 'http', 'https') \
             and result.netloc == 'onlinejudge.u-aizu.ac.jp' \
             and utils.normpath(result.path) == '/services/room.html':
         fragment = result.fragment.split('/')
         if len(fragment) == 3 and fragment[1] == 'problems':
             return cls(fragment[0], fragment[2].upper())
     return None
Beispiel #16
0
 def from_url(cls, url: str) -> Optional['GoogleCodeJamService']:
     # example: https://codingcompetitions.withgoogle.com/
     # example: https://code.google.com/codejam
     result = urllib.parse.urlparse(url)
     if result.scheme in ('', 'http', 'https'):
         if result.netloc == 'codingcompetitions.withgoogle.com':
             return cls()
         if result.netloc == 'code.google.com':
             dirs = utils.normpath(result.path).split('/')
             if len(dirs) >= 2 and dirs[1] == 'codejam':
                 return cls()
     return None
Beispiel #17
0
    def from_url(cls, s: str) -> Optional['TophProblem']:
        result = urllib.parse.urlparse(s)
        dirname, basename = posixpath.split(utils.normpath(result.path))
        # example: https://toph.co/p/new-year-couple
        if result.scheme in ('', 'http', 'https') \
                and result.netloc.count('.') == 1 \
                and result.netloc.endswith('toph.co') \
                and dirname == '/p' \
                and basename:
            problem_id = basename
            return cls(problem_id)

        return None
Beispiel #18
0
 def from_url(cls, url: str) -> Optional['Contest']:
     # example: https://yukicoder.me/contests/276
     # example: http://yukicoder.me/contests/276/all
     result = urllib.parse.urlparse(url)
     dirs = utils.normpath(result.path).split('/')
     if result.scheme in ('', 'http', 'https') and result.netloc == 'yukicoder.me':
         if len(dirs) >= 3 and dirs[1] == 'contests':
             try:
                 contest_id = int(dirs[2])
             except ValueError:
                 pass
             else:
                 return cls(contest_id=contest_id)
     return None
Beispiel #19
0
 def from_url(cls, url: str) -> Optional['POJProblem']:
     # example: http://poj.org/problem?id=2104
     result = urllib.parse.urlparse(url)
     if result.scheme in ('', 'http', 'https') \
             and result.netloc == 'poj.org' \
             and utils.normpath(result.path) == '/problem':
         query = urllib.parse.parse_qs(result.query)
         if 'id' in query and len(query['id']) == 1:
             try:
                 n = int(query['id'][0])
                 return cls(n)
             except ValueError:
                 pass
     return None
Beispiel #20
0
 def from_url(cls, url: str) -> Optional['CSAcademyProblem']:
     # example: https://csacademy.com/contest/round-38/task/path-union/
     # example: https://csacademy.com/contest/round-38/task/path-union/discussion/
     # example: https://csacademy.com/contest/archive/task/swap_permutation/
     # example: https://csacademy.com/contest/archive/task/swap_permutation/statement/
     result = urllib.parse.urlparse(url)
     if result.scheme in ('', 'http', 'https') \
             and result.netloc in ('csacademy.com', 'www.csacademy.com'):
         m = re.match(
             r'^/contest/([0-9A-Za-z_-]+)/task/([0-9A-Za-z_-]+)(|/statement|/solution|/discussion|/statistics|/submissions)/?$',
             utils.normpath(result.path))
         if m:
             return cls(m.group(1), m.group(2))
     return None
Beispiel #21
0
 def from_url(cls, url: str) -> Optional['CodeforcesContest']:
     result = urllib.parse.urlparse(url)
     if result.scheme in ('', 'http', 'https') \
             and result.netloc in _CODEFORCES_DOMAINS:
         table = {}
         table['contest'] = r'/contest/([0-9]+).*'.format(
         )  # example: https://codeforces.com/contest/538
         table['gym'] = r'/gym/([0-9]+).*'.format(
         )  # example: https://codeforces.com/gym/101021
         for kind, expr in table.items():
             m = re.match(expr, utils.normpath(result.path))
             if m:
                 return cls(contest_id=int(m.group(1)), kind=kind)
     return None
Beispiel #22
0
 def from_url(cls, url: str) -> Optional['TopcoderLongContestProblem']:
     # example: https://community.topcoder.com/longcontest/?module=ViewProblemStatement&rd=16997&pm=14690
     # example: https://community.topcoder.com/longcontest/?module=ViewProblemStatement&rd=16997&compid=57374
     # example: https://community.topcoder.com/longcontest/?module=ViewStandings&rd=16997
     # example: https://community.topcoder.com/tc?module=MatchDetails&rd=16997
     result = urllib.parse.urlparse(url)
     if result.scheme in ('', 'http', 'https') \
             and result.netloc == 'community.topcoder.com' \
             and utils.normpath(result.path) in ['/longcontest', '/tc']:
         querystring = dict(urllib.parse.parse_qsl(result.query))
         if 'rd' in querystring:
             kwargs = {}
             for name in ['rd', 'cd', 'compid', 'pm']:
                 if name in querystring:
                     kwargs[name] = int(querystring[name])
             return cls(**kwargs)
     return None
Beispiel #23
0
 def from_url(cls, url: str) -> Optional['YukicoderProblem']:
     # example: https://yukicoder.me/problems/no/499
     # example: http://yukicoder.me/problems/1476
     result = urllib.parse.urlparse(url)
     dirname, basename = posixpath.split(utils.normpath(result.path))
     if result.scheme in ('', 'http', 'https') \
             and result.netloc == 'yukicoder.me':
         n = None  # type: Optional[int]
         try:
             n = int(basename)
         except ValueError:
             pass
         if n is not None:
             if dirname == '/problems/no':
                 return cls(problem_no=n)
             if dirname == '/problems':
                 return cls(problem_id=n)
     return None
Beispiel #24
0
 def from_url(cls, url: str) -> Optional['CodeforcesProblem']:
     result = urllib.parse.urlparse(url)
     if result.scheme in ('', 'http', 'https') \
             and result.netloc == 'codeforces.com':
         table = {}
         table[
             'contest'] = r'^/contest/([0-9]+)/problem/([0A-Za-z])$'  # example: https://codeforces.com/contest/538/problem/H
         table[
             'problemset'] = r'^/problemset/problem/([0-9]+)/([0A-Za-z])$'  # example: https://codeforces.com/problemset/problem/700/B
         table[
             'gym'] = r'^/gym/([0-9]+)/problem/([0A-Za-z])$'  # example: https://codeforces.com/gym/101021/problem/A
         normalize = (lambda c: c == '0' and 'A' or c.upper())
         for kind, expr in table.items():
             m = re.match(expr, utils.normpath(result.path))
             if m:
                 return cls(int(m.group(1)),
                            normalize(m.group(2)),
                            kind=kind)
     return None
Beispiel #25
0
 def from_url(cls, url: str) -> Optional['CodeforcesProblem']:
     result = urllib.parse.urlparse(url)
     if result.scheme in ('', 'http', 'https') \
             and result.netloc in _CODEFORCES_DOMAINS:
         # "0" is needed. example: https://codeforces.com/contest/1000/problem/0
         # "[1-9]?" is sometime used. example: https://codeforces.com/contest/1133/problem/F2
         re_for_index = r'(?P<index>0|[A-Za-z][1-9]?)'
         table = {}
         table[
             'contest'] = r'^/contest/(?P<contest>[0-9]+)/problem/{}$'.format(
                 re_for_index
             )  # example: https://codeforces.com/contest/538/problem/H
         table[
             'problemset'] = r'^/problemset/problem/(?P<contest>[0-9]+)/{}$'.format(
                 re_for_index
             )  # example: https://codeforces.com/problemset/problem/700/B
         table['gym'] = r'^/gym/(?P<contest>[0-9]+)/problem/{}$'.format(
             re_for_index
         )  # example: https://codeforces.com/gym/101021/problem/A
         table[
             'edu'] = r'^/edu/course/(?P<course>[0-9]*)/lesson/(?P<lesson>[0-9]*)/(?P<step>[0-9]*)/practice/contest/(?P<contest>[0-9]*)/problem/{}$'.format(
                 re_for_index
             )  # example https://codeforces.com/edu/course/2/lesson/2/1/practice/contest/269100/problem/A
         for kind, expr in table.items():
             m = re.match(expr, utils.normpath(result.path))
             if m:
                 if m.group('index') == '0':
                     index = 'A'  # NOTE: This is broken if there was "A1".
                 else:
                     index = m.group('index').upper()
                 if kind == 'edu':
                     return cls(contest_id=int(m.group('contest')),
                                index=index,
                                kind=kind,
                                course=int(m.group('course')),
                                lesson=int(m.group('lesson')),
                                step=int(m.group('step')))
                 else:
                     return cls(contest_id=int(m.group('contest')),
                                index=index,
                                kind=kind)
     return None
Beispiel #26
0
    def from_url(cls, url: str) -> Optional['KagamizContestSystemProblem']:
        result = urllib.parse.urlparse(url)

        # example: https://kcs.miz-miz.biz/contest/2000/view/A
        # example: https://kcs.miz-miz.biz/contest/2000/view/%5C
        if result.scheme in ('', 'http', 'https') \
                and result.netloc == 'kcs.miz-miz.biz':
            parts = utils.normpath(result.path).split('/')
            if len(parts) >= 5 and not parts[0] and parts[
                    1] == 'contest' and parts[3] == 'view':
                problem_id = parts[4]
                if problem_id:
                    try:
                        contest_id = int(parts[2])
                        return cls(contest_id=contest_id,
                                   problem_id=problem_id)
                    except ValueError:
                        pass

        return None