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 code(code_file): code_defaults_file = os.path.join(os.path.dirname(__file__), "code_defaults.json") f = open(code_defaults_file, "r") defaults = json.load(f) ext = os.path.splitext(code_file)[1] app = None if (ext in lang_map): if (os.path.exists(code_file) is False): templates_folder = os.path.join(os.path.dirname(__file__), "templates") lang_folder = lang_map[ext] lang_folder = os.path.join(templates_folder, lang_folder) try: template_file = os.path.join(lang_folder, "template" + ext) template = open(template_file, "r").readlines() f = open(code_file, "w") f.write(''.join(template)) f.close() except BaseException: pass app = defaults[lang_map[ext]] if (app is None): click.edit(filename=code_file) else: subprocess.call([app, code_file]) else: display.error("termicoder doesn't support extension: " + ext)
def is_same(ansfile, outfile): a = False try: a = filecmp.cmp(ansfile, outfile) except BaseException: display.error("error in infile/outfile") return a
def check_status(upid): delay = 2 codechef_session = session.codechef_session check_url = "https://www.codechef.com/api/ide/submit" payload = {"solution_id": upid} r = codechef_session.get(check_url, params=payload) try: status = r.json() except BaseException: status = None # maxtries such that max 3 minutes maxtries = 180 // delay + 1 i = 0 while (status is not None and status["result_code"] == 'wait' and i < maxtries): i += 1 time.sleep(delay) r = codechef_session.get(check_url, params=payload) try: status = r.json() except BaseException: status = None # if still the first 2 conditions hold if (status is not None and status["result_code"] == 'wait'): display.error("\nMax tries(" + str(maxtries) + ")exceeded\n" + "seems that judge is too busy\n" + "the last status returned by judge was:") click.echo("status: " + json.dumps(status, indent=2)) sys.exit() else: return status
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 view_problems(contest_code): # if empty contest code, get one here if (not contest_code): contest_code = click.prompt("please enter a contest code", type=click.STRING, default="PRACTICE") if (contest_code): view_module.problems(contest_code) else: # TODO remove this later display.error("some error with contest code... It shouldn't be empty")
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 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 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 problems(contest): contest = contest.upper() display_strings = [] if contest == "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 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=True) else: click.echo("requesting problem list from server...") # the following statement returns data of the contest contest_data = scrape.get_contest(contest, abort=True) click.echo("Done") if (contest_data["user"]["username"]): display_strings.append( style.normal( "You are logged in.\nOnly UNSOLVED problems are being displayed" )) else: display_strings.append( style.normal("You are NOT logged in\n" + "displaying ALL the problems")) display_strings.append( style.normal("\nContest: ") + style.contest_code(contest_data["code"]) + " " + style.contest_name("(" + contest_data["name"] + ")")) # print(contest_data) if (contest_data["rank_and_score"] and contest_data["user"]["username"]): display_strings.append( style.normal("Rank: " + contest_data["rank_and_score"]["rank"] + "\t" + "Score: " + contest_data["rank_and_score"]["score"])) display_strings.append(problem_divison_line()) display_strings.append("|" + style.sno("SNo", 3) + "|" + style.problem_code("Code", 10) + "|" + style.unsolved("Name", 25) + "|" + style.submissions("Submissions", 7) + "|") display_strings.append(problem_divison_line()) problems = [] 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.append(contest_data["problems"][i]) problems.sort(key=lambda p: int(p["successful_submissions"]), reverse=True) for (sno, problem) in zip(range(len(problems)), problems): name_style = style.unsolved if (contest_data["problems"][problem["code"]]["type"] not in normal_problem_types): name_style = style.challenge elif (problem["code"] in contest_data["problemsstats"]["partially_solved"]): name_style = style.partially_solved elif (problem["code"] in contest_data["problemsstats"]["attempted"]): name_style = style.incorrect problem_string = "|".join([ "", style.sno(str(sno + 1), 3), style.problem_code(problem["code"], 10), name_style(problem["name"], 25), style.submissions(problem["successful_submissions"], 7), "" ]) #print(problem) try: if problem["category_name"] == "unscored": problem_string += style.incorrect("unscored") display_strings.append(problem_string) except BaseException: pass display_strings.append(problem_divison_line()) click.echo_via_pager('\n'.join(display_strings))
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")