Add running fitness history and configurable heart rate zones
This commit is contained in:
+63
-1
@@ -1,6 +1,6 @@
|
||||
"""Private training preferences and session observations."""
|
||||
|
||||
from flask import Blueprint, abort, flash, redirect, request, url_for
|
||||
from flask import Blueprint, abort, flash, jsonify, redirect, render_template, request, url_for
|
||||
from flask_login import current_user, login_required
|
||||
|
||||
from .extensions import db
|
||||
@@ -9,6 +9,68 @@ from .models import Activity
|
||||
training = Blueprint("training", __name__)
|
||||
|
||||
|
||||
@training.get("/fitness")
|
||||
@login_required
|
||||
def fitness():
|
||||
from .fitness import history
|
||||
|
||||
return render_template("fitness.html", data=history(current_user))
|
||||
|
||||
|
||||
@training.get("/fitness/data")
|
||||
@login_required
|
||||
def fitness_data():
|
||||
from .fitness import history
|
||||
|
||||
return jsonify(history(current_user))
|
||||
|
||||
|
||||
@training.app_context_processor
|
||||
def fitness_helpers():
|
||||
from .fitness import effort
|
||||
from .heart_rate import zones
|
||||
|
||||
return {"run_effort": effort, "fitness_zones": zones}
|
||||
|
||||
|
||||
@training.post("/training/zones")
|
||||
@login_required
|
||||
def zones():
|
||||
from datetime import date, datetime
|
||||
from zoneinfo import ZoneInfo
|
||||
|
||||
mode = request.form.get("mode")
|
||||
if mode not in {"auto", "max", "custom"}:
|
||||
abort(400)
|
||||
config = {"mode": mode}
|
||||
try:
|
||||
birthday = request.form.get("birthday", "").strip()
|
||||
if birthday:
|
||||
birthday_date = date.fromisoformat(birthday)
|
||||
today = datetime.now(ZoneInfo(current_user.timezone)).date()
|
||||
age = today.year - birthday_date.year - ((today.month, today.day) <
|
||||
(birthday_date.month, birthday_date.day))
|
||||
if not 5 <= age <= 110:
|
||||
abort(400)
|
||||
config["birthday"] = birthday
|
||||
if mode == "max":
|
||||
maximum = int(request.form.get("max_hr", ""))
|
||||
if not 100 <= maximum <= 230:
|
||||
abort(400)
|
||||
config["max_hr"] = maximum
|
||||
if mode == "custom":
|
||||
boundaries = [int(request.form.get(f"z{i}", "")) for i in range(2, 6)]
|
||||
if not 30 <= boundaries[0] < boundaries[1] < boundaries[2] < boundaries[3] <= 230:
|
||||
abort(400)
|
||||
config["boundaries"] = boundaries
|
||||
except (ValueError, TypeError):
|
||||
abort(400)
|
||||
current_user.hr_zones = config
|
||||
db.session.commit()
|
||||
flash("Fitness zones saved. Your full fitness history recalculates automatically.")
|
||||
return redirect(url_for("training.fitness"))
|
||||
|
||||
|
||||
@training.post("/training/bands")
|
||||
@login_required
|
||||
def bands():
|
||||
|
||||
Reference in New Issue
Block a user