def get_problem(problem_code, abort_on_error=False): url = "http://opc.iarcs.org.in/index.php/problems/" + problem_code j = {"error": None, "judge": "iarcs", "problem_code": problem_code} try: r = requests.get(url) soup = BeautifulSoup(r.text, "html.parser") display.check_response_status(r, abort=abort_on_error) except SystemExit: sys.exit() except BaseException: display.url_error(url, abort=abort_on_error) j["error"] = "urlerror" else: j["body"] = str(soup.find(id='maincontent')) iocandidate = soup.find_all("pre") sample_inputs, sample_outputs = extract_io(iocandidate) sample_io = {} sample_io["inputs"] = sample_inputs sample_io["outputs"] = sample_outputs if(len(sample_inputs) == len(sample_outputs)): sample_io["error"] = None else: sample_io["error"] = "sample io not equal" j["sample_io"] = sample_io return j
def login(username, password): global codechef_session login_url = url + "/" try: login_page = codechef_session.get(login_url) except BaseException: display.url_error(login_url, abort=True) form_feilds = BeautifulSoup(login_page.text, "html.parser").findAll("input") form_data = {"pass": password, "name": username} for i in form_feilds: attrs = i.attrs if "name" in attrs: if "value" in attrs and attrs["value"]: form_data[attrs["name"]] = attrs["value"] try: logged_page = codechef_session.post(login_url, form_data) except BaseException: display.url_error(login_url, abort=True) else: # logout all other sessions as codechef doesn't allow multiple sessions if ("session/limit" in logged_page.url): click.confirm("Session limit exceeded\n" + "Do you want to logout of other sessions", default=True, abort=True) display.normal("logging you out of all other sessions\n" + "this may take some time...") while "session/limit" in logged_page.url: logout_other_session() logged_page = codechef_session.post(url, form_data) # codechef doesn't check cookies and trivially displays # the latest as current session # handle this using modifying logout_other_session by # logging out after checking session cookies # and matching with form data. trivially the following solution works logged_page = codechef_session.post(url, form_data) if len( BeautifulSoup(logged_page.text, "html.parser").findAll( "input")) > 0 and is_logged_in(ensure=True): click.confirm(style.error( "You are/have tried to login to codechef while" + "the script was running\nDo you want to try login again?"), default=True, abort=True) login(username, password) else: if (is_logged_in(ensure=True)): if (cookies.save(codechef_session)): return True else: display.credential_error("codechef", abort=True)
def logout(): global iarcs_session logout_url = url + "index.php/auth/logout" try: # no need to store in a variable iarcs_session.get(logout_url) except BaseException: display.url_error(logout_url, abort=True) else: if (cookies.delete()): return True else: return None
def logout(): global codechef_session logout_url = url + "/logout" try: # no need to assign to a variable codechef_session.get(logout_url) except BaseException: display.url_error(logout_url, abort=True) else: if (cookies.delete()): return True else: return None
def login(username, password): login_url = url + "index.php/auth/login" global iarcs_session form_data = {"username": username, "password": password, "redirectto": "/"} try: logged_page = iarcs_session.post(login_url, form_data) except BaseException: display.url_error(login_url, abort=True) else: if (is_logged_in(ensure=True, passed_page=logged_page)): if (cookies.save(iarcs_session)): return True else: display.credential_error("iarcs", abort=True)
def get_problem(problem_code, contest_code, abort): codechef_session = session.codechef_session # works on the fact that sample io will be inside pre tag and if more than # 1 sample than more than 1 pre tag url = "https://www.codechef.com/api/contests/" + contest_code +\ "/problems/" + problem_code j = { "error": None, "judge": "codechef", "contest_code": contest_code, "problem_code": problem_code } try: r = codechef_session.get(url) j.update(r.json()) except BaseException: j["error"] = "urlerror" click.echo('') display.url_error(url, abort=abort) else: if (j["status"] == "error"): click.echo('') click.echo("codechef returned following error:") display.error(j["message"]) display.normal( "There may be a problem with the problem code/contest code." + "\nPlease check and try again") if (abort): sys.exit() else: soup = BeautifulSoup(j['body'], "html.parser") pre_tag_elements = soup.find_all('pre') pre_tag_count = len(pre_tag_elements) sample_io = {} if pre_tag_count >= 1: sample_inputs, sample_outputs = extract_io( pre_tag_elements, url) sample_io["inputs"] = sample_inputs sample_io["outputs"] = sample_outputs sample_io["error"] = None else: sample_io["error"] = "Out of Scope" display.error("WARNING:the sample testcases of problem " + problem_code + " could not be extrated properly,\n" + "please have a look at the testcases folder") j["sample_io"] = sample_io return j
def get_contest(contest_code, abort): codechef_session = session.codechef_session url = "https://www.codechef.com/api/contests/" + contest_code j = {"error": None, "judge": "codechef", "contest_code": contest_code} try: r = codechef_session.get(url) j.update(r.json()) except BaseException: j["error"] = "urlerror" click.echo("") display.url_error(url, abort=abort) if ("error" in j["status"]): display.error("\n" + j["message"]) if (abort): raise click.Abort return j
def check_status(code): delay = 1 iarcs_session = session.iarcs_session url = "http://opc.iarcs.org.in/index.php/results/"+str(code) status = "compiling" while("running" in status.lower() or "compiling" in status.lower()): try: r = iarcs_session.get(url) except BaseException: display.url_error(url, abort=True) soup = BeautifulSoup(r.text, "html.parser") body = soup.find(id="maincontent") status = body.findAll("p")[1].text.split(' ', 1)[1] time.sleep(delay) points = body.findAll("p")[2].text.rsplit(' ', 1)[1] return status, points
def logout_other_session(): global codechef_session sess_url = url + "/session/limit" try: session_page = codechef_session.get(sess_url) except BaseException: display.url_error(sess_url, abort=True) form_feilds = BeautifulSoup(session_page.text, "html.parser").findAll("input") form_data = {} for j in [0, -1, -2, -3, -4]: i = form_feilds[j] attrs = i.attrs if "name" in attrs: if "value" in attrs and attrs["value"]: form_data[attrs["name"]] = attrs["value"] try: # no need to assign to a variable codechef_session.post(sess_url, data=form_data) except BaseException: display.url_error(sess_url, abort=True)
def get_problem_list(): iarcs_session = session.iarcs_session logged_in = (session.is_logged_in()) url = "http://opc.iarcs.org.in/index.php/problems/" try: r = iarcs_session.get(url) soup = BeautifulSoup(r.text, "html.parser") except BaseException: display.url_error(url, abort=True) else: unsolved_list = [] problem_rows = soup.find_all("tr")[1:-1] # 0th row contains heading for problem in problem_rows: row_data = problem.find_all("td") code_data, problem_data = row_data[1], row_data[2] status = None if(logged_in): status = row_data[3].text if(not status): unsolved_list.append({"problem_code": code_data.a.text, "problem_name": problem_data.a.text}) return unsolved_list
def get_contest_list(): codechef_session = session.codechef_session url = "https://www.codechef.com/api/runningUpcomingContests/data" j = {"error": None, "judge": "codechef", "others": None} try: page = codechef_session.get(url) j.update(page.json()) except BaseException: j["error"] = "urlerror" display.url_error(url, abort=True) # try to add other contests (PRACTICE,ZCO etc) # (for which submissions are allowed) others = None try: url = "https://www.codechef.com/api/allowed/contests" page = codechef_session.get(url) others = page.json() j["others"] = others except BaseException: pass return j
def get_practice_problems(catagory, abort): catagory = str(catagory) codechef_session = session.codechef_session url = "https://www.codechef.com/problems/" + catagory j = {"error": None, "judge": "codechef", "contest_code": "PRACTICE"} data = {"sort_by": "SucessfulSubmission", "sorting_order": "desc"} try: practice_page = codechef_session.get(url, data=data) except BaseException: j["error"] = "urlerror" click.echo("") display.url_error(url, abort=abort) else: soup = BeautifulSoup(practice_page.text, 'html.parser') problem_rows = soup.find_all('tr', class_='problemrow') problems = {} problemsstats = {'attempted': {}, 'partially_solved': {}, 'solved': {}} for problem_row in problem_rows: problem_data = problem_row.find_all('td') # TODO partially implimented dictionary... may lead to error problem = { 'code': problem_data[1].get_text(strip=True), 'name': problem_data[0].get_text(strip=True), 'type': "1" if catagory.lower() == "challenge" else "3", 'successful_submissions': problem_data[2].get_text(strip=True), 'allow_submissions': True, 'accuracy': problem_data[3].get_text(strip=True), } problems[problem['code']] = problem try: if ('green' in problem_data[0].a['style']): # solved problemsstats['attempted'][problem['code']] = True problemsstats['solved'][problem['code']] = True elif ('red' in problem_data[0].a['style']): # wrong problemsstats['attempted'][problem['code']] = True else: # TODO partially solved problem...to be handled later # TODO assinging 30 for convienence change later problemsstats['attempted'][problem['code']] = True problemsstats['partially_solved'][problem['code']] = 30 except BaseException: # unsolved problems pass # the dictionary to be returned..similar to one returned by codechef # TODO partially implimented dictionary... may lead to error # find username next tempindex = practice_page.text.find("username") ustart = practice_page.text.find(":", tempindex) uend = practice_page.text.find("}", ustart) username = practice_page.text[ustart + 1:uend] if (username == "null"): username = None else: username = username[1:-1] j.update({ 'status': 'success', 'user': { 'username': username }, 'code': "PRACTICE", 'name': "PRACTICE/" + catagory.upper(), 'problems': problems, 'problemsstats': problemsstats, 'rank_and_score': None, 'practice_catagory': catagory, 'rules': None }) return j
def submit(code_file): iarcs_session = session.iarcs_session problem_file = open(".problem") j = json.load(problem_file) submit_url = "http://opc.iarcs.org.in/index.php/submit/upload" probid = j["problem_code"] source = open(str(code_file), "rb") extension = os.path.splitext(code_file)[1] try: lang = lang_map[extension] except BaseException: click.echo("the following extension is not supported:" + extension) sys.exit() files = { "source": source } data = { "MAX_FILE_SIZE": "100000", "probid": probid, "lang": lang } # final confirmation click.confirm("following problem will be submitted\n" + "judge: iarcs\n" + "problem code: "+probid+"\n" + "file: "+str(code_file)+"\n" + "lang: "+lang+"\n" "Are you sure?", default=True, abort=True) display.normal("checking your login...") login_status = session.is_logged_in(ensure=True) if(login_status is False): display.normal("You are NOT logged in. Redirecting to login...") setup_module.login() elif(login_status): display.normal("You are logged in") else: display.error("cannot determine login status\n" + "please check your internet connection") sys.exit() click.echo("submitting your solution...", nl=False) # TODO: test before submit and confirm try: r = iarcs_session.post(submit_url, files=files, data=data) except BaseException: display.url_error(submit_url, abort=True) display.normal("\tDone") click.echo( "retriving status (you can continue your work in another tab)...", nl=False) submission_code = get_submission_code(r.text) status, points = check_status(submission_code) click.echo("\tDone") click.echo("status: "+status) click.echo("points: "+points)
def submit(code_file, submit_to_practice=False): # TODO check if it is able to submit(allowed) codechef_session = session.codechef_session submit_url = "https://www.codechef.com/api/ide/submit" problem_file = open(".problem") j = json.load(problem_file) problem_code = j["problem_code"] contest_code = j["contest_code"] if (submit_to_practice): contest_code = "PRACTICE" extension = os.path.splitext(code_file)[1] try: solution_text = open(code_file, 'r').read() except BaseException: display.error("The code file could not be loaded") sys.exit() try: lang = lang_map[extension] if (lang == "python"): ver = click.prompt("Enter python version", type=click.Choice(["2", "3"]), default="3") lang = lang + ver lang_code = lang_code_map[lang] except BaseException: click.echo("the following extension is not supported:" + extension) sys.exit() submit_data = { "sourceCode": solution_text, "problemCode": problem_code, "contestCode": contest_code, "language": lang_code } # final confirmation click.confirm("following problem will be submitted\n" + "judge: codechef\n" + "problem code: " + problem_code + "\n" + "contest code: " + contest_code + "\n" + "file: " + str(code_file) + "\n" + "lang: " + lang + "\n" "Are you sure?", default=True, abort=True) display.normal("checking your login...") login_status = session.is_logged_in(ensure=True) if (login_status is False): display.normal("You are NOT logged in. Redirecting to login...") setup_module.login() elif (login_status): display.normal("You are logged in") else: display.error("cannot determine login status\n" + "please check your internet connection") sys.exit() click.echo("submitting your solution...", nl=False) try: a = codechef_session.post(submit_url, data=submit_data) j = a.json() assert (a.status_code == 200) except BaseException: display.url_error(submit_url, abort=True) if (j['status'] == "error"): display.normal("\nCodechef returned following errors:") display.error("\n".join(j['errors'])) click.confirm( "Do you want to try to submitting to practice section instead?", default=True) submit(code_file, submit_to_practice=True) else: display.normal("\tDone") click.echo( "retriving status (you can continue your work in another tab)...", nl=False) status = check_status(j["upid"]) click.echo("\tDone") click.echo("status: " + json.dumps(status, indent=2))