Esempio n. 1
0
def make_login_req(username, password, disconnect_sessions):
    with HTMLSession() as session:
        set_session_cookies(session)

        resp = request(session=session)
        token = get_csrf_token(resp.html, CSRF_TOKEN_INPUT_ID)
        if not token:
            return [{'data': CSRF_TOKEN_MISSING, 'code': 500}]

        data = {
            'name': username,
            'pass': password,
            'form_id': LOGIN_FORM_ID[1:],
            'csrfToken': token
        }

        resp = request(session=session, method='POST', data=data)
        resp_html = resp.html

        if resp.status_code == 200:
            if resp_html.find(SESSION_LIMIT_FORM_ID):
                if disconnect_sessions:
                    resps = disconnect_active_sessions(session, resp_html)
                    save_session_cookies(session, username)
                    return resps
                else:
                    logout(session=session)
                    return [{'data': SESSION_LIMIT_MSG, 'code': 400}]
            elif resp_html.find(LOGOUT_BUTTON_CLASS):
                save_session_cookies(session, username)
                return [{'data': LOGIN_SUCCESS_MSG}]
            return [{'data': INCORRECT_CREDS_MSG, 'code': 400}]
        return [{'code': 503}]
Esempio n. 2
0
def get_solutions(sort, order, problem_code, page, language, result, username):
    url = f'/status/{problem_code.upper()}'
    resp = request(url=url)

    if resp.status_code != 200:
        return [{'code': 503}]

    params = build_request_params(resp.html, language, result, username, page)
    resp = request(url=url, params=params)

    if resp.status_code == 200:
        if problem_code in resp.url:
            resp_html = resp.html
            solution_table = resp_html.find('table')[2]
            page_info = resp_html.find(PAGE_INFO_CLASS, first=True)

            data_rows = html_to_list(solution_table)
            for row in data_rows:
                # remove view solution column
                del row[-1]

                # format result column
                row[3] = ' '.join(row[3].split('\n'))

            resp = {'data_type': 'table', 'data': data_rows}
            if page_info:
                resp['extra'] = f'\nPage: {page_info.text}'

            return [resp]
        else:
            return [{'code': 404, 'data': INVALID_PROBLEM_CODE_MSG}]
    return [{'code': 503}]
Esempio n. 3
0
def get_tagged_problems(sort, order, tags):
    resp = request(url=f'/get/tags/problems/{",".join(tags)}')

    try:
        all_tags = resp.json()
    except ValueError:
        return [{'code': 503}]

    if resp.status_code == 200:
        data_rows = [PROBLEM_LIST_TABLE_HEADINGS]
        all_tags = all_tags.get('all_problems')

        if not all_tags:
            return [{'code': 404, 'extra': "Sorry, there are no problems with the following tags!"}]

        for _, problem in all_tags.items():
            problem_info = [
                problem.get('code', ''),
                problem.get('name', ''),
                str(problem.get('attempted_by', ''))
            ]
            try:
                accuracy = (problem.get('solved_by') / problem.get('attempted_by')) * 100
                problem_info.append(str(math.floor(accuracy)))
            except TypeError:
                problem_info.append('')
            data_rows.append(problem_info)

        return [{'data': data_rows, 'data_type': 'table'}]

    return [{'code': 503}]
Esempio n. 4
0
def get_all_tags():
    resp = request(url='/get/tags/problems')

    try:
        all_tags = resp.json()
    except ValueError:
        return [{'code': 503}]

    if resp.status_code == 200:
        data_rows = []
        num_cols = 5
        row = []

        for index, tag in enumerate(all_tags):
            tag_name = tag.get('tag', '')
            if len(row) < num_cols:
                row.append(tag_name)
            else:
                data_rows.append(row)
                row = [tag_name]
        if len(row):
            data_rows.append(row)

        return [{'data': data_rows, 'data_type': 'table'}]

    return [{'code': 503}]
