From ec9ec443e4a0745319c490e92784008fe5e4cf21 Mon Sep 17 00:00:00 2001 From: Peter Stockings Date: Fri, 20 Oct 2023 19:15:47 +1100 Subject: [PATCH] Refactor workout graph generation endpoint --- app.py | 127 +++++++++++---------------------------------------------- 1 file changed, 23 insertions(+), 104 deletions(-) diff --git a/app.py b/app.py index ef1e6af..18b05a3 100644 --- a/app.py +++ b/app.py @@ -211,116 +211,35 @@ def create_workout(user_id): 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) - if request.method == 'GET': - workouts_data = get_workouts_for_user_view_data(user) - return render_template('workouts_list.html', workouts=workouts_data) - - elif request.method == 'POST': - app.logger.info(f'Creating workout for user {user.name} ({user.id})') - - data = request.json - cadence_readings = data['cadence_readings'] or [] - heart_rate_readings = data['heart_rate_readings'] or [] - - # create a new workout - workout = Workout(user_id=user_id, bike_id=user.bike_id) - db.session.add(workout) - db.session.commit() - - app.logger.info( - f'Workout({workout.id}) created for user {user.name} ({user.id}) with {len(cadence_readings)} cadence readings and {len(heart_rate_readings)} heart rate readings') - - # add cadence readings to the workout - for c in cadence_readings: - cadence_reading = CadenceReading( - workout_id=workout.id, created_at=c['timestamp'], rpm=c['rpm'], distance=c['distance'], speed=c['speed'], calories=c['calories'], power=c['power']) - db.session.add(cadence_reading) - - for h in heart_rate_readings: - heart_rate_reading = HeartRateReading( - workout_id=workout.id, created_at=h['timestamp'], bpm=h['bpm']) - db.session.add(heart_rate_reading) - - if cadence_readings: - timestamps = [isoparse( - c['timestamp']) for c in cadence_readings] - start_time = min(timestamps) - end_time = max(timestamps) - duration = end_time - start_time - duration = duration.total_seconds() - average_rpm = sum( - c['rpm'] for c in cadence_readings) / len(cadence_readings) - min_rpm = min( - c['rpm'] for c in cadence_readings) - max_rpm = max( - c['rpm'] for c in cadence_readings) - calories = cadence_readings[-1]['calories'] - distance = cadence_readings[-1]['distance'] - - workout.is_cadence_available = True - workout.started_at = start_time - workout.duration = duration - workout.average_rpm = average_rpm - workout.min_rpm = min_rpm - workout.max_rpm = max_rpm - workout.calories = calories - workout.distance = distance - - if heart_rate_readings: - bpm = [h['bpm'] for h in heart_rate_readings] - average_bpm = sum(bpm) / len(bpm) - min_bpm = min(bpm) - max_bpm = max(bpm) - - workout.is_heart_rate_available = True - workout.average_bpm = average_bpm - workout.min_bpm = min_bpm - workout.max_bpm = max_bpm - - db.session.commit() - - return jsonify({'message': 'Workout created successfully.'}), 201 -""" - - @app.route('/user//workout//', methods=['GET']) def workout(user_id, workout_id, graph_type): - workout = Workout.query.filter_by(user_id=user_id, id=workout_id).join( - Workout.cadence_readings).join(Workout.heart_rate_readings).first() + workout = Workout.query.filter_by(user_id=user_id, id=workout_id) \ + .join(Workout.cadence_readings) \ + .join(Workout.heart_rate_readings) \ + .first() if not workout: - return jsonify({'message': 'Workout {} not found for user {}.'.format(workout_id, user_id)}), 404 + return jsonify({'message': f'Workout {workout_id} not found for user {user_id}.'}), 404 - if workout.is_cadence_available: - x_values = [reading.created_at for reading in workout.cadence_readings] - if graph_type == 'cadence': - y_values = [reading.rpm for reading in workout.cadence_readings] - return create_graph(x_values=x_values, y_values=y_values, y_label='Cadence (RPM)', filename='cadence'), 200 - elif graph_type == 'speed': - y_values = [reading.speed for reading in workout.cadence_readings] - return create_graph(x_values=x_values, y_values=y_values, y_label='Speed (KPH)', filename='speed'), 200 - elif graph_type == 'distance': - y_values = [ - reading.distance for reading in workout.cadence_readings] - return create_graph(x_values=x_values, y_values=y_values, y_label='Distance (KM)', filename='distance'), 200 - elif graph_type == 'calories': - y_values = [ - reading.calories for reading in workout.cadence_readings] - return create_graph(x_values=x_values, y_values=y_values, y_label='Calories (KCAL)', filename='calories'), 200 - elif graph_type == 'power': - y_values = [reading.power for reading in workout.cadence_readings] - return create_graph(x_values=x_values, y_values=y_values, y_label='Power (WATTS)', filename='power'), 200 - if workout.is_heart_rate_available: - x_values = [ - reading.created_at for reading in workout.heart_rate_readings] - y_values = [reading.bpm for reading in workout.heart_rate_readings] - return create_graph(x_values=x_values, y_values=y_values, y_label='Heart Rate (BPM)', filename='heart_rate'), 200 + graph_mappings = { + 'cadence': ('cadence_readings', 'rpm', 'Cadence (RPM)', 'cadence'), + 'speed': ('cadence_readings', 'speed', 'Speed (KPH)', 'speed'), + 'distance': ('cadence_readings', 'distance', 'Distance (KM)', 'distance'), + 'calories': ('cadence_readings', 'calories', 'Calories (KCAL)', 'calories'), + 'power': ('cadence_readings', 'power', 'Power (WATTS)', 'power'), + 'heart_rate': ('heart_rate_readings', 'bpm', 'Heart Rate (BPM)', 'heart_rate') + } - return jsonify({'message': 'Unable to generate {} for workout {}.'.format(graph_type, workout_id)}), 409 + readings_attr, y_attr, y_label, filename = graph_mappings.get( + graph_type, (None, None, None, None)) + readings = getattr(workout, readings_attr, []) + + if readings: + x_values = [reading.created_at for reading in readings] + y_values = [getattr(reading, y_attr) for reading in readings] + return create_graph(x_values=x_values, y_values=y_values, y_label=y_label, filename=filename), 200 + + return jsonify({'message': f'Unable to generate {graph_type} for workout {workout_id}.'}), 409 @app.route('/user//workout//view', methods=['GET'])