diff --git a/app.py b/app.py index 98108dd..59d576c 100644 --- a/app.py +++ b/app.py @@ -1,5 +1,6 @@ -from flask import Flask, render_template, g, redirect, url_for +from flask import Flask, render_template, g, redirect, request, url_for import sqlite3 +import datetime app = Flask(__name__) @@ -17,34 +18,145 @@ def get_db(): def query_db(query, args=(), one=False): cur = get_db().execute(query, args) rv = cur.fetchall() + cur.connection.commit() cur.close() return (rv[0] if rv else None) if one else rv @app.route("/") def dashboard(): - rows = query_db('select * from TopSet') - print(rows[0]['TopSetId']) - return render_template('index.html', name='peter') + return render_template('index.html') @app.route("/person/") def display_workouts_for_person(person_id): - return render_template('workouts.html', person_id=person_id) + person = query_db('SELECT * FROM Person WHERE PersonId=?', + [person_id], one=True) + + if person is None: + return render_template('error.html', error='404', message=f'Unable to find Person({person_id})', url='/') + + workouts = query_db(""" + SELECT + W.WorkoutId, + W.StartDate, + T.TopSetId, + E.ExcerciseId, + E.Name, + T.Repetitions || ' x ' || T.Weight || 'kg' AS TopSet + FROM + Workout W + LEFT JOIN TopSet T ON W.WorkoutId = T.WorkoutId + LEFT JOIN Excercise E ON T.ExcerciseId = E.ExcerciseId + WHERE + W.PersonId = ?""", + [person_id]) + + exercises = query_db('select * from Excercise') + + unique_workout_ids = set([w['WorkoutId'] for w in workouts]) + + transformed_workouts = [] + for workout_id in unique_workout_ids: + # topsets = [w for w in workouts if w['WorkoutId' == workout_id]] + topsets = [] + for workout in workouts: + if workout['WorkoutId'] == workout_id: + topsets.append(workout) + topset_exercises = {} + for exercise in exercises: + for topset in topsets: + if topset['ExcerciseId'] == exercise['ExcerciseId']: + topset_exercises[exercise['ExcerciseId'] + ] = topset['TopSet'] + + workout = [w for w in workouts if w['WorkoutId'] == workout_id][0] + transformed_workouts.append( + {"workout_id": workout['WorkoutId'], "start_date": workout['StartDate'], "topset_exercises": topset_exercises}) + + return render_template('workouts.html', person_id=person_id, person=person, workouts=transformed_workouts, exercises=exercises) @app.route("/person//new_workout") def new_workout_for_person(person_id): - # hardcoded workout_id, need to create record in Workout table and return workout_id - return redirect(url_for('show_workout_for_person', person_id=person_id, workout_id=1)) + person = query_db('SELECT * FROM Person WHERE PersonId=?', + [person_id], one=True) + + if person is None: + return render_template('error.html', error='404', message=f'Unable to find Person({person_id})', url='/') + + now = datetime.datetime.now() + date_string = now.strftime('%Y-%m-%d') + print(f'Creating workout for {person_id} at {date_string}') + query_db('INSERT INTO Workout (PersonId, StartDate) VALUES (?, ?)', [ + person_id, date_string]) + w = query_db('SELECT MAX(WorkoutId) AS WorkoutId FROM Workout WHERE PersonId=?', [ + person_id], one=True) + + return redirect(url_for('show_workout_for_person', person_id=person_id, workout_id=w['WorkoutId'])) @app.route("/person//workout/") def show_workout_for_person(person_id, workout_id): - return render_template('workout.html', person_id=person_id, workout_id=workout_id) + workout_info = query_db(""" + SELECT + P.Name, + W.StartDate + FROM + Person P + LEFT JOIN Workout W ON P.PersonId = W.PersonId + WHERE + P.PersonId = ? + AND W.WorkoutId = ? + LIMIT 1""", + [person_id, workout_id], one=True) + + if workout_info is None: + return render_template('error.html', error='404', message=f'Unable to find Workout({workout_id}) completed by Person({person_id})', url=url_for('display_workouts_for_person', person_id=person_id)) + + top_sets = query_db(""" + SELECT + T.TopSetId, + E.Name, + T.Repetitions || ' x ' || T.Weight || 'kg' AS TopSet + FROM + Person P + LEFT JOIN Workout W ON P.PersonId = W.PersonId + INNER JOIN TopSet T ON W.WorkoutId = T.WorkoutId + INNER JOIN Excercise E ON T.ExcerciseId = E.ExcerciseId + WHERE + P.PersonId = ? + AND W.WorkoutId = ?""", + [person_id, workout_id]) + + return render_template('workout.html', person_id=person_id, workout_id=workout_id, workout_info=workout_info, top_sets=top_sets, exercises=query_db('select * from Excercise')) -@app.route("/person//workout//topset/") +@app.route("/person//workout//delete", methods=['GET', 'DELETE']) +def delete_workout_from_person(person_id, workout_id): + workout_info = query_db(""" + SELECT + P.Name, + W.StartDate + FROM + Person P + LEFT JOIN Workout W ON P.PersonId = W.PersonId + WHERE + P.PersonId = ? + AND W.WorkoutId = ? + LIMIT 1""", + [person_id, workout_id], one=True) + + if workout_info is None: + return render_template('error.html', error='404', message=f'Unable to find Workout({workout_id}) completed by Person({person_id})', url=url_for('display_workouts_for_person', person_id=person_id)) + + query_db('DELETE FROM Workout WHERE WorkoutId=?', + [workout_id]) + + return redirect(url_for('display_workouts_for_person', person_id=person_id)) + + +@app.route("/person//workout//topset/", methods=['GET', 'POST']) def show_topset_from_workout_for_person(person_id, workout_id, topset_id): topset = query_db(""" SELECT @@ -66,11 +178,111 @@ def show_topset_from_workout_for_person(person_id, workout_id, topset_id): [person_id, workout_id, topset_id], one=True) if topset is None: - return render_template('error.html', error='404', message=f'Unable to find TopSet({topset_id}) in Workout({workout_id}) completed by Person({person_id})') + return render_template('error.html', error='404', message=f'Unable to find TopSet({topset_id}) in Workout({workout_id}) completed by Person({person_id})', url=url_for('show_workout_for_person', person_id=person_id, workout_id=workout_id)) + + if request.method == 'POST': + exercise_id = request.form.get("exercise_id") + repetitions = request.form.get("repetitions") + weight = request.form.get("weight") + + query_db('UPDATE TopSet SET ExcerciseId=?, Repetitions=?, Weight=? WHERE TopSetId=?', [ + exercise_id, repetitions, weight, topset_id]) + + return redirect(url_for('show_workout_for_person', person_id=person_id, workout_id=workout_id)) return render_template('topset.html', topset=topset, exercises=query_db('select * from Excercise')) +@app.route("/person//workout//topset", methods=['POST']) +def add_topset_to_workout_for_person(person_id, workout_id): + workout_info = query_db(""" + SELECT + P.Name, + W.StartDate + FROM + Person P + LEFT JOIN Workout W ON P.PersonId = W.PersonId + WHERE + P.PersonId = ? + AND W.WorkoutId = ? + LIMIT 1""", + [person_id, workout_id], one=True) + + if workout_info is None: + return render_template('error.html', error='404', message=f'Unable to find Workout({workout_id}) completed by Person({person_id})', url=url_for('display_workouts_for_person', person_id=person_id)) + + exercise_id = request.form.get("exercise_id") + repetitions = request.form.get("repetitions") + weight = request.form.get("weight") + + query_db('INSERT INTO TopSet (WorkoutId, ExcerciseId, Repetitions, Weight) VALUES (?, ?, ?, ?)', [ + workout_id, exercise_id, repetitions, weight]) + + return redirect(url_for('show_workout_for_person', person_id=person_id, workout_id=workout_id)) + + +@app.route("/person//workout//topset//delete", methods=['GET', 'DELETE']) +def delete_topset_from_workout_for_person(person_id, workout_id, topset_id): + topset = query_db(""" + SELECT + P.Name, + W.StartDate, + E.ExcerciseId, + E.Name, + T.Repetitions, + T.Weight + FROM + Person P + LEFT JOIN Workout W ON P.PersonId = W.PersonId + INNER JOIN TopSet T ON W.WorkoutId = T.WorkoutId + INNER JOIN Excercise E ON T.ExcerciseId = E.ExcerciseId + WHERE + P.PersonId = ? + AND W.WorkoutId = ? + AND T.TopSetId = ?""", + [person_id, workout_id, topset_id], one=True) + + if topset is None: + return render_template('error.html', error='404', message=f'Unable to find TopSet({topset_id}) in Workout({workout_id}) completed by Person({person_id})', url=url_for('show_workout_for_person', person_id=person_id, workout_id=workout_id)) + + query_db('DELETE FROM TopSet WHERE TopSetId=?', [ + topset_id]) + + return redirect(url_for('show_workout_for_person', person_id=person_id, workout_id=workout_id)) + + +@app.context_processor +def my_utility_processor(): + + def is_selected_page(url): + if url == request.path: + return 'bg-gray-200' + return '' + + def get_list_of_people_and_workout_count(): + person_id = -1 + if 'person_id' in request.view_args: + person_id = request.view_args['person_id'] + + return query_db(""" + SELECT + P.PersonId, + P.Name, + COUNT(W.WorkoutId) AS NumberOfWorkouts, + CASE P.PersonId + WHEN ? + THEN 1 + ELSE 0 + END IsActive + FROM + Person P + LEFT JOIN Workout W ON P.PersonId = W.PersonId + GROUP BY + P.PersonId""", [person_id]) + + return dict(get_list_of_people_and_workout_count=get_list_of_people_and_workout_count, is_selected_page=is_selected_page) + + @app.teardown_appcontext def close_connection(exception): db = getattr(g, '_database', None) diff --git a/templates/base.html b/templates/base.html index 876d9c7..473c01d 100644 --- a/templates/base.html +++ b/templates/base.html @@ -57,10 +57,9 @@
Error: {{ error }} {{ message }} - + Close diff --git a/templates/index.html b/templates/index.html index e0da602..0c96808 100644 --- a/templates/index.html +++ b/templates/index.html @@ -2,13 +2,13 @@ {% block content %} -
+
+ +
+
+
+
+

