Move nested functions
This commit is contained in:
@@ -36,4 +36,3 @@ def logout():
|
|||||||
logout_user() # Logs out the current user
|
logout_user() # Logs out the current user
|
||||||
flash('You have been logged out.', 'success')
|
flash('You have been logged out.', 'success')
|
||||||
return redirect(url_for('auth.login')) # Redirect to login page or home page
|
return redirect(url_for('auth.login')) # Redirect to login page or home page
|
||||||
|
|
||||||
|
|||||||
@@ -23,132 +23,6 @@ def health():
|
|||||||
@main.route('/dashboard', methods=['GET', 'POST'])
|
@main.route('/dashboard', methods=['GET', 'POST'])
|
||||||
@login_required
|
@login_required
|
||||||
def dashboard():
|
def dashboard():
|
||||||
# Helper function to get first and last reading timestamps
|
|
||||||
def get_reading_date_range(user_id):
|
|
||||||
result = (
|
|
||||||
db.session.query(
|
|
||||||
func.min(Reading.timestamp).label('first'),
|
|
||||||
func.max(Reading.timestamp).label('last')
|
|
||||||
)
|
|
||||||
.filter(Reading.user_id == user_id)
|
|
||||||
.first()
|
|
||||||
)
|
|
||||||
return result.first, result.last
|
|
||||||
|
|
||||||
# Helper function to calculate weekly summary averages
|
|
||||||
def calculate_weekly_summary(readings):
|
|
||||||
one_week_ago = datetime.now() - timedelta(days=7)
|
|
||||||
weekly_readings = [r for r in readings if r.timestamp >= one_week_ago]
|
|
||||||
if weekly_readings:
|
|
||||||
systolic_avg = round(sum(r.systolic for r in weekly_readings) / len(weekly_readings), 1)
|
|
||||||
diastolic_avg = round(sum(r.diastolic for r in weekly_readings) / len(weekly_readings), 1)
|
|
||||||
heart_rate_avg = round(sum(r.heart_rate for r in weekly_readings) / len(weekly_readings), 1)
|
|
||||||
else:
|
|
||||||
systolic_avg = diastolic_avg = heart_rate_avg = 0
|
|
||||||
return systolic_avg, diastolic_avg, heart_rate_avg
|
|
||||||
|
|
||||||
# Helper function to calculate progress badges
|
|
||||||
def calculate_progress_badges(readings):
|
|
||||||
"""Calculate badges based on user reading activity."""
|
|
||||||
badges = []
|
|
||||||
now = datetime.utcnow().date()
|
|
||||||
|
|
||||||
# Prepare sorted readings by timestamp
|
|
||||||
sorted_readings = sorted(readings, key=lambda r: r.timestamp)
|
|
||||||
|
|
||||||
# Incremental milestone badge
|
|
||||||
def highest_milestone(total_readings, milestones):
|
|
||||||
"""Determine the highest milestone achieved."""
|
|
||||||
for milestone in reversed(milestones):
|
|
||||||
if total_readings >= milestone:
|
|
||||||
return f"{milestone} Readings Logged"
|
|
||||||
return None
|
|
||||||
|
|
||||||
highest_milestone_badge = highest_milestone(len(readings), [10, 50, 100, 500, 1000, 5000, 10000])
|
|
||||||
if highest_milestone_badge:
|
|
||||||
badges.append(highest_milestone_badge)
|
|
||||||
|
|
||||||
# Streaks and calendar month badges
|
|
||||||
if sorted_readings:
|
|
||||||
streak_count = 1
|
|
||||||
daily_streak = True
|
|
||||||
monthly_tracker = defaultdict(int)
|
|
||||||
|
|
||||||
# Start with the first reading
|
|
||||||
previous_date = sorted_readings[0].timestamp.date()
|
|
||||||
|
|
||||||
for reading in sorted_readings[1:]:
|
|
||||||
current_date = reading.timestamp.date()
|
|
||||||
|
|
||||||
# Check for consecutive daily streaks
|
|
||||||
if (current_date - previous_date).days == 1:
|
|
||||||
streak_count += 1
|
|
||||||
elif (current_date - previous_date).days > 1:
|
|
||||||
daily_streak = False
|
|
||||||
|
|
||||||
# Track monthly activity
|
|
||||||
monthly_tracker[current_date.strftime('%Y-%m')] += 1
|
|
||||||
|
|
||||||
previous_date = current_date
|
|
||||||
|
|
||||||
# Add streak badges
|
|
||||||
if daily_streak and streak_count >= 1:
|
|
||||||
badges.append(f"Current Streak: {streak_count} Days")
|
|
||||||
if daily_streak and streak_count >= 7:
|
|
||||||
badges.append("Logged Every Day for a Week")
|
|
||||||
|
|
||||||
if daily_streak and streak_count >= 30 and previous_date == now:
|
|
||||||
badges.append("Monthly Streak")
|
|
||||||
|
|
||||||
# Add calendar month streak badges
|
|
||||||
for month, count in monthly_tracker.items():
|
|
||||||
if count >= 30:
|
|
||||||
badges.append(f"Full Month of Logging: {month}")
|
|
||||||
|
|
||||||
# Time-specific badges (morning/night logging)
|
|
||||||
def is_morning(reading_time):
|
|
||||||
return 5 <= reading_time.hour < 12
|
|
||||||
|
|
||||||
def is_night(reading_time):
|
|
||||||
return 18 <= reading_time.hour <= 23
|
|
||||||
|
|
||||||
if all(is_morning(r.timestamp) for r in sorted_readings[-7:]):
|
|
||||||
badges.append("Morning Riser: Logged Readings Every Morning for a Week")
|
|
||||||
|
|
||||||
if all(is_night(r.timestamp) for r in sorted_readings[-7:]):
|
|
||||||
badges.append("Night Owl: Logged Readings Every Night for a Week")
|
|
||||||
|
|
||||||
return badges
|
|
||||||
|
|
||||||
def generate_monthly_calendar(readings, selected_date, local_timezone):
|
|
||||||
# Convert selected date to user's timezone and extract the start/end dates
|
|
||||||
today = datetime.now(local_timezone).date()
|
|
||||||
date = selected_date.astimezone(local_timezone).date()
|
|
||||||
first_day_of_month = date.replace(day=1)
|
|
||||||
days_to_subtract = (first_day_of_month.weekday() + 1) % 7
|
|
||||||
start_date = first_day_of_month - timedelta(days=days_to_subtract)
|
|
||||||
end_date = start_date + timedelta(days=6 * 7 - 1)
|
|
||||||
|
|
||||||
# Group readings by day
|
|
||||||
readings_by_day = {}
|
|
||||||
for reading in readings:
|
|
||||||
local_date = reading.timestamp.astimezone(local_timezone).date()
|
|
||||||
readings_by_day.setdefault(local_date, []).append(reading)
|
|
||||||
|
|
||||||
# Build calendar days
|
|
||||||
calendar = []
|
|
||||||
current_date = start_date
|
|
||||||
while current_date <= end_date:
|
|
||||||
calendar.append({
|
|
||||||
'day': current_date.day,
|
|
||||||
'is_today': current_date == today,
|
|
||||||
'is_in_current_month': current_date.month == date.month,
|
|
||||||
'readings': readings_by_day.get(current_date, []),
|
|
||||||
})
|
|
||||||
current_date += timedelta(days=1)
|
|
||||||
|
|
||||||
return calendar
|
|
||||||
|
|
||||||
# Get the first and last reading timestamps
|
# Get the first and last reading timestamps
|
||||||
first_reading_timestamp, last_reading_timestamp = get_reading_date_range(current_user.id)
|
first_reading_timestamp, last_reading_timestamp = get_reading_date_range(current_user.id)
|
||||||
|
|
||||||
@@ -221,3 +95,129 @@ def dashboard():
|
|||||||
date=date,
|
date=date,
|
||||||
timedelta=timedelta
|
timedelta=timedelta
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Helper function to get first and last reading timestamps
|
||||||
|
def get_reading_date_range(user_id):
|
||||||
|
result = (
|
||||||
|
db.session.query(
|
||||||
|
func.min(Reading.timestamp).label('first'),
|
||||||
|
func.max(Reading.timestamp).label('last')
|
||||||
|
)
|
||||||
|
.filter(Reading.user_id == user_id)
|
||||||
|
.first()
|
||||||
|
)
|
||||||
|
return result.first, result.last
|
||||||
|
|
||||||
|
# Helper function to calculate weekly summary averages
|
||||||
|
def calculate_weekly_summary(readings):
|
||||||
|
one_week_ago = datetime.now() - timedelta(days=7)
|
||||||
|
weekly_readings = [r for r in readings if r.timestamp >= one_week_ago]
|
||||||
|
if weekly_readings:
|
||||||
|
systolic_avg = round(sum(r.systolic for r in weekly_readings) / len(weekly_readings), 1)
|
||||||
|
diastolic_avg = round(sum(r.diastolic for r in weekly_readings) / len(weekly_readings), 1)
|
||||||
|
heart_rate_avg = round(sum(r.heart_rate for r in weekly_readings) / len(weekly_readings), 1)
|
||||||
|
else:
|
||||||
|
systolic_avg = diastolic_avg = heart_rate_avg = 0
|
||||||
|
return systolic_avg, diastolic_avg, heart_rate_avg
|
||||||
|
|
||||||
|
def generate_monthly_calendar(readings, selected_date, local_timezone):
|
||||||
|
# Convert selected date to user's timezone and extract the start/end dates
|
||||||
|
today = datetime.now(local_timezone).date()
|
||||||
|
date = selected_date.astimezone(local_timezone).date()
|
||||||
|
first_day_of_month = date.replace(day=1)
|
||||||
|
days_to_subtract = (first_day_of_month.weekday() + 1) % 7
|
||||||
|
start_date = first_day_of_month - timedelta(days=days_to_subtract)
|
||||||
|
end_date = start_date + timedelta(days=6 * 7 - 1)
|
||||||
|
|
||||||
|
# Group readings by day
|
||||||
|
readings_by_day = {}
|
||||||
|
for reading in readings:
|
||||||
|
local_date = reading.timestamp.astimezone(local_timezone).date()
|
||||||
|
readings_by_day.setdefault(local_date, []).append(reading)
|
||||||
|
|
||||||
|
# Build calendar days
|
||||||
|
calendar = []
|
||||||
|
current_date = start_date
|
||||||
|
while current_date <= end_date:
|
||||||
|
calendar.append({
|
||||||
|
'day': current_date.day,
|
||||||
|
'is_today': current_date == today,
|
||||||
|
'is_in_current_month': current_date.month == date.month,
|
||||||
|
'readings': readings_by_day.get(current_date, []),
|
||||||
|
})
|
||||||
|
current_date += timedelta(days=1)
|
||||||
|
|
||||||
|
return calendar
|
||||||
|
|
||||||
|
# Helper function to calculate progress badges
|
||||||
|
def calculate_progress_badges(readings):
|
||||||
|
"""Calculate badges based on user reading activity."""
|
||||||
|
badges = []
|
||||||
|
now = datetime.utcnow().date()
|
||||||
|
|
||||||
|
# Prepare sorted readings by timestamp
|
||||||
|
sorted_readings = sorted(readings, key=lambda r: r.timestamp)
|
||||||
|
|
||||||
|
# Incremental milestone badge
|
||||||
|
def highest_milestone(total_readings, milestones):
|
||||||
|
"""Determine the highest milestone achieved."""
|
||||||
|
for milestone in reversed(milestones):
|
||||||
|
if total_readings >= milestone:
|
||||||
|
return f"{milestone} Readings Logged"
|
||||||
|
return None
|
||||||
|
|
||||||
|
highest_milestone_badge = highest_milestone(len(readings), [10, 50, 100, 500, 1000, 5000, 10000])
|
||||||
|
if highest_milestone_badge:
|
||||||
|
badges.append(highest_milestone_badge)
|
||||||
|
|
||||||
|
# Streaks and calendar month badges
|
||||||
|
if sorted_readings:
|
||||||
|
streak_count = 1
|
||||||
|
daily_streak = True
|
||||||
|
monthly_tracker = defaultdict(int)
|
||||||
|
|
||||||
|
# Start with the first reading
|
||||||
|
previous_date = sorted_readings[0].timestamp.date()
|
||||||
|
|
||||||
|
for reading in sorted_readings[1:]:
|
||||||
|
current_date = reading.timestamp.date()
|
||||||
|
|
||||||
|
# Check for consecutive daily streaks
|
||||||
|
if (current_date - previous_date).days == 1:
|
||||||
|
streak_count += 1
|
||||||
|
elif (current_date - previous_date).days > 1:
|
||||||
|
daily_streak = False
|
||||||
|
|
||||||
|
# Track monthly activity
|
||||||
|
monthly_tracker[current_date.strftime('%Y-%m')] += 1
|
||||||
|
|
||||||
|
previous_date = current_date
|
||||||
|
|
||||||
|
# Add streak badges
|
||||||
|
if daily_streak and streak_count >= 1:
|
||||||
|
badges.append(f"Current Streak: {streak_count} Days")
|
||||||
|
if daily_streak and streak_count >= 7:
|
||||||
|
badges.append("Logged Every Day for a Week")
|
||||||
|
|
||||||
|
if daily_streak and streak_count >= 30 and previous_date == now:
|
||||||
|
badges.append("Monthly Streak")
|
||||||
|
|
||||||
|
# Add calendar month streak badges
|
||||||
|
for month, count in monthly_tracker.items():
|
||||||
|
if count >= 30:
|
||||||
|
badges.append(f"Full Month of Logging: {month}")
|
||||||
|
|
||||||
|
# Time-specific badges (morning/night logging)
|
||||||
|
def is_morning(reading_time):
|
||||||
|
return 5 <= reading_time.hour < 12
|
||||||
|
|
||||||
|
def is_night(reading_time):
|
||||||
|
return 18 <= reading_time.hour <= 23
|
||||||
|
|
||||||
|
if all(is_morning(r.timestamp) for r in sorted_readings[-7:]):
|
||||||
|
badges.append("Morning Riser: Logged Readings Every Morning for a Week")
|
||||||
|
|
||||||
|
if all(is_night(r.timestamp) for r in sorted_readings[-7:]):
|
||||||
|
badges.append("Night Owl: Logged Readings Every Night for a Week")
|
||||||
|
|
||||||
|
return badges
|
||||||
@@ -1,12 +1,10 @@
|
|||||||
from collections import defaultdict
|
|
||||||
from flask import Blueprint, render_template, redirect, request, url_for, flash
|
from flask import Blueprint, render_template, redirect, request, url_for, flash
|
||||||
import humanize
|
|
||||||
from pytz import timezone, utc
|
from pytz import timezone, utc
|
||||||
from sqlalchemy import func
|
|
||||||
from app.models import Reading, db
|
from app.models import Reading, db
|
||||||
from app.forms import DeleteForm, ReadingForm
|
from app.forms import ReadingForm
|
||||||
from flask_login import login_required, current_user
|
from flask_login import login_required, current_user
|
||||||
from datetime import date, datetime, timedelta
|
from datetime import datetime
|
||||||
|
|
||||||
reading = Blueprint('reading', __name__)
|
reading = Blueprint('reading', __name__)
|
||||||
|
|
||||||
@reading.route('/add', methods=['GET', 'POST'])
|
@reading.route('/add', methods=['GET', 'POST'])
|
||||||
|
|||||||
Reference in New Issue
Block a user