예제 #1
0
파일: scrape.py 프로젝트: apb7/termicoder
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
예제 #2
0
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)
예제 #3
0
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
예제 #4
0
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
예제 #5
0
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)
예제 #6
0
파일: scrape.py 프로젝트: apb7/termicoder
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
예제 #7
0
파일: scrape.py 프로젝트: apb7/termicoder
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
예제 #8
0
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
예제 #9
0
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)
예제 #10
0
파일: scrape.py 프로젝트: apb7/termicoder
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
예제 #11
0
파일: scrape.py 프로젝트: apb7/termicoder
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
예제 #12
0
파일: scrape.py 프로젝트: apb7/termicoder
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
예제 #13
0
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)
예제 #14
0
파일: submit.py 프로젝트: apb7/termicoder
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))