Esempio n. 5
0
def get_contest_problems(sort, order, contest_code):
    url = f'/api/contests/{contest_code}?'
    resp = request(url=url)

    try:
        resp_json = resp.json()
    except ValueError:
        return [{"code": 503}]

    if resp_json['status'] == "success":
        problems_table = [[
            x.upper() for x in [
                "Name", "Code", "URL", "Successful Submissions", "Accuracy", "Scorable?"]
        ]]
        for _, problem in resp_json['problems'].items():
            problems_table.append([
                problem['name'],
                problem['code'],
                f"{BASE_URL}{problem['problem_url']}",
                problem['successful_submissions'],
                f"{problem['accuracy']} %",
                "Yes" if problem['category_name'] == 'main' else "No"
            ])

        return [
            {'data': f"\n{style_text('Name:', 'BOLD')} {resp_json['name']}\n"},
            {'data': problems_table, "data_type": "table"},
            {'data': f'\n{style_text("Announcements", "BOLD")}:\n{resp_json["announcements"]}'}
        ]
    elif resp_json['status'] == "error":
        return [{'data': 'Contest doesn\'t exist.', 'code': 404}]
    return [{"code": 503}]
Esempio n. 6
0
def get_team(name):
    if not name:
        return []
    resp = request(url=get_team_url(name))

    if resp.status_code == 200:
        resp_html = resp.html
        tables = resp_html.find('table')

        header = tables[1].text.strip()
        team_info = tables[2].text.strip()
        team_info = team_info.replace(':\n', ': ')
        team_info_list = team_info.split('\n')

        basic_info = "\n".join(team_info_list[:2])
        contests_info = "\n".join(
            [format_contest(item) for item in team_info_list[2:-1]])
        problems_solved_table = html_to_list(tables[-1])

        team_details = "\n".join([
            '', header, '', basic_info, contests_info, '',
            'Problems Successfully Solved:', ''
        ])
        return [{
            'data': team_details
        }, {
            'data': problems_solved_table,
            "data_type": "table",
            "is_pager": False
        }]
    elif resp.status_code == 404:
        return [{'code': 404, 'data': 'Team not found.'}]
    return [{'code': 503}]
Esempio n. 7
0
def logout(session=None):
    resp = request(session=session, url='/logout')
    if resp.status_code == 200:
        if os.path.exists(COOKIES_FILE_PATH):
            os.remove(COOKIES_FILE_PATH)
        return [{'data': LOGOUT_SUCCESS_MSG}]
    return [{'code': 503}]
Esempio n. 8
0
def get_solution(solution_code):
    resp = request(url=f'/viewplaintext/{solution_code}')
    if resp.status_code == 200:
        err_msg_element = resp.html.find(SOLUTION_ERR_MSG_CLASS, first=True)
        if err_msg_element and err_msg_element.text == INVALID_SOLUTION_ID_MSG:
            return [{'code': 404, "data": "Invalid Solution ID"}]
        return [{'data': f'\n{resp.html.find("pre", first=True).element.text}\n'}]
    return [{'code': 503}]
Esempio n. 9
0
def get_ratings(sort, order, country, institution, institution_type, page, lines):
    csrf_resp = request(url='/ratings/all')
    if csrf_resp.status_code == 200:
        csrf_token = get_csrf_token(csrf_resp.html, CSRF_TOKEN_INPUT_ID)
    else:
        return [{'code': 503}]

    url = '/api/ratings/all?sortBy=global_rank&order=asc'
    params = {'page': str(page), 'itemsPerPage': str(lines), 'filterBy': ''}
    if country:
        params['filterBy'] += f'Country={country};'
    if institution:
        institution = institution.title()
        params['filterBy'] += f'Institution={institution};'
    if institution_type:
        params['filterBy'] += f'Institution type={institution_type};'

    resp = request(url=url, params=params, token=csrf_token)

    if resp.status_code == 200:
        try:
            ratings = resp.json()
        except ValueError:
            return [{'code': 503}]

        ratings = ratings.get('list') or []
        if len(ratings) == 0:
            return [{'code': 404, 'data': 'No ratings found'}]

        data_rows = [RATINGS_TABLE_HEADINGS]
        for user in ratings:
            data_rows.append([
                f"{str(user['global_rank'])} ({str(user['country_rank'])})",
                user['username'],
                str(user['rating']),
                str(user['diff'])
            ])
        return [{'data': data_rows, 'data_type': 'table'}]
    return [{'code': 503}]
