From c5f9c19fb0591a1d14777ad205e01e29101715ae Mon Sep 17 00:00:00 2001 From: Thomas Vanbesien Date: Wed, 18 Mar 2026 16:03:00 +0100 Subject: Prefix non-public screen functions with _ and split sessions.py into helpers --- screens/sessions.py | 223 ++++++++++++++++++++++++++++------------------------ 1 file changed, 121 insertions(+), 102 deletions(-) (limited to 'screens/sessions.py') diff --git a/screens/sessions.py b/screens/sessions.py index 58b2f71..67ef9ba 100644 --- a/screens/sessions.py +++ b/screens/sessions.py @@ -4,73 +4,67 @@ import models import ui -def log_workout(conn: sqlite3.Connection) -> None: - exercises = models.list_workout_exercises(conn) - if not exercises: - print("No exercises defined. Add some first via Manage Workout Exercises.") - return - - # Session metadata - ui.clear_screen() - ui.print_header("Log Workout") - date_time = ui.prompt_datetime("Date/Time") - session_note = ui.prompt_str("Session note (optional): ", required=False) - - # Check if user wants to start from a template - entries: list[dict] = [] +def _load_from_template(conn: sqlite3.Connection, entries: list[dict]) -> None: + """Offer to pre-fill session exercises from a template.""" templates = models.list_workout_templates(conn) - if templates: - print("\nStart from a template?") - for i, t in enumerate(templates, 1): - print(f" {i}. {t['name']}") - print(" 0. No template (blank session)") - choice = input("\n> ").strip() - try: - idx = int(choice) - if 1 <= idx <= len(templates): - # Load template exercises as defaults - template_id = templates[idx - 1]["id"] - _, tmpl_entries = models.get_workout_template_detail(conn, template_id) - print(f'\nUsing template "{templates[idx - 1]["name"]}"') - print("Press Enter to accept defaults, or type new values.\n") - for te in tmpl_entries: - print(f" -- {te['exercise_name']} --") - sets = ui.prompt_int( - f" Sets [{te['sets'] or ''}]: ", - min_val=1, - default=te["sets"], - ) - assert sets is not None - reps, weight, rest_time = ui.prompt_sets_detail( - sets, - default_reps=te["reps"], - default_rest=te["rest_time"], - bw_relative=bool(te["bw_relative"]), - ) - lsrpe = ui.prompt_int(" Last Set RPE: ", min_val=1, max_val=10) - note = ui.prompt_str( - f" Note [{te['note'] or ''}]: ", - required=False, - default=te["note"], - ) - entries.append( - { - "exercise_id": te["exercise_id"], - "exercise_name": te["exercise_name"], - "bw_relative": bool(te["bw_relative"]), - "sets": sets, - "reps": reps, - "weight": weight, - "rest_time": rest_time, - "lsrpe": lsrpe, - "note": note, - } - ) - print(f' "{te["exercise_name"]}" added to session.') - except (ValueError, IndexError): - pass # Invalid input or 0 — proceed without template - - # Build exercise list — collect everything in memory before saving + if not templates: + return + print("\nStart from a template?") + for i, t in enumerate(templates, 1): + print(f" {i}. {t['name']}") + print(" 0. No template (blank session)") + choice = input("\n> ").strip() + try: + idx = int(choice) + if 1 <= idx <= len(templates): + template_id = templates[idx - 1]["id"] + _, tmpl_entries = models.get_workout_template_detail(conn, template_id) + print(f'\nUsing template "{templates[idx - 1]["name"]}"') + print("Press Enter to accept defaults, or type new values.\n") + for te in tmpl_entries: + print(f" -- {te['exercise_name']} --") + sets = ui.prompt_int( + f" Sets [{te['sets'] or ''}]: ", + min_val=1, + default=te["sets"], + ) + assert sets is not None + reps, weight, rest_time = ui.prompt_sets_detail( + sets, + default_reps=te["reps"], + default_rest=te["rest_time"], + bw_relative=bool(te["bw_relative"]), + ) + lsrpe = ui.prompt_int(" Last Set RPE: ", min_val=1, max_val=10) + note = ui.prompt_str( + f" Note [{te['note'] or ''}]: ", + required=False, + default=te["note"], + ) + entries.append( + { + "exercise_id": te["exercise_id"], + "exercise_name": te["exercise_name"], + "bw_relative": bool(te["bw_relative"]), + "sets": sets, + "reps": reps, + "weight": weight, + "rest_time": rest_time, + "lsrpe": lsrpe, + "note": note, + } + ) + print(f' "{te["exercise_name"]}" added to session.') + except (ValueError, IndexError): + pass # Invalid input or 0 — proceed without template + + +def _prompt_exercises( + conn: sqlite3.Connection, + exercises: list[sqlite3.Row], + entries: list[dict], +) -> bool: + """Prompt user to add exercises manually. Returns False if aborted.""" while True: print("\nAvailable exercises:") for e in exercises: @@ -81,10 +75,9 @@ def log_workout(conn: sqlite3.Connection) -> None: if choice.lower() == "d": if not entries: print("No exercises added. Aborting.") - return - break + return False + return True - # Select existing exercise and prompt for set details try: eid = int(choice) except ValueError: @@ -119,7 +112,14 @@ def log_workout(conn: sqlite3.Connection) -> None: ) print(f' "{ex["name"]}" added to session.') - # Show summary and confirm before writing to DB + +def _confirm_and_save( + conn: sqlite3.Connection, + date_time: str, + session_note: str | None, + entries: list[dict], +) -> None: + """Show session summary and save if confirmed.""" ui.clear_screen() ui.print_header("Session Summary") print(f"Date: {date_time}") @@ -150,10 +150,59 @@ def log_workout(conn: sqlite3.Connection) -> None: ui.pause() +def log_workout(conn: sqlite3.Connection) -> None: + exercises = models.list_workout_exercises(conn) + if not exercises: + print("No exercises defined. Add some first via Manage Workout Exercises.") + return + + ui.clear_screen() + ui.print_header("Log Workout") + date_time = ui.prompt_datetime("Date/Time") + session_note = ui.prompt_str("Session note (optional): ", required=False) + + entries: list[dict] = [] + _load_from_template(conn, entries) + if not _prompt_exercises(conn, exercises, entries): + return + _confirm_and_save(conn, date_time, session_note, entries) + + +def _view_session_detail(conn: sqlite3.Connection, session_id: int) -> None: + """Display a single session's exercises and handle deletion.""" + ui.clear_screen() + session, entries = models.get_workout_session_detail(conn, session_id) + assert session is not None + ui.print_header(f"Session: {session['date_time']}") + if session["note"]: + print(f"Note: {session['note']}\n") + ui.print_table( + ["#", "Exercise", "Sets", "Reps", "Weight", "Rest", "LSRPE", "Note"], + [ + [ + str(e["position"]), + e["exercise_name"], + str(e["sets"]), + str(e["reps"]).replace(",", "/"), + ui.format_weight(str(e["weight"]), bool(e["bw_relative"])), + ui.format_rest_time(e["rest_time"]), + str(e["lsrpe"]), + e["note"] or "", + ] + for e in entries + ], + ) + action = input("\nActions: (b)ack, (d)elete session\n> ").strip().lower() + if action == "d": + if ui.confirm("Delete this session?"): + models.delete_workout_session(conn, session_id) + print("Session deleted.") + ui.pause() + + def view_workout_sessions(conn: sqlite3.Connection) -> None: while True: ui.clear_screen() - # List all sessions with exercise name preview sessions = models.list_workout_sessions(conn) if not sessions: print("\nNo sessions recorded yet.") @@ -167,7 +216,6 @@ def view_workout_sessions(conn: sqlite3.Connection) -> None: ], ) - # Select a session to view details choice = input("\nSelect # for details ('b' = back): ").strip() if choice.lower() == "b": break @@ -180,33 +228,4 @@ def view_workout_sessions(conn: sqlite3.Connection) -> None: print("Invalid input.") continue - # Show full session detail with all exercise entries - ui.clear_screen() - session_id = sessions[idx]["id"] - session, entries = models.get_workout_session_detail(conn, session_id) - assert session is not None - ui.print_header(f"Session: {session['date_time']}") - if session["note"]: - print(f"Note: {session['note']}\n") - ui.print_table( - ["#", "Exercise", "Sets", "Reps", "Weight", "Rest", "LSRPE", "Note"], - [ - [ - str(e["position"]), - e["exercise_name"], - str(e["sets"]), - str(e["reps"]).replace(",", "/"), - ui.format_weight(str(e["weight"]), bool(e["bw_relative"])), - ui.format_rest_time(e["rest_time"]), - str(e["lsrpe"]), - e["note"] or "", - ] - for e in entries - ], - ) - action = input("\nActions: (b)ack, (d)elete session\n> ").strip().lower() - if action == "d": - if ui.confirm("Delete this session?"): - models.delete_workout_session(conn, session_id) - print("Session deleted.") - ui.pause() + _view_session_detail(conn, sessions[idx]["id"]) -- cgit v1.2.3