143 lines
6.2 KiB
Python
143 lines
6.2 KiB
Python
from datetime import datetime, timedelta
|
|
from dateutil.relativedelta import relativedelta
|
|
import pandas as pd
|
|
|
|
class Calendar:
|
|
def __init__(self, db_connection_method):
|
|
self.execute = db_connection_method
|
|
|
|
def fetch_workouts_for_person(self, person_id, date, view):
|
|
prev_date, next_date = None, None
|
|
if view == 'month':
|
|
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)
|
|
prev_date = first_day_of_month - relativedelta(months=1)
|
|
next_date = first_day_of_month + relativedelta(months=1)
|
|
elif view == 'year':
|
|
start_date = date.replace(month=1, day=1)
|
|
end_date = date.replace(year=date.year + 1, month=1, day=1) - timedelta(days=1)
|
|
prev_date = date - relativedelta(years=1)
|
|
next_date = date + relativedelta(years=1)
|
|
else:
|
|
raise ValueError('Invalid view')
|
|
|
|
query = """
|
|
SELECT
|
|
w.workout_id,
|
|
w.start_date,
|
|
t.topset_id,
|
|
t.repetitions,
|
|
t.weight,
|
|
e.name AS exercise_name,
|
|
p.name AS person_name
|
|
FROM
|
|
person p
|
|
LEFT JOIN workout w ON p.person_id = w.person_id AND w.start_date BETWEEN %s AND %s
|
|
LEFT JOIN topset t ON w.workout_id = t.workout_id
|
|
LEFT JOIN exercise e ON t.exercise_id = e.exercise_id
|
|
WHERE
|
|
p.person_id = %s
|
|
ORDER BY
|
|
w.start_date,
|
|
t.topset_id;
|
|
"""
|
|
workouts_data = self.execute(query, [start_date, end_date, person_id])
|
|
|
|
# Assuming person_name is the same for all rows as we filter by person_id
|
|
person_name = workouts_data[0]['person_name'] if workouts_data else 'Unknown'
|
|
|
|
calendar_view = {'prev_date': prev_date, 'next_date': next_date, 'person_id': person_id, 'person_name': person_name, 'view': view, 'date': date}
|
|
|
|
if view == 'month':
|
|
calendar_view['days'] = []
|
|
workouts_by_date = {}
|
|
|
|
for row in workouts_data:
|
|
if row['workout_id'] is None:
|
|
continue # Skip rows that don't have workout data
|
|
|
|
workout_date_str = row['start_date'].strftime("%Y-%m-%d")
|
|
workout_id = row['workout_id']
|
|
|
|
if workout_date_str not in workouts_by_date:
|
|
workouts_by_date[workout_date_str] = {}
|
|
|
|
if workout_id not in workouts_by_date[workout_date_str]:
|
|
workouts_by_date[workout_date_str][workout_id] = {
|
|
'workout_id': workout_id,
|
|
'start_date': row['start_date'],
|
|
'sets': []
|
|
}
|
|
|
|
if row['topset_id']:
|
|
workouts_by_date[workout_date_str][workout_id]['sets'].append({
|
|
'repetitions': row['repetitions'],
|
|
'weight': row['weight'],
|
|
'exercise_name': row['exercise_name']
|
|
})
|
|
|
|
for current_date in pd.date_range(start_date, end_date, freq='D'):
|
|
date_str = current_date.strftime("%Y-%m-%d")
|
|
day_workouts = workouts_by_date.get(date_str, {})
|
|
today = datetime.today().date()
|
|
|
|
calendar_view['days'].append({
|
|
'day': current_date.day,
|
|
'is_today': current_date == today,
|
|
'is_in_current_month': current_date.month == date.month, # Ensure it compares with the selected month
|
|
'has_workouts': len(day_workouts) > 0,
|
|
'workouts': list(day_workouts.values())
|
|
})
|
|
|
|
|
|
elif view == 'year':
|
|
calendar_view['months'] = []
|
|
workouts_by_date = {}
|
|
for row in workouts_data:
|
|
if row['start_date'] is None:
|
|
continue # Skip rows that don't have workout data
|
|
workout_date_str = row['start_date'].strftime("%Y-%m-%d")
|
|
if workout_date_str not in workouts_by_date:
|
|
workouts_by_date[workout_date_str] = []
|
|
|
|
workouts_by_date[workout_date_str].append({
|
|
'workout_id': row['workout_id'],
|
|
'start_date': row['start_date'],
|
|
'topset_id': row['topset_id'],
|
|
'repetitions': row['repetitions'],
|
|
'weight': row['weight'],
|
|
'exercise_name': row['exercise_name']
|
|
})
|
|
|
|
|
|
for month in range(1, 13):
|
|
first_day_of_month = date.replace(month=month, 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)
|
|
|
|
month_data = {'name': first_day_of_month.strftime('%B'), 'first_day_of_month': first_day_of_month, 'days': []}
|
|
|
|
current_day = start_date
|
|
while current_day <= end_date:
|
|
day_workouts = workouts_by_date.get(current_day.strftime('%Y-%m-%d'), [])
|
|
has_workouts = len(day_workouts) > 0
|
|
first_workout_id = day_workouts[0]['workout_id'] if has_workouts else None
|
|
|
|
day_data = {
|
|
'day': current_day.day,
|
|
'is_today': current_day == datetime.today().date(),
|
|
'is_in_current_month': current_day.month == month,
|
|
'workouts': day_workouts,
|
|
'has_workouts': has_workouts,
|
|
'first_workout_id': first_workout_id
|
|
}
|
|
month_data['days'].append(day_data)
|
|
current_day += timedelta(days=1)
|
|
|
|
calendar_view['months'].append(month_data)
|
|
|
|
return calendar_view
|