From 3d51e2de8a2dc2616e14660d5814bc1cde461cee Mon Sep 17 00:00:00 2001 From: thematdev Date: Fri, 17 Feb 2023 18:56:02 +0300 Subject: [PATCH] Split termforces into other package --- README.md | 19 ------- scripts/termforces | 84 ----------------------------- setup.py | 8 +-- termforces/__main__.py | 6 --- termforces/cmds/__init__.py | 2 - termforces/cmds/session_manager.py | 43 --------------- termforces/cmds/submit_interface.py | 64 ---------------------- termforces/session_manager.py | 23 -------- termforces/termforces_shell.py | 31 ----------- termforces/utils.py | 18 ------- 10 files changed, 2 insertions(+), 296 deletions(-) delete mode 100755 scripts/termforces delete mode 100644 termforces/__main__.py delete mode 100644 termforces/cmds/__init__.py delete mode 100644 termforces/cmds/session_manager.py delete mode 100644 termforces/cmds/submit_interface.py delete mode 100644 termforces/session_manager.py delete mode 100644 termforces/termforces_shell.py delete mode 100644 termforces/utils.py diff --git a/README.md b/README.md index 1c16a81..cb87d4f 100644 --- a/README.md +++ b/README.md @@ -28,22 +28,3 @@ python3 setup.py install ## Reference A comment provided for each function. - -## Termforces -Termforces is a CLI wrapper for scraper. Currently it has a python module and a shell script - -## Quickstart -Use `termforces login ` to login, it will store your session, -so you're not needed to do it often. - -Then enter a directory you want and use `termforces strap --contest-id --indices `. - -Indices should be separated with space, i.e `termforces strap --contest-id 1329 --indices "A B1 B2 C D E"`. -It will create folders `problem$index` for each index you specified. - -You may also specify template folder with `--template `, in this case script will copy -its contents to all problem subfolders. - -You can check your results with `termforces results` and submit files with `termforces submit `. -Script will determine contest id from parent .rc file and problem index from folder name. You may run it either from parent or from child -directory. diff --git a/scripts/termforces b/scripts/termforces deleted file mode 100755 index 098b1a9..0000000 --- a/scripts/termforces +++ /dev/null @@ -1,84 +0,0 @@ -#!/usr/bin/env bash -# Minimalistic script to interact with Codeforces -# Written by thematdev in 2023 - - -load_rc() { - if [[ -e $1 ]]; then source $1; fi; -} - -# Load .rc files -load_rc ~/.config/termforces/termforces.rc -load_rc ../termforces.rc -load_rc termforces.rc - -login() { - if [[ $TF_PASS_CMD ]] - then - python3 -m termforces login "$1" --session-file "~/.config/termforces/termforces_cookies.json" --no-getpass <<< "$($TF_PASS_CMD)" - else - python3 -m termforces login "$1" --session-file "~/.config/termforces/termforces_cookies.json" - fi -} - -whoami() { - python3 -m termforces whoami -} - -submit() { - source_file=$1 - # Calling from either parent or child directory - if [ $(dirname $1) = "." ]; then - p=$(pwd) - else - p=$(dirname $1) - fi - problem_index=${p:0-1} - python3 -m termforces submit --contest-id $contest_id $problem_index $source_file -} - -results() { - python3 -m termforces results-my --contest-id $contest_id -} - -strap() { - while [[ $# -gt 0 ]] - do - key="$1" - case $key in - -c|--contest-id) - contest_id="$2" - shift - shift - ;; - -i|--indices) - indices="$2" - shift - shift - ;; - -t|--template) - template="$2" - shift - shift - ;; - *) - POSITIONAL+=("$1") - shift - ;; - esac - done - read -a indices_arr <<< $indices - if [[ ! -d $template ]]; then echo "Template directory not found or not specified, will create empty"; fi; - for index in "${indices_arr[@]}" - do - if [[ -d $template ]] - then - cp -r $template problem$index - else - mkdir problem$index - fi - done - echo "contest_id=$contest_id" >> termforces.rc -} - -"$@" diff --git a/setup.py b/setup.py index 6e23f92..17bae76 100644 --- a/setup.py +++ b/setup.py @@ -2,20 +2,16 @@ import setuptools setuptools.setup( name='codeforces-scraper', - version='0.2.0-r1', + version='0.3.0', author='thematdev', author_email='thematdev@thematdev.org', description='Utility to do actions on codeforces', - packages=['codeforces_scraper', 'codeforces_scraper.assets', - 'termforces', 'termforces.cmds'], - scripts=['scripts/termforces'], + packages=['codeforces_scraper', 'codeforces_scraper.assets'], install_requires=[ 'bs4', 'lxml', 'pydantic', 'requests', - 'click', - 'click_shell' ], python_requires='>=3.8', zip_safe=True, diff --git a/termforces/__main__.py b/termforces/__main__.py deleted file mode 100644 index aa92f2e..0000000 --- a/termforces/__main__.py +++ /dev/null @@ -1,6 +0,0 @@ -from termforces.termforces_shell import termforces_shell -from termforces.cmds import * - - -if __name__ == '__main__': - termforces_shell() diff --git a/termforces/cmds/__init__.py b/termforces/cmds/__init__.py deleted file mode 100644 index b286e33..0000000 --- a/termforces/cmds/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -from termforces.cmds.session_manager import * -from termforces.cmds.submit_interface import * diff --git a/termforces/cmds/session_manager.py b/termforces/cmds/session_manager.py deleted file mode 100644 index 838c20e..0000000 --- a/termforces/cmds/session_manager.py +++ /dev/null @@ -1,43 +0,0 @@ -import click -import os -from termforces.termforces_shell import termforces_shell, State -from termforces.session_manager import load_session, store_session -from getpass import getpass -from codeforces_scraper import ScraperError - - -@termforces_shell.command() -@click.argument('handle') -@click.option('--password', - help="Will be prompted, so do not pass, unless you're sure for safety") -@click.option('--session-file', help='Tries to store session on successful login') -@click.option('--no-getpass', is_flag=True, - show_default=True, default=False, help='Read password from stdin instead of using getpass') -@click.pass_obj -def login(state: State, handle, password, session_file, no_getpass): - if password is None: - if no_getpass: - password = input() - else: - password = getpass(f'Codeforces password for {handle}: ') - try: - state.scraper.login(handle, password) - except ScraperError: - print('Failed to login, check your credentials') - return - if session_file is not None: - store_session(state.scraper, os.path.expanduser(session_file)) - - -@termforces_shell.command(name='load-session') -@click.argument('session_file') -@click.pass_obj -def load_session_cmd(state: State, session_file): - load_session(state.scraper, os.path.expanduser(session_file)) - - -@termforces_shell.command(name='whoami') -@click.pass_obj -def whoami(state: State): - state.scraper.update_current_user() - print(state.scraper.current_user) diff --git a/termforces/cmds/submit_interface.py b/termforces/cmds/submit_interface.py deleted file mode 100644 index 288cce5..0000000 --- a/termforces/cmds/submit_interface.py +++ /dev/null @@ -1,64 +0,0 @@ -import click -from termforces.termforces_shell import termforces_shell, State -from codeforces_scraper import Verdict -from codeforces_scraper.languages import some_compiler_by_ext -from termforces.utils import tcolors, str_from_timestamp - - -@termforces_shell.command(name='enter-contest') -@click.argument('contest_id') -@click.pass_obj -def enter_contest(state: State, contest_id: int): - state.contest_id = contest_id - - -@termforces_shell.command(name='submit') -@click.argument('problem_index') -@click.argument('source_file') -@click.option('--contest-id') -@click.option('--lang-code') -@click.pass_obj -def submit(state: State, problem_index, source_file, contest_id, lang_code): - if contest_id is None: - if state.contest_id is not None: - contest_id = state.contest_id - else: - print('Specify contest id or enter contest via enter-contest command') - return - if lang_code is None: - ext = '.' + source_file.split('.')[-1] - compiler = some_compiler_by_ext(ext) - if compiler is None: - print('Please specify language code') - return - lang_code = compiler.id - with open(source_file, 'r') as f: - source_code = f.read() - state.scraper.submit(contest_id, problem_index, source_code, lang_code) - - -@termforces_shell.command(name='results-my') -@click.option('--contest-id') -@click.pass_obj -def results_my(state: State, contest_id): - if contest_id is None: - if state.contest_id is not None: - contest_id = state.contest_id - else: - print('Specify contest id or enter contest via enter-contest command') - return - if state.scraper.current_user is None: - print('Please login to view your results') - return - subms = state.scraper.get_submissions(contest_id, state.scraper.current_user) - subms.sort(key=lambda subm: (subm.problem.index, subm.creation_time_seconds)) - - for subm in subms: - if subm.verdict == Verdict.TESTING: - color = tcolors.WARNING - elif subm.verdict == Verdict.OK: - color = tcolors.OKGREEN - else: - color = tcolors.FAIL - verdict_str = f'{color}{subm.verdict.name}{tcolors.ENDC}' - print(f'{subm.problem.index} \t {str_from_timestamp(subm.creation_time_seconds)} \t {verdict_str}') diff --git a/termforces/session_manager.py b/termforces/session_manager.py deleted file mode 100644 index f151293..0000000 --- a/termforces/session_manager.py +++ /dev/null @@ -1,23 +0,0 @@ -import json -import requests -from codeforces_scraper import Scraper - - -# TODO: it should be scraper method -def store_session(scraper: Scraper, session_file): - with open(session_file, 'w') as f: - d = requests.utils.dict_from_cookiejar(scraper.session.cookies) - d['__termforces_name'] = scraper.current_user - json.dump(d, f) - - -# TODO: it should be a scraper method -def load_session(scraper: Scraper, session_file): - with open(session_file, 'r') as f: - d = json.load(f) - name = d['__termforces_name'] - del d['__termforces_name'] - new_cookies = requests.utils.cookiejar_from_dict(d) - scraper.current_user = name - scraper.session.cookies.clear() - scraper.session.cookies.update(new_cookies) diff --git a/termforces/termforces_shell.py b/termforces/termforces_shell.py deleted file mode 100644 index bdab100..0000000 --- a/termforces/termforces_shell.py +++ /dev/null @@ -1,31 +0,0 @@ -import click -import os -from click_shell import shell -from codeforces_scraper import Scraper -from termforces.session_manager import load_session - -SEARCH_LOCATIONS = ['.', '..', os.path.join(os.path.expanduser('~'), '.config', 'termforces')] -FILE_NAME = 'termforces_cookies.json' - - -class State: - def __init__(self): - self.scraper = Scraper() - - -def preload_session(state): - for loc in SEARCH_LOCATIONS: - file_path = os.path.join(loc, FILE_NAME) - if os.path.exists(file_path): - print(f'Loading session from {file_path}') - load_session(state.scraper, file_path) - return - - -@shell(prompt='termforces > ', intro='Entering termforces shell') -@click.pass_context -def termforces_shell(ctx): - state = State() - preload_session(state) - ctx.obj = state - pass diff --git a/termforces/utils.py b/termforces/utils.py deleted file mode 100644 index 3db9e08..0000000 --- a/termforces/utils.py +++ /dev/null @@ -1,18 +0,0 @@ -from datetime import datetime - - -class tcolors: - HEADER = '\033[95m' - OKBLUE = '\033[94m' - OKCYAN = '\033[96m' - OKGREEN = '\033[92m' - WARNING = '\033[93m' - FAIL = '\033[91m' - ENDC = '\033[0m' - BOLD = '\033[1m' - UNDERLINE = '\033[4m' - - -def str_from_timestamp(timestamp: int): - date = datetime.fromtimestamp(timestamp) - return date.strftime('%d.%m.%y %T')