Squat

+ + + + + + + + + + + + - - - - - - @@ -154,7 +170,7 @@

Michael

- List of rep maxes + Current rep maxes
+ Date + + Rep Max + + Estimated 1 Rep max +
+ Apr 23 ,2021 - 100kg + 5 x 100kg + + 130kg
Apr 23 ,2021 - Squats + + 5 x 100kg - 5 - - 100kg + 130kg
Apr 23 ,2021 - Squats + + 5 x 100kg - 5 - - 100kg + 130kg
Apr 23 ,2021 - Squats + + 5 x 100kg - 5 - - 100kg + 130kg
- @@ -192,98 +205,118 @@ - - - - - - - + + +
- Exercise - Date - Reps + Rep Max - Weight + Estimated 1 Rep max
Apr 23 ,2021 - Squats + + 5 x 100kg - 5 - - 100kg + 130kg
Apr 23 ,2021 - Squats + + 5 x 100kg - 5 - - 100kg + 130kg
Apr 23 ,2021 - Squats + + 5 x 100kg - 5 - - 100kg + 130kg
Apr 23 ,2021 - Squats + + 5 x 100kg - 5 + 130kg +
+
+
+
+
+ +
+
+
+
+

Squat

+ + + + + + + + + + + + - - - - - - @@ -293,6 +326,7 @@ +
diff --git a/templates/topset.html b/templates/topset.html index 7acf42e..9bd8cc7 100644 --- a/templates/topset.html +++ b/templates/topset.html @@ -28,7 +28,7 @@
+ id="grid-city" type="number" value="{{ topset['Repetitions']}}" name="repetitions">
@@ -59,7 +59,7 @@ + id="grid-zip" type="number" value="{{ topset['Weight']}}" name="weight">
+ {% for t in top_sets %} - + {{ t['TopSet'] }} - - - - - - - - - - + {% endfor %}
+ Date + + Rep Max + + Estimated 1 Rep max +
+ Apr 23 ,2021 - 100kg + 5 x 100kg + + 130kg
Apr 23 ,2021 - Squats + + 5 x 100kg - 5 - - 100kg + 130kg
Apr 23 ,2021 - Squats + + 5 x 100kg - 5 - - 100kg + 130kg
Apr 23 ,2021 - Squats + + 5 x 100kg - 5 - - 100kg + 130kg
Squats + + {{ t['Name'] }} - 5 x 60kg - Edit - - Delete - -
Bench - - 5 x 60kg - - Edit - - - Delete - -
Lat - Pulldowns - - 5 x 60kg - - Edit - - Delete
@@ -93,7 +63,9 @@
-
+
@@ -103,10 +75,11 @@
@@ -123,7 +96,7 @@ + id="grid-city" type="number" name="repetitions">
@@ -132,7 +105,7 @@ + id="grid-zip" type="number" name="weight">
@@ -22,222 +22,50 @@ class="p-4 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"> Date + {% for e in exercises %} - Squats - - - - Bench - - - Deadlift - - - Lat Pulldown + {{ e['Name'] }} + {% endfor %} + + {% for w in workouts %} - Apr 23 ,2021 - - - 5 x 60kg + {{ w['start_date'] }} + + {% for e in exercises %} - 5 x 60kg - - - 5 x 60kg + {% if e['ExcerciseId'] in w['topset_exercises'] %} + {{ w['topset_exercises'][e['ExcerciseId']] }} + {% endif %} + {% endfor %} + - 5 x 60kg - - -
Edit - - Delete - - - - - - Apr 23 ,2021 - - - 5 x 60kg - - - 5 x 60kg - - - 5 x 60kg - - - 5 x 60kg - - - - Edit - - - Delete - - - - - - Apr 23 ,2021 - - - 5 x 60kg - - - 5 x 60kg - - - 5 x 60kg - - - 5 x 60kg - - - - Edit - - - Delete - - - - - - Apr 23 ,2021 - - - 5 x 60kg - - - 5 x 60kg - - - 5 x 60kg - - - 5 x 60kg - - - - Edit - - - Delete - - - - - - Apr 23 ,2021 - - - 5 x 60kg - - - 5 x 60kg - - - 5 x 60kg - - - 5 x 60kg - - - - Edit - - - Delete - - - - - - Apr 23 ,2021 - - - 5 x 60kg - - - 5 x 60kg - - - 5 x 60kg - - - 5 x 60kg - - - - Edit - - - Delete - - - - - - Apr 23 ,2021 - - - 5 x 60kg - - - 5 x 60kg - - - 5 x 60kg - - - 5 x 60kg - - - - Edit - - Delete + {% endfor %} + + class="sm:inline-flex text-white bg-cyan-600 hover:bg-cyan-700 focus:ring-4 focus:ring-cyan-200 font-medium rounded-lg text-sm px-5 py-2.5 text-center items-center mt-6"> New workout