From f801c3c615e3b95c445a55bf307d9fad2a362959 Mon Sep 17 00:00:00 2001 From: Peter Stockings Date: Fri, 20 Oct 2023 18:40:40 +1100 Subject: [PATCH] Refactor get/add workouts for user endpoint, and update message on completion of workout --- app.py | 79 ++++++++++++++++++++++++++++++++++---- templates/new_workout.html | 8 ++-- 2 files changed, 75 insertions(+), 12 deletions(-) diff --git a/app.py b/app.py index 5ff481e..fb1a236 100644 --- a/app.py +++ b/app.py @@ -106,7 +106,7 @@ class HeartRateReading(db.Model): @app.route('/', methods=['GET']) -def get_workouts(): +def overview(): return render_users_and_workouts() @@ -143,6 +143,75 @@ def delete_user(user_id): return jsonify({'error': 'User not found.'}), 404 +@app.route('/user//workouts', methods=['GET']) +def get_workouts(user_id): + user = User.query.get(user_id) + workouts_data = get_workouts_for_user_view_data(user) + return render_template('workouts_list.html', workouts=workouts_data) + + +@app.route('/user//workouts', methods=['POST']) +def create_workout(user_id): + user = User.query.get(user_id) + app.logger.info(f'Creating workout for user {user.name} ({user.id})') + + data = request.json + cadence_readings = data.get('cadence_readings', []) + heart_rate_readings = data.get('heart_rate_readings', []) + + # Create a new workout + workout = Workout(user_id=user_id, bike_id=user.bike_id) + db.session.add(workout) + db.session.flush() # To get the workout.id before committing + + # Add cadence readings to the workout + cadences = [{ + 'workout_id': workout.id, + 'created_at': c['timestamp'], + 'rpm': c['rpm'], + 'distance': c['distance'], + 'speed': c['speed'], + 'calories': c['calories'], + 'power': c['power'] + } for c in cadence_readings] + + heart_rates = [{ + 'workout_id': workout.id, + 'created_at': h['timestamp'], + 'bpm': h['bpm'] + } for h in heart_rate_readings] + + db.session.bulk_insert_mappings(CadenceReading, cadences) + db.session.bulk_insert_mappings(HeartRateReading, heart_rates) + + if cadence_readings: + timestamps = [isoparse(c['timestamp']) for c in cadence_readings] + rpms = [c['rpm'] for c in cadence_readings] + + workout.is_cadence_available = True + workout.started_at = min(timestamps) + workout.duration = ( + max(timestamps) - workout.started_at).total_seconds() + workout.average_rpm = sum(rpms) / len(rpms) + workout.min_rpm = min(rpms) + workout.max_rpm = max(rpms) + workout.calories = cadence_readings[-1]['calories'] + workout.distance = cadence_readings[-1]['distance'] + + if heart_rate_readings: + bpms = [h['bpm'] for h in heart_rate_readings] + + workout.is_heart_rate_available = True + workout.average_bpm = sum(bpms) / len(bpms) + workout.min_bpm = min(bpms) + workout.max_bpm = max(bpms) + + db.session.commit() + + return f'Added {humanize.naturaldelta(workout.duration)} session.', 201 + + +""" @app.route('/user//workouts', methods=['GET', 'POST']) def workouts(user_id): user = User.query.get(user_id) @@ -215,6 +284,7 @@ def workouts(user_id): db.session.commit() return jsonify({'message': 'Workout created successfully.'}), 201 +""" @app.route('/user//workout//', methods=['GET']) @@ -271,13 +341,6 @@ def delete_workout(user_id, workout_id): return render_users_and_workouts() -@app.route('/user//workouts', methods=['GET']) -def workouts_for_user(user_id): - user = User.query.get(user_id) - workouts_data = get_workouts_for_user_view_data(user) - return render_template('workouts_list.html', workouts=workouts_data) - - @app.route('/user//bike', methods=['GET']) def update_users_bike(user_id): bike_id = request.args.get('bike_id') diff --git a/templates/new_workout.html b/templates/new_workout.html index 5705039..d897e38 100644 --- a/templates/new_workout.html +++ b/templates/new_workout.html @@ -215,17 +215,17 @@ // Disconnect from heart rate sensor disconnectHeartRateMonitor(); - fetch("{{ url_for('workouts', user_id=user.id) }}", { + fetch("{{ url_for('create_workout', user_id=user.id) }}", { method: "POST", headers: { Accept: "application/json", "Content-Type": "application/json", }, body: JSON.stringify({ cadence_readings: workoutData, heart_rate_readings: heartRateData }), - }).then(res => res.json()) - .then(res => { + }).then(res => res.text()) + .then(txt => { workoutData = []; - swal("Submitted", JSON.stringify(res), "success"); + swal("Submitted", txt, "success"); }) .catch(err => swal("Failed to submit workout", err.message, "error"));