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 view_problems(contest): try: assert (contest is None) except BaseException: display.error("unexpected input --contest for judge iarcs") display.normal("try:") display.command("termicoder view problems -j iarcs") else: view_module.problems()
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 logout(): if (not session.is_logged_in(ensure=False)): display.normal("invalid option --logout") display.normal("you are already logged out of iarcs") else: display.normal("logging you out of iarcs. please wait...") session.logout() display.normal("you were logged out sucessfully. cookies deleted")
def setup_all_problems(confirm=True): if (confirm): click.confirm("You have not passed any flag to iarcs.\n" + "Do you want to setup all problems?", default=True, abort=True) click.echo("trying to get your login status...", nl=False) status = session.is_logged_in(ensure=True) if (status): display.normal("\tDone\nYou are currently logged in, " + "only unsolved problems will be setup") elif (status is False): display.normal("\tDone\nYou are currently logged out, " + "all problems will be setup") else: display.error("Cannot determine login status\n" + "Pls check your internet connection") sys.exit() cwd = os.getcwd() try: os.mkdir("iarcs") except BaseException: pass os.chdir("iarcs") click.echo("fetching problem list... ", nl=False) problem_list = scrape.get_problem_list() click.echo("\tDone") display.normal("setting up %d problems from iarcs..." % len(problem_list)) with click.progressbar(problem_list) as bar: for problem in bar: setup_problem(problem["problem_code"]) os.chdir(cwd)
def setup(contest, problem_code, status): try: assert (contest is None) except BaseException: display.error("unexpected input --contest for judge iarcs") display.normal("try:") display.command("termicoder view problems -j iarcs") else: if (status == "login"): setup_module.login() elif (status == "logout"): setup_module.logout() if (problem_code is not None): click.echo("setting up problem " + problem_code.upper() + " from iarcs...", nl=False) setup_module.setup_problem(problem_code) click.echo("\tDone") elif (status is None and problem_code is None): setup_module.setup_all_problems(confirm=True)
def login(): click.echo("trying to get your login page...") if (session.is_logged_in(ensure=True)): display.normal("You are already logged in") else: username = click.prompt('enter username', type=click.STRING) password = click.prompt('enter password', type=click.STRING, hide_input=True) display.normal("logging you into iarcs. please wait...") session.login(username, password) display.normal("you were logged in successfully. cookies saved")
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 setup_contest(contest_code, abort): contest_code = contest_code.upper() contest_path = os.path.join(".", contest_code) if contest_code == "PRACTICE": try: catagory_list_path = os.path.join( os.path.dirname(os.path.dirname(__file__)), "catagories.json") catagory_file = open(catagory_list_path) catagory_list = json.load(catagory_file)["catagorylist"] except BaseException: display.error("INTERNAL ERROR:catagorylist for codechef not found") raise click.Abort else: chosen_catagory = click.prompt("Please choose a catagory" + "(" + "|".join(catagory_list) + ")", type=click.Choice(catagory_list)) click.echo("requesting problem list from server...") contest_data = scrape.get_practice_problems(chosen_catagory, abort=abort) contest_path = os.path.join(contest_path, contest_data["practice_catagory"]) else: click.echo("requesting data for contest %s. Please wait..." % contest_code, nl=False) contest_data = scrape.get_contest(contest_code, abort=abort) if (contest_data["error"] is None): click.echo("\t Done") if (contest_data["user"]["username"] is not None): click.echo( "you are currently logged in." + "\ncompletely solved problems will not be setup" + "\nthough if you want you can set them up individually later") else: click.echo("you are currently NOT logged in." + "\nALL problems of the contest will be setup") problems_to_setup = [] for i in contest_data["problems"]: if (i not in contest_data["problemsstats"]["solved"] or contest_data["problems"][i]["type"] not in normal_problem_types or i in contest_data["problemsstats"]["partially_solved"]): problems_to_setup.append(contest_data["problems"][i]) try: os.makedirs(contest_path) except FileExistsError: pass contest_setup_file = os.path.join(contest_path, ".contest") f = open(contest_setup_file, "w") if (contest_data["error"] is None): del contest_data["rules"] click.echo(json.dumps(contest_data, indent=2), file=f) # setup all problems for the contests problem_list = [problem["code"] for problem in problems_to_setup] if (len(problem_list) >= 0): directory = os.getcwd() os.chdir(contest_path) display.normal("setting up %s problems" % len(problem_list)) if (contest_data["error"] is None): with click.progressbar(problem_list) as bar: for problem_code in bar: setup_problem(problem_code, contest_code, abort=False) os.chdir(directory) else: display.error( "There are no problems to setup in this contest/Category") display.normal("Possibly you have solved all the problems") else: display.error("error in fetching contest:\n" + contest_data['error'])
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))
def view_contests(): display.error("iarcs does not hold any contests") display.normal("you can view problems through:") display.command("termicoder view problems -j iarcs")