Add options to filter epoch for exercise progress graphs (1M, 3M, 6M, All), however if there isnt data in a selected epoch the endpoint returns 404. Havent bothered to look into to it, probs should clean up code as well

This commit is contained in:
Peter Stockings
2024-04-03 20:31:13 +11:00
parent dae4fcbf44
commit 6dafdf71dd
4 changed files with 37 additions and 7 deletions

4
app.py
View File

@@ -413,7 +413,9 @@ def get_exercise_progress_for_user(person_id, exercise_id):
'min_date'), '%Y-%m-%d')
max_date = convert_str_to_date(request.args.get(
'max_date'), '%Y-%m-%d')
exercise_progress = db.get_exercise_progress_for_user(person_id, exercise_id, min_date, max_date)
epoch = request.args.get('epoch', default='All')
exercise_progress = db.get_exercise_progress_for_user(person_id, exercise_id, min_date, max_date, epoch)
if not exercise_progress:
abort(404)

12
db.py
View File

@@ -3,6 +3,7 @@ import psycopg2
import numpy as np
from psycopg2.extras import RealDictCursor
from datetime import datetime
from dateutil.relativedelta import relativedelta
from urllib.parse import urlparse
from flask import g
@@ -450,7 +451,14 @@ class DataBase():
'SELECT exercise_id, name FROM exercise')
return exercises
def get_exercise_progress_for_user(self, person_id, exercise_id, min_date=None, max_date=None):
def get_exercise_progress_for_user(self, person_id, exercise_id, min_date=None, max_date=None, epoch='all'):
today = datetime.now()
if epoch == '1M':
min_date = today - relativedelta(months=1)
elif epoch == '3M':
min_date = today - relativedelta(months=3)
elif epoch == '6M':
min_date = today - relativedelta(months=6)
# Execute SQL query to fetch topset data for a specific person and exercise
topsets = self.execute("""
SELECT
@@ -484,7 +492,7 @@ class DataBase():
start_dates = [t['start_date'] for t in topsets]
messages = [f'{t["repetitions"]} x {t["weight"]}kg ({t["estimated_1rm"]}kg E1RM) on {t["start_date"].strftime("%d %b %y")}' for t in topsets]
exercise_progress = get_exercise_graph_model(topsets[0]['exercise_name'], estimated_1rm, repetitions, weight, start_dates, messages)
exercise_progress = get_exercise_graph_model(topsets[0]['exercise_name'], estimated_1rm, repetitions, weight, start_dates, messages, epoch, person_id, exercise_id)
return exercise_progress

View File

@@ -47,11 +47,24 @@
<!-- Popover content will be dynamically inserted here -->
</div>
<h4 class="text-l font-semibold text-blue-400 text-center">{{ title }}</h4>
<h2 class="text-xs font-semibold text-blue-200 mb-2 text-center" style='font-family: "Computer Modern Sans", sans-serif;'>
<h2 class="text-xs font-semibold text-blue-200 mb-1 text-center" style='font-family: "Computer Modern Sans", sans-serif;'>
{% if best_fit_formula %}
y = {{ best_fit_formula.slope }}x {% if best_fit_formula.intercept != 0 %}+ {{ best_fit_formula.intercept }}{% endif %}, {{ best_fit_formula.kg_per_week }} kg/week, {{ best_fit_formula.kg_per_month }} kg/month
{% endif %}
</h2>
<div class="inline-flex rounded-md shadow-sm w-full items-center justify-center mb-1">
{% for epoch in epochs %}
<div
{% if selected_epoch == epoch %}
class="px-4 py-2 text-sm font-medium text-blue-700 bg-white border border-gray-200 rounded-s-lg hover:bg-gray-100 focus:z-10 focus:ring-2 focus:ring-blue-700 focus:text-blue-700 dark:bg-gray-800 dark:border-gray-700 dark:text-white dark:hover:text-white dark:hover:bg-gray-700 dark:focus:ring-blue-500 dark:focus:text-white"
{% else %}
class="px-4 py-2 text-sm font-medium text-gray-900 bg-white border border-gray-200 rounded-e-lg hover:bg-gray-100 hover:text-blue-700 focus:z-10 focus:ring-2 focus:ring-blue-700 focus:text-blue-700 dark:bg-gray-800 dark:border-gray-700 dark:text-white dark:hover:text-white dark:hover:bg-gray-700 dark:focus:ring-blue-500 dark:focus:text-white cursor-pointer"
hx-get='{{ url_for("get_exercise_progress_for_user", person_id=person_id, exercise_id=exercise_id, epoch=epoch) }}' hx-target="#svg-plot-{{ unique_id }}" hx-swap="outerHTML" hx-trigger="click"
{% endif %}>
{{ epoch}}
</div>
{% endfor %}
</div>
<svg viewBox="0 0 {{ (vb_width + 2*margin) | int }} {{ (vb_height + 2*margin) | int }}" preserveAspectRatio="none">
{% for plot in plots %}
<g class="{{ plot.label }}" style="fill: {{ plot.color }}; stroke: {{ plot.color }};">

View File

@@ -52,8 +52,11 @@ def get_topsets_for_person(person_topsets):
weight = [t['Weight'] for t in exercise_topsets]
start_dates = [t['StartDate'] for t in exercise_topsets]
messages = [f'{t["Repetitions"]} x {t["Weight"]}kg ({t["Estimated1RM"]}kg E1RM) on {t["StartDate"].strftime("%d %b %y")}' for t in exercise_topsets]
epoch = 'All'
person_id = exercise_topsets[0]['PersonId']
exercise_id = exercise_topsets[0]['ExerciseId']
exercise_progress = get_exercise_graph_model(exercise_topsets[0]['ExerciseName'], estimated_1rm, repetitions, weight, start_dates, messages)
exercise_progress = get_exercise_graph_model(exercise_topsets[0]['ExerciseName'], estimated_1rm, repetitions, weight, start_dates, messages, epoch, person_id, exercise_id)
exercises_topsets.append({
'ExerciseId': e['ExerciseId'],
@@ -236,7 +239,7 @@ def get_date_info(input_date, selected_view):
'end_date': last_day_of_year,
}
def get_exercise_graph_model(title, estimated_1rm, repetitions, weight, start_dates, messages):
def get_exercise_graph_model(title, estimated_1rm, repetitions, weight, start_dates, messages, epoch, person_id, exercise_id):
min_date, max_date = min(start_dates), max(start_dates)
min_e1rm, max_e1rm = min(estimated_1rm), max(estimated_1rm)
min_reps, max_reps = min(repetitions), max(repetitions)
@@ -318,7 +321,11 @@ def get_exercise_graph_model(title, estimated_1rm, repetitions, weight, start_da
'plots': [repetitions, weight, estimated_1rm],
'best_fit_points': best_fit_points,
'best_fit_formula': best_fit_formula,
'plot_labels': plot_labels
'plot_labels': plot_labels,
'epochs': ['1M', '3M', '6M', 'All'],
'selected_epoch': epoch,
'person_id': person_id,
'exercise_id': exercise_id
}
def get_workout_counts(workouts, period='week'):