Persists list of rendered user graphs in db, graph is removed list on click
This commit is contained in:
90
app.py
90
app.py
@@ -105,6 +105,17 @@ class HeartRateReading(db.Model):
|
||||
bpm = db.Column(db.Integer, nullable=False)
|
||||
|
||||
|
||||
class UserGraphs(db.Model):
|
||||
__tablename__ = 'user_graphs'
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
user_id = db.Column(db.Integer, db.ForeignKey(
|
||||
'users.id', ondelete='CASCADE'), nullable=False)
|
||||
start_date = db.Column(db.DateTime, nullable=False)
|
||||
end_date = db.Column(db.DateTime, nullable=False)
|
||||
period = db.Column(db.String(255), nullable=False)
|
||||
attributes = db.Column(db.ARRAY(db.String(255)))
|
||||
|
||||
|
||||
@app.route('/', methods=['GET'])
|
||||
def overview():
|
||||
return render_users_and_workouts()
|
||||
@@ -243,9 +254,27 @@ def graph_user_workouts(user_id):
|
||||
|
||||
period = request.args.get('period', default='day', type=str)
|
||||
|
||||
# Add record of user graph
|
||||
insert_usergraph_if_not_exists(
|
||||
user_id, start_date, end_date, period, attributes)
|
||||
|
||||
return plot_averaged_attributes(workouts, user, start_date, end_date, period, attributes)
|
||||
|
||||
|
||||
@app.route('/user/<int:user_id>/workouts/graph/delete', methods=['DELETE'])
|
||||
def delete_user_graph(user_id):
|
||||
attributes = request.args.getlist(
|
||||
'attributes', type=str)
|
||||
start_date = request.args.get(
|
||||
'start_date', default=datetime.now().date(), type=toDate)
|
||||
end_date = request.args.get(
|
||||
'end_date', default=datetime.now().date(), type=toDate)
|
||||
period = request.args.get('period', default='day', type=str)
|
||||
|
||||
remove_usergraph(user_id, start_date, end_date, period, attributes)
|
||||
return ""
|
||||
|
||||
|
||||
def daterange(start_date, end_date, delta=timedelta(days=1)):
|
||||
"""Helper generator to iterate over date ranges."""
|
||||
curr_date = start_date
|
||||
@@ -486,7 +515,8 @@ def generate_user_data(user, workouts=[]):
|
||||
'attributes': [('workout_count', 'Workout count'), ('duration_seconds', 'Duration (sec)'), ('duration_minutes', 'Duration (min)'), ('average_rpm', 'Average RPM'), ('max_rpm', 'Max RPM'), ('average_bpm', 'Average BPM'), ('max_bpm', 'Max BPM'), ('distance', 'Distance'), ('calories', 'Calories')],
|
||||
'periods': [('day', 'Day'), ('week', 'Week'), ('month', 'Month')],
|
||||
# (period: str, attributes: [str])
|
||||
'graphs': [('month', ['duration_minutes']), ('week', ['average_rpm', 'average_bpm']), ('week', ['workout_count'])],
|
||||
# 'graphs': [('month', ['duration_minutes']), ('week', ['average_rpm', 'average_bpm']), ('week', ['workout_count'])],
|
||||
'graphs': get_user_graphs(user.id),
|
||||
'first_workout_date': workouts[-1]['start_time_date'] if workouts else None,
|
||||
'last_workout_date': workouts[0]['start_time_date'] if workouts else None,
|
||||
}
|
||||
@@ -638,7 +668,8 @@ def generate_calendar_monthly_view(workouts, selected_date):
|
||||
start_date, end_date = get_month_bounds(selected_date)
|
||||
|
||||
# Build a lookup dictionary for faster access
|
||||
workout_lookup = {w['start_time_date'] : w for w in workouts if start_date <= w['start_time_date'] <= end_date}
|
||||
workout_lookup = {w['start_time_date']
|
||||
: w for w in workouts if start_date <= w['start_time_date'] <= end_date}
|
||||
|
||||
current_date = datetime.now().date()
|
||||
days_of_month = [
|
||||
@@ -695,6 +726,61 @@ def generate_daily_duration_sparkline(workouts):
|
||||
return sparklines.sparklines(daily_durations)[0]
|
||||
|
||||
|
||||
def get_user_graphs(user_id):
|
||||
"""Retrieve a list of UserGraphs entries for the given user_id."""
|
||||
|
||||
user_graphs = UserGraphs.query.filter_by(
|
||||
user_id=user_id).order_by(UserGraphs.id.desc()).all()
|
||||
|
||||
# change start_date, end_date from datetime to dates
|
||||
for user_graph in user_graphs:
|
||||
user_graph.start_date = user_graph.start_date.date()
|
||||
user_graph.end_date = user_graph.end_date.date()
|
||||
|
||||
return user_graphs
|
||||
|
||||
|
||||
def insert_usergraph_if_not_exists(user_id, start_date, end_date, period, attributes):
|
||||
"""Insert a UserGraphs entry if it doesn't already exist based on specified attributes and return its ID."""
|
||||
|
||||
existing_graph = UserGraphs.query.filter_by(
|
||||
user_id=user_id,
|
||||
start_date=start_date,
|
||||
end_date=end_date,
|
||||
period=period,
|
||||
attributes=attributes
|
||||
).first()
|
||||
|
||||
if not existing_graph:
|
||||
new_graph = UserGraphs(
|
||||
user_id=user_id,
|
||||
start_date=start_date,
|
||||
end_date=end_date,
|
||||
period=period,
|
||||
attributes=attributes
|
||||
)
|
||||
db.session.add(new_graph)
|
||||
db.session.commit()
|
||||
return new_graph.id # Return the ID of the newly added object
|
||||
return None # Return None if the record already exists
|
||||
|
||||
|
||||
def remove_usergraph(user_id, start_date, end_date, period, attributes):
|
||||
"""Remove a UserGraphs entry based on specified attributes."""
|
||||
|
||||
existing_graph = UserGraphs.query.filter_by(
|
||||
user_id=user_id,
|
||||
start_date=start_date,
|
||||
end_date=end_date,
|
||||
period=period,
|
||||
attributes=attributes
|
||||
).first()
|
||||
|
||||
if existing_graph:
|
||||
db.session.delete(existing_graph)
|
||||
db.session.commit()
|
||||
|
||||
|
||||
def toDate(dateString):
|
||||
return datetime.strptime(dateString, "%Y-%m-%d").date()
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<div class="flex flex-wrap mb-1">
|
||||
<div class="flex flex-wrap mb-5">
|
||||
<div class="w-full md:w-1/5 px-3 mb-6 md:mb-0">
|
||||
<div class="mb-1 w-full">
|
||||
<label class="block uppercase tracking-wide text-gray-700 text-xs font-bold mb-2" for="grid-city">
|
||||
@@ -89,8 +89,10 @@
|
||||
</div>
|
||||
|
||||
<div id="user-workouts-overview-graphs-{{ user.id }}">
|
||||
{% for period, attributes in user.graphs %}
|
||||
<img src="{{ url_for('graph_user_workouts', user_id=user.id, period=period, attributes=attributes) }}"
|
||||
loading="lazy" alt="No image" class="mx-auto" _="on click remove me">
|
||||
{% for graph in user.graphs %}
|
||||
<img src="{{ url_for('graph_user_workouts', user_id=user.id, start_date=graph.start_date, end_date=graph.end_date, period=graph.period, attributes=graph.attributes) }}"
|
||||
loading="lazy" alt="No image" class="mx-auto"
|
||||
hx-delete="{{ url_for('delete_user_graph', user_id=user.id, start_date=graph.start_date, end_date=graph.end_date, period=graph.period, attributes=graph.attributes ) }}"
|
||||
hx-swap="outerHTML">
|
||||
{% endfor %}
|
||||
</div>
|
||||
Reference in New Issue
Block a user