From 81c3cbf634e1e6929317d3ffcd87df6426808417 Mon Sep 17 00:00:00 2001 From: Thomas Vanbesien Date: Wed, 18 Mar 2026 15:18:46 +0100 Subject: Refactor screen logic into screens/ package Split egometrics.py (610 lines) into domain-specific modules: exercises, sessions, and templates. Entry point now just wires the main menu to the screen modules. --- screens/exercises.py | 106 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 screens/exercises.py (limited to 'screens/exercises.py') diff --git a/screens/exercises.py b/screens/exercises.py new file mode 100644 index 0000000..983f50f --- /dev/null +++ b/screens/exercises.py @@ -0,0 +1,106 @@ +import sqlite3 + +import models +import ui + + +def manage_workout_exercises(conn: sqlite3.Connection) -> None: + while True: + ui.clear_screen() + ui.print_header("Manage Workout Exercises") + print("1. List Exercises") + print("2. Add Exercise") + print("3. Edit Exercise") + print("4. Delete Exercise") + print("5. Back") + choice = input("\n> ").strip() + if choice == "1": + list_workout_exercises(conn) + elif choice == "2": + add_workout_exercise(conn) + elif choice == "3": + edit_workout_exercise(conn) + elif choice == "4": + delete_workout_exercise(conn) + elif choice == "5": + break + + +def list_workout_exercises(conn: sqlite3.Connection, pause: bool = True) -> None: + exercises = models.list_workout_exercises(conn) + ui.print_header("All Workout Exercises") + ui.print_table( + ["ID", "Name", "BW?", "Note"], + [ + [ + str(e["id"]), + e["name"], + "Yes" if e["bw_relative"] else "No", + e["note"] or "", + ] + for e in exercises + ], + ) + if pause: + ui.pause() + + +def add_workout_exercise(conn: sqlite3.Connection) -> None: + name = ui.prompt_str("Name: ") + assert name is not None + bw_relative = ui.confirm("Is weight relative to body weight?") + note = ui.prompt_str("Note (optional): ", required=False) + try: + models.add_workout_exercise(conn, name, bw_relative, note) + print(f'Exercise "{name}" added.') + except sqlite3.IntegrityError: + print(f'Exercise "{name}" already exists.') + ui.pause() + + +def edit_workout_exercise(conn: sqlite3.Connection) -> None: + list_workout_exercises(conn, pause=False) + eid = ui.prompt_int("\nExercise ID to edit: ") + assert eid is not None + ex = models.get_workout_exercise(conn, eid) + if not ex: + print("Exercise not found.") + return + print(f'Editing "{ex["name"]}" (leave blank to keep current value)') + name = ui.prompt_str(f"Name [{ex['name']}]: ", required=False) + bw_cur = "Yes" if ex["bw_relative"] else "No" + print(f"BW-relative [{bw_cur}]: ", end="") + bw_input = input().strip().lower() + if bw_input in ("y", "yes"): + bw_relative: bool | None = True + elif bw_input in ("n", "no"): + bw_relative = False + else: + bw_relative = None # keep current + note = ui.prompt_str(f"Note [{ex['note'] or ''}]: ", required=False) + try: + models.update_workout_exercise(conn, eid, name, bw_relative, note) + print("Exercise updated.") + except sqlite3.IntegrityError: + print(f'An exercise named "{name}" already exists.') + ui.pause() + + +def delete_workout_exercise(conn: sqlite3.Connection) -> None: + list_workout_exercises(conn, pause=False) + eid = ui.prompt_int("\nExercise ID to delete: ") + assert eid is not None + ex = models.get_workout_exercise(conn, eid) + if not ex: + print("Exercise not found.") + return + if not ui.confirm(f'Delete "{ex["name"]}"?'): + return + try: + models.delete_workout_exercise(conn, eid) + print("Exercise deleted.") + except sqlite3.IntegrityError: + print( + f'Cannot delete "{ex["name"]}" — it is used in existing sessions or templates.' + ) + ui.pause() -- cgit v1.2.3