diff options
| -rw-r--r-- | db.py | 10 | ||||
| -rw-r--r-- | egometrics.py | 10 | ||||
| -rw-r--r-- | models.py | 30 | ||||
| -rw-r--r-- | screens/__init__.py | 1 | ||||
| -rw-r--r-- | screens/weight.py | 72 |
5 files changed, 122 insertions, 1 deletions
@@ -59,6 +59,16 @@ CREATE INDEX IF NOT EXISTS idx_workout_sessions_date CREATE INDEX IF NOT EXISTS idx_workout_template_exercises_template ON workout_template_exercises(template_id); + +CREATE TABLE IF NOT EXISTS weight_logs ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + date_time TEXT NOT NULL, + weight REAL NOT NULL, + note TEXT +); + +CREATE INDEX IF NOT EXISTS idx_weight_logs_date + ON weight_logs(date_time); """ diff --git a/egometrics.py b/egometrics.py index f45fa6d..5a8a556 100644 --- a/egometrics.py +++ b/egometrics.py @@ -2,9 +2,11 @@ import sqlite3 from db import get_connection, init_db from screens import ( + log_weight, log_workout, manage_workout_exercises, manage_workout_templates, + view_weight_logs, view_workout_sessions, ) @@ -19,7 +21,9 @@ def main_menu(conn: sqlite3.Connection) -> None: print("2. View Workout Sessions") print("3. Manage Workout Exercises") print("4. Manage Workout Templates") - print("5. Quit") + print("5. Log Weight") + print("6. View Weight Logs") + print("7. Quit") choice = input("\n> ").strip() if choice == "1": log_workout(conn) @@ -30,6 +34,10 @@ def main_menu(conn: sqlite3.Connection) -> None: elif choice == "4": manage_workout_templates(conn) elif choice == "5": + log_weight(conn) + elif choice == "6": + view_weight_logs(conn) + elif choice == "7": break @@ -252,3 +252,33 @@ def save_workout_template_exercises( ), ) conn.commit() + + +# --- Weight Logs --- + + +def add_weight_log( + conn: sqlite3.Connection, + date_time: str, + weight: float, + note: str | None = None, +) -> int: + cur = conn.execute( + "INSERT INTO weight_logs (date_time, weight, note) VALUES (?, ?, ?)", + (date_time, weight, note), + ) + conn.commit() + assert cur.lastrowid is not None + return cur.lastrowid + + +def list_weight_logs(conn: sqlite3.Connection, limit: int = 20) -> list[sqlite3.Row]: + return conn.execute( + "SELECT id, date_time, weight, note FROM weight_logs ORDER BY date_time DESC LIMIT ?", + (limit,), + ).fetchall() + + +def delete_weight_log(conn: sqlite3.Connection, log_id: int) -> None: + conn.execute("DELETE FROM weight_logs WHERE id = ?", (log_id,)) + conn.commit() diff --git a/screens/__init__.py b/screens/__init__.py index 5bd64e6..72858c8 100644 --- a/screens/__init__.py +++ b/screens/__init__.py @@ -1,3 +1,4 @@ from screens.exercises import manage_workout_exercises from screens.sessions import log_workout, view_workout_sessions from screens.templates import manage_workout_templates +from screens.weight import log_weight, view_weight_logs diff --git a/screens/weight.py b/screens/weight.py new file mode 100644 index 0000000..5669f07 --- /dev/null +++ b/screens/weight.py @@ -0,0 +1,72 @@ +import sqlite3 + +import models +import ui + + +def log_weight(conn: sqlite3.Connection) -> None: + ui.clear_screen() + ui.print_header("Log Weight") + date_time = ui.prompt_datetime("Date/Time") + weight = ui.prompt_float("Weight (kg): ", min_val=0.1) + assert weight is not None + note = ui.prompt_str("Note (optional): ", required=False) + models.add_weight_log(conn, date_time, weight, note) + print(f"Logged {weight:.1f}kg.") + ui.pause() + + +def _fmt_diff(current: float, previous: float) -> str: + diff = round(current - previous, 1) + if diff > 0: + return f"+{diff:.1f}" + elif diff < 0: + return f"{diff:.1f}" + return "0.0" + + +def view_weight_logs(conn: sqlite3.Connection) -> None: + while True: + ui.clear_screen() + logs = models.list_weight_logs(conn) + if not logs: + print("\nNo weight logs recorded yet.") + ui.pause() + return + ui.print_header("Weight Logs") + + # Logs are newest-first; diff compares to the next row (previous in time) + rows = [] + for i, log in enumerate(logs): + weight = log["weight"] + if i < len(logs) - 1: + diff = _fmt_diff(weight, logs[i + 1]["weight"]) + else: + diff = "" + rows.append( + [ + str(i + 1), + log["date_time"], + f"{weight:.1f}", + diff, + log["note"] or "", + ] + ) + + ui.print_table(["#", "Date", "Weight (kg)", "Diff", "Note"], rows) + + choice = input("\nSelect # to delete ('b' = back): ").strip() + if choice.lower() == "b": + break + try: + idx = int(choice) - 1 + if idx < 0 or idx >= len(logs): + print("Invalid selection.") + continue + except ValueError: + print("Invalid input.") + continue + if ui.confirm(f"Delete log from {logs[idx]['date_time']}?"): + models.delete_weight_log(conn, logs[idx]["id"]) + print("Log deleted.") + ui.pause() |
