aboutsummaryrefslogtreecommitdiffstats
path: root/screens/exercises.py
diff options
context:
space:
mode:
authorThomas Vanbesien <tvanbesi@proton.me>2026-03-18 15:18:46 +0100
committerThomas Vanbesien <tvanbesi@proton.me>2026-03-18 15:18:46 +0100
commit81c3cbf634e1e6929317d3ffcd87df6426808417 (patch)
tree3c4045f2ae4329983c3fabe6710a1caa3168e06c /screens/exercises.py
parent7ceb22f1e12e3a040874a43b5e1177db83be15ed (diff)
downloadEgoMetrics-81c3cbf634e1e6929317d3ffcd87df6426808417.tar.gz
EgoMetrics-81c3cbf634e1e6929317d3ffcd87df6426808417.zip
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.
Diffstat (limited to 'screens/exercises.py')
-rw-r--r--screens/exercises.py106
1 files changed, 106 insertions, 0 deletions
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()