def from_url(cls, s: str) -> Optional['AOJProblem']: result = urllib.parse.urlparse(s) # 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
def from_url(cls, s, problem_id=None): # 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: submission_id = None if submission_id is not None: return cls(contest_id, submission_id, problem_id=problem_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 == '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, submission_id, problem_id=problem_id)
def from_url(cls, s, problem_id=None): # 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: submission_id = None if submission_id is not None: return cls(contest_id, submission_id, problem_id=problem_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 == "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, submission_id, problem_id=problem_id)
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
def from_url(cls, s: 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(s) 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 from_url(cls, s): # example: http://golf.shinh.org/p.rb?The+B+Programming+Language result = urllib.parse.urlparse(s) if (result.scheme in ("", "http", "https") and result.netloc == "golf.shinh.org" and utils.normpath(result.path) == "/p.rb" and result.query): return cls(result.query)
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
def from_url(cls, s): # example: http://golf.shinh.org/p.rb?The+B+Programming+Language result = urllib.parse.urlparse(s) if result.scheme in ('', 'http', 'https') \ and result.netloc == 'golf.shinh.org' \ and utils.normpath(result.path) == '/p.rb' \ and result.query: return cls(result.query)
def from_url(cls, s): # 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(s) 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))
def from_url(cls, s): # 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 result = urllib.parse.urlparse(s) 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)
def from_url(cls, s): # 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 == "beta.atcoder.jp" and m): contest_id = m.group(1) problem_id = m.group(2) return cls(contest_id, problem_id)
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
def from_url(cls, s): # 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(s) 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))
def submit_code( self, code: bytes, language: str, session: Optional[requests.Session] = None ) -> onlinejudge.type.DummySubmission: assert language in self.get_language_dict(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 SubmissionError # 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), language) 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 onlinejudge.type.DummySubmission(url) else: log.failure('failure') log.debug('redirected to %s', resp.url) raise SubmissionError
def from_url(cls, s: str) -> Optional['POJProblem']: # example: http://poj.org/problem?id=2104 result = urllib.parse.urlparse(s) 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
def from_url(cls, s): # 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 result = urllib.parse.urlparse(s) 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)
def from_url(cls, s: str) -> Optional['CodeforcesProblem']: result = urllib.parse.urlparse(s) 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
def from_url(cls, s): # 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(s) 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)
def from_url(cls, s): # 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(s) 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)
def from_url(cls, s): # example: https://yukicoder.me/problems/no/499 # example: http://yukicoder.me/problems/1476 result = urllib.parse.urlparse(s) dirname, basename = posixpath.split(utils.normpath(result.path)) if result.scheme in ("", "http", "https") and result.netloc == "yukicoder.me": try: n = int(basename) except ValueError: n = None if n is not None: if dirname == "/problems/no": return cls(problem_no=int(n)) if dirname == "/problems": return cls(problem_id=int(n)) return cls()
def submit(self, code, language, session=None): assert language in self.get_language_dict(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 = utils.request("GET", url, session=session) msgs = AtCoderService._get_messages_from_cookie(resp.cookies) if AtCoderService._report_messages(msgs, unexpected=True): return None # check whether logged in path = utils.normpath(urllib.parse.urlparse(resp.url).path) if path.startswith("/login"): log.error("not logged in") return None # 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") return None 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), language) 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 onlinejudge.submission.CompatibilitySubmission(url) else: log.failure("failure") return None
def from_url(cls, s: str) -> Optional['YukicoderProblem']: # example: https://yukicoder.me/problems/no/499 # example: http://yukicoder.me/problems/1476 result = urllib.parse.urlparse(s) 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=int(n)) if dirname == '/problems': return cls(problem_id=int(n)) return cls() return None
def from_url(cls, s): result = urllib.parse.urlparse(s) if result.scheme in ("", "http", "https") and result.netloc == "codeforces.com": table = {} table["contest"] = ( r"^/contest/([0-9]+)/problem/([0A-Za-z])$" ) # example: http://codeforces.com/contest/538/problem/H table["problemset"] = ( r"^/problemset/problem/([0-9]+)/([0A-Za-z])$" ) # example: http://codeforces.com/problemset/problem/700/B table["gym"] = ( r"^/gym/([0-9]+)/problem/([0A-Za-z])$" ) # example: http://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)