Esempio n. 10
0
def disconnect_active_sessions(session, login_resp_html):
    token = get_csrf_token(login_resp_html, CSRF_TOKEN_INPUT_ID)
    post_url = get_form_url(login_resp_html)
    other_active_sessions = get_other_active_sessions(login_resp_html)

    resp = request(session=session,
                   method='POST',
                   url=post_url,
                   data=other_active_sessions,
                   token=token)
    if resp and hasattr(resp, 'status_code') and resp.status_code == 200:
        return [{'data': LOGIN_SUCCESS_MSG}]
    return [{'code': 503}]
Esempio n. 11
0
def get_user(username):
    if not username:
        return []

    resp = request(url=f'/users/{username}')

    if resp.status_code == 200:
        team_url = get_team_url(username)
        if resp.url == team_url:
            return [{
                'data': f'This is a team handle.'
                f'Run `codechefcli --team {username}` to get team info\n',
                'code': 400
            }]
        elif resp.url.rstrip('/') == BASE_URL:
            return [{'code': 404, 'data': 'User not found.'}]
        else:
            resp_html = resp.html
            details_container = resp_html.find(USER_DETAILS_CONTAINER_CLASS,
                                               first=True)

            # basic info
            header = details_container.find(HEADER, first=True).text.strip()
            info_list_items = details_container.find(USER_DETAILS_CLASS,
                                                     first=True).find('li')

            # ignore first & last item i.e. username item & teams item respectively
            info = "\n".join(
                [format_list_item(li) for li in info_list_items[1:-1]])

            # rating
            star_rating = details_container.find(STAR_RATING_CLASS,
                                                 first=True).text.strip()
            rating = resp_html.find(RATING_NUMBER_CLASS,
                                    first=True).text.strip()
            rank_items = resp_html.find(RATING_RANKS_CLASS,
                                        first=True).find('li')
            global_rank = rank_items[0].find('a', first=True).text.strip()
            country_rank = rank_items[1].find('a', first=True).text.strip()

            user_details = "\n".join([
                '',
                style_text(f'User Details for {header} ({username}):', 'BOLD'),
                '', info, f"User's Teams: {get_user_teams_url(username)}", '',
                f'Rating: {star_rating} {rating}',
                f'Global Rank: {global_rank}', f'Country Rank: {country_rank}',
                '', f'Find more at: {resp.url}', ''
            ])
            return [{'data': user_details}]
    return [{'code': 503}]
Esempio n. 12
0
def get_contests(show_past):
    resp = request(url='/contests')
    if resp.status_code == 200:
        tables = resp.html.find('table')
        labels = ['Present', 'Future']
        if show_past:
            labels = ['Past']
            tables = [tables[0], tables[-1]]

        resps = []
        for idx, label in enumerate(labels):
            resps += [
                {'data': style_text(f'{label} Contests:\n', 'BOLD')},
                {'data': html_to_list(tables[idx + 1]), 'data_type': 'table'}
            ]
        return resps
    return [{'code': 503}]
