From 0c62fcaa01cbb236cb224252475212de14288c88 Mon Sep 17 00:00:00 2001 From: Rene Luria Date: Tue, 19 Aug 2025 09:25:50 +0200 Subject: [PATCH] feat: make config_section a global CLI option Users can now specify --config-section once at the beginning of the command instead of repeating it for each subcommand. Also bumped version to v0.5.0 for this new feature. --- myice/myice.py | 127 +++++++++++++++++++++---------------------------- pyproject.toml | 2 +- 2 files changed, 54 insertions(+), 75 deletions(-) diff --git a/myice/myice.py b/myice/myice.py index 0c15e4a..d2aaade 100755 --- a/myice/myice.py +++ b/myice/myice.py @@ -92,6 +92,23 @@ def sanitize_json_response(text): app = typer.Typer(no_args_is_help=True) session: requests.Session userid: int +global_config_section: str = "default" + + +# Add global option for config section +@app.callback() +def main( + config_section: Annotated[ + str, + typer.Option( + "--config-section", "-c", help="Configuration section to use from INI file" + ), + ] = "default", +): + """My Ice Hockey schedule tool""" + # Store the config_section in a global variable so it can be accessed by commands + global global_config_section + global_config_section = config_section class AgeGroup(str, Enum): @@ -210,12 +227,15 @@ def select_club(club_id: int = 172): r.raise_for_status() -def do_login(config_section: str = "default"): +def do_login(config_section: str | None = None): global session global userid - username, password, userid_tmp, token, club_id = get_login( - config_section=config_section - ) + global global_config_section + + # Use provided config_section, or fall back to global one + section = config_section if config_section is not None else global_config_section + + username, password, userid_tmp, token, club_id = get_login(config_section=section) if userid_tmp is not None: userid = userid_tmp r = session.get("https://app.myice.hockey/", headers={"User-Agent": user_agent}) @@ -261,9 +281,9 @@ def get_userid(): def wrapper_session(func): def wrapper(*args, **kwargs): - global session, userid - # Extract config_section from kwargs if present - config_section = kwargs.get("config_section", "default") + global session, userid, global_config_section + # Use the global config_section + config_section = global_config_section session = requests.Session() # session.verify = False @@ -271,7 +291,7 @@ def wrapper_session(func): session.cookies.clear_expired_cookies() if not session.cookies.get("mih_v3_cookname"): print("login...", file=sys.stderr) - do_login(config_section=config_section) + do_login(config_section=None) # Use global config_section save_cookies() _, _, userid, _, _ = get_login(config_section=config_section) if not userid: @@ -284,7 +304,7 @@ def wrapper_session(func): @wrapper_session -def get_schedule(num_days: int, config_section: str = "default") -> str: +def get_schedule(num_days: int) -> str: global session global userid assert session and userid @@ -315,7 +335,7 @@ def get_schedule(num_days: int, config_section: str = "default") -> str: @wrapper_session -def game_pdf(gameid: int, outfile: Path, config_section: str = "default"): +def game_pdf(gameid: int, outfile: Path): global session, userid assert session and userid r = session.get( @@ -332,7 +352,7 @@ def game_pdf(gameid: int, outfile: Path, config_section: str = "default"): @wrapper_session -def practice_pdf(gameid: int, outfile: Path, config_section: str = "default"): +def practice_pdf(gameid: int, outfile: Path): global session, userid assert session and userid r = session.get( @@ -357,17 +377,12 @@ def schedule( ), ] = None, num_days: Annotated[int, typer.Option("--days")] = 7, - config_section: Annotated[ - str, - typer.Option( - "--config-section", "-c", help="Configuration section to use from INI file" - ), - ] = "default", ): """ Fetch schedule as json """ - schedule = get_schedule(num_days, config_section=config_section) + global global_config_section + schedule = get_schedule(num_days) # Sanitize the JSON response using our proven approach sanitized_schedule = sanitize_json_response(schedule) if outfile: @@ -406,21 +421,16 @@ def extract_players(pdf_file: Path) -> List[str]: def get_game_pdf( game_id: Annotated[int, typer.Argument(help="ID of game to gen pdf for")], open_file: Annotated[bool, typer.Option("--open", "-o")] = False, - config_section: Annotated[ - str, - typer.Option( - "--config-section", "-c", help="Configuration section to use from INI file" - ), - ] = "default", ): """ Genate the pdf for the game invitation """ + global global_config_section if open_file: output_filename = f"game_{game_id}.pdf" else: output_filename = tempfile.NamedTemporaryFile().name - game_pdf(game_id, Path(output_filename), config_section=config_section) + game_pdf(game_id, Path(output_filename)) if open_file: os_open(output_filename) else: @@ -432,18 +442,13 @@ def get_game_pdf( @app.command("practice") def get_practice_pdf( game_id: Annotated[int, typer.Argument(help="ID of practice to gen pdf for")], - config_section: Annotated[ - str, - typer.Option( - "--config-section", "-c", help="Configuration section to use from INI file" - ), - ] = "default", ): """ Genate the pdf for the practice invitation """ + global global_config_section output_filename = f"practice_{game_id}.pdf" - practice_pdf(game_id, Path(output_filename), config_section=config_section) + practice_pdf(game_id, Path(output_filename)) os_open(output_filename) @@ -457,16 +462,11 @@ def parse_schedule( schedule_file: Annotated[ Path, typer.Option(help="schedule json file to parse") ] = Path("schedule.json"), - config_section: Annotated[ - str, - typer.Option( - "--config-section", "-c", help="Configuration section to use from INI file" - ), - ] = "default", ): """ Parse schedule.json to look for specific games or practices """ + global global_config_section try: with schedule_file.open("r") as f: data = json.load(f) @@ -512,16 +512,11 @@ def check_with_ai( schedule_file: Annotated[ Path, typer.Option(help="schedule json file to parse") ] = Path("schedule.json"), - config_section: Annotated[ - str, - typer.Option( - "--config-section", "-c", help="Configuration section to use from INI file" - ), - ] = "default", ): """ Search through the schedule with natural language using Infomaniak LLM API """ + global global_config_section if not utils.init(): sys.exit(1) with schedule_file.open("r") as f: @@ -570,10 +565,14 @@ mobile_headers = { } -def mobile_login(config_section: str = "default"): +def mobile_login(config_section: str | None = None): + global global_config_section import base64 - username, password, _, token, club_id = get_login(config_section=config_section) + # Use provided config_section, or fall back to global one + section = config_section if config_section is not None else global_config_section + + username, password, _, token, club_id = get_login(config_section=section) if token and club_id: return {"id": 0, "token": token, "id_club": club_id} @@ -612,30 +611,16 @@ def refresh_data(): @app.command("mobile-login") -def do_mobile_login( - config_section: Annotated[ - str, - typer.Option( - "--config-section", "-c", help="Configuration section to use from INI file" - ), - ] = "default", -): - global userdata - userdata = mobile_login(config_section=config_section) +def do_mobile_login(): + global userdata, global_config_section + userdata = mobile_login(config_section=global_config_section) print(json.dumps(userdata, indent=2)) @app.command("mobile") -def mobile( - config_section: Annotated[ - str, - typer.Option( - "--config-section", "-c", help="Configuration section to use from INI file" - ), - ] = "default", -): - global userdata - userdata = mobile_login(config_section=config_section) +def mobile(): + global userdata, global_config_section + userdata = mobile_login(config_section=global_config_section) games = [x for x in refresh_data().get("club_games")] print(json.dumps(games, indent=2)) @@ -644,15 +629,9 @@ def mobile( def mobile_game( game_id: Annotated[int, typer.Argument(help="game id")], raw: Annotated[bool, typer.Option(help="display raw output")] = False, - config_section: Annotated[ - str, - typer.Option( - "--config-section", "-c", help="Configuration section to use from INI file" - ), - ] = "default", ): - global userdata - userdata = mobile_login(config_section=config_section) + global userdata, global_config_section + userdata = mobile_login(config_section=global_config_section) # data = refresh_data() with requests.post( diff --git a/pyproject.toml b/pyproject.toml index cc9a990..e069fd4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "myice" -version = "v0.4.3" +version = "v0.5.0" description = "myice parsing" authors = [ { name = "Rene Luria", "email" = ""},