Refactor workout graph generation endpoint
This commit is contained in:
127
app.py
127
app.py
@@ -211,116 +211,35 @@ def create_workout(user_id):
|
||||
return f'Added {humanize.naturaldelta(workout.duration)} session.', 201
|
||||
|
||||
|
||||
"""
|
||||
@app.route('/user/<int:user_id>/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/<int:user_id>/workout/<int:workout_id>/<string:graph_type>', 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/<int:user_id>/workout/<int:workout_id>/view', methods=['GET'])
|
||||
|
||||
Reference in New Issue
Block a user