Esempio n. 13
0
def get_description(problem_code, contest_code):
    url = f'/api/contests/{contest_code}/problems/{problem_code}'
    resp = request(url=url)

    try:
        resp_json = resp.json()
    except ValueError:
        return [{'code': 503}]

    if resp_json["status"] == "success":
        problem = [
            '',
            style_text('Name: ', "BOLD") + resp_json.get('problem_name', ''),
            style_text("Description:", "BOLD"),
            re.sub(r'(<|<\/)\w+>', '', resp_json.get("body", '')),
            '',
            style_text("Author: ", "BOLD") + resp_json.get('problem_author', ''),
            style_text("Date Added: ", "BOLD") + resp_json.get('date_added', ''),
            style_text("Max Time Limit: ", "BOLD") + f"{resp_json.get('max_timelimit', '')} secs",
            style_text("Source Limit: ", "BOLD") + f"{resp_json.get('source_sizelimit', '')} Bytes",
            style_text("Languages: ", "BOLD") + resp_json.get('languages_supported', ''),
            ''
        ]
        if resp_json.get('tags'):
            problem.append(
                style_text('Tags: ', 'BOLD') +
                " ".join([tag.text for tag in HTML(html=resp_json['tags']).find('a')])
            )
            problem.append('')
        if resp_json.get('editorial_url'):
            problem.append(style_text('Editorial: ', 'BOLD') + resp_json['editorial_url'])
            problem.append('')

        return [{"data": "\n".join(problem)}]
    elif resp_json["status"] == "error":
        return [{
            'data': 'Problem not found. Use `--search` to search in a specific contest',
            'code': 404
        }]
    return [{'code': 503}]
Esempio n. 14
0
def submit_problem(problem_code, solution_file, language):
    url = f'/submit/{problem_code}'
    get_resp = request(url=url)

    if not is_logged_in(get_resp):
        return [{"code": 401, "data": "This session has been disconnected. Login again."}]

    if get_resp.status_code == 200:
        rhtml = get_resp.html
        form_token = get_form_token(rhtml)
        language_code = get_language_code(rhtml, language)
        csrf_token = get_csrf_token(rhtml, CSRF_TOKEN_INPUT_ID)

        if language_code is None:
            return [{'code': 400, 'data': 'Invalid language.'}]
    else:
        return [{'code': 503}]

    try:
        solution_file_obj = open(solution_file)
    except IOError:
        return [{'data': 'Solution file not found.', 'code': 400}]

    data = {
        'language': language_code,
        'problem_code': problem_code,
        'form_id': PROBLEM_SUB_DATA_FORM_ID,
        'form_token': form_token
    }
    files = {'files[sourcefile]': solution_file_obj}

    post_resp = request(method='POST', url=url, data=data, files=files)
    if post_resp.status_code == 200:
        print(style_text('Submitting code...\n', 'BLUE'))

        status_code = post_resp.url.split('/')[-1]
        url = f'/get_submission_status/{status_code}'
        print(style_text('Fetching results...\n', 'BLUE'))

        max_tries = 3
        num_tries = 0
        while True:
            resp = request(url=url, token=csrf_token)
            num_tries += 1

            try:
                status_json = resp.json()
            except ValueError:
                if num_tries == max_tries:
                    return [{'code': 503}]
                continue

            result_code = status_json['result_code']

            if result_code != 'wait':
                data = ''
                if result_code == 'compile':
                    error_msg = get_compilation_error(status_code)
                    data = style_text(f'Compilation error.\n{error_msg}', 'FAIL')
                elif result_code == 'runtime':
                    data = style_text(f"Runtime error. {status_json.get('signal', '')}\n", 'FAIL')
                elif result_code == 'wrong':
                    data = style_text('Wrong answer\n', 'FAIL')
                elif result_code == 'accepted':
                    data = 'Correct answer\n'

                resps = [{'data': data}]
                status_table = get_status_table(status_code)
                if status_table:
                    resps.append({'data_type': 'table', 'data': html_to_list(status_table)})
                return resps
            else:
                print(style_text('Waiting...\n', 'BLUE'))
    return [{'code': 503}]
Esempio n. 15
0
def get_status_table(status_code):
    resp = request(url=f'/error_status_table/{status_code}')
    if resp.status_code != 200 or not resp.text:
        return
    return resp.html
Esempio n. 16
0
def get_compilation_error(status_code):
    resp = request(url=f'/view/error/{status_code}')
    if resp.status_code == 200:
        return resp.html.find(COMPILATION_ERROR_CLASS, first=True).text
    return SERVER_DOWN_MSG
Esempio n. 17
0
def search_problems(sort, order, search_type):
    url = f'/problems/{search_type.lower()}'
    resp = request(url=url)
    if resp.status_code == 200:
        return [{'data_type': 'table', 'data': html_to_list(resp.html.find('table')[1])}]
    return [{"code": 503}]