Minor refactor to generate_calendar_monthly_view function
This commit is contained in:
98
app.py
98
app.py
@@ -436,56 +436,61 @@ def format_duration(duration):
|
||||
return f"{minutes}m"
|
||||
|
||||
|
||||
def date_range(start_date, end_date):
|
||||
"""
|
||||
Generator for dates between two dates (inclusive).
|
||||
"""
|
||||
current_date = start_date
|
||||
while current_date <= end_date:
|
||||
yield current_date
|
||||
current_date += timedelta(days=1)
|
||||
|
||||
|
||||
def get_month_bounds(dt):
|
||||
"""
|
||||
Determine the bounds of a month for a given date.
|
||||
This considers the starting and ending weekdays to fit a calendar view.
|
||||
"""
|
||||
first_day_of_month = dt.replace(day=1)
|
||||
next_month = first_day_of_month + relativedelta(months=1)
|
||||
last_day_of_month = next_month - timedelta(days=1)
|
||||
|
||||
# Define weekday mappings to determine start and end bounds
|
||||
weekday_to_start_offset = {6: 0, 0: 1, 1: 2, 2: 3, 3: 4, 4: 5, 5: 6}
|
||||
weekday_to_end_offset = {6: 6, 0: 5, 1: 4, 2: 3, 3: 2, 4: 1, 5: 0}
|
||||
|
||||
start_date = first_day_of_month - \
|
||||
timedelta(days=weekday_to_start_offset[first_day_of_month.weekday()])
|
||||
end_date = last_day_of_month + \
|
||||
timedelta(days=weekday_to_end_offset[last_day_of_month.weekday()])
|
||||
|
||||
return start_date, end_date
|
||||
|
||||
|
||||
def generate_calendar_monthly_view(workouts, selected_date):
|
||||
# Generate a monthly calendar view of the workouts
|
||||
def get_month_bounds(dt):
|
||||
# First day of the month
|
||||
first_day_of_month = dt.replace(day=1)
|
||||
|
||||
# Last day of the month
|
||||
next_month = first_day_of_month + relativedelta(months=1)
|
||||
last_day_of_month = next_month - timedelta(days=1)
|
||||
|
||||
start = dict(
|
||||
[(6, 0), (0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6)])
|
||||
start_date = first_day_of_month - \
|
||||
timedelta(days=start[first_day_of_month.weekday()])
|
||||
|
||||
end = dict([(6, 6), (0, 5), (1, 4),
|
||||
(2, 3), (3, 2), (4, 1), (5, 0)])
|
||||
end_date = last_day_of_month + \
|
||||
timedelta(days=end[last_day_of_month.weekday()])
|
||||
|
||||
return start_date, end_date
|
||||
|
||||
def date_range(start_date, end_date):
|
||||
current_date = start_date
|
||||
while current_date <= end_date:
|
||||
yield current_date
|
||||
current_date += timedelta(days=1)
|
||||
|
||||
def get_workout_for_date(workouts, date):
|
||||
for w in workouts:
|
||||
if w['start_time_date'].date() == date:
|
||||
return w
|
||||
return None
|
||||
"""
|
||||
Generate a monthly calendar view of the workouts.
|
||||
"""
|
||||
def get_workout_for_date(workout_lookup, date):
|
||||
return workout_lookup.get(date)
|
||||
|
||||
start_date, end_date = get_month_bounds(selected_date)
|
||||
monthly_workouts = [w for w in workouts if start_date <=
|
||||
w['start_time_date'].date() <= end_date]
|
||||
|
||||
# Build a lookup dictionary for faster access
|
||||
workout_lookup = {w['start_time_date'].date(
|
||||
): w for w in workouts if start_date <= w['start_time_date'].date() <= end_date}
|
||||
|
||||
current_date = datetime.now().date()
|
||||
days_of_month = [
|
||||
{
|
||||
'date': single_date,
|
||||
'day_of_month': single_date.day,
|
||||
'is_workout': bool(workout),
|
||||
'workout': workout if workout else None,
|
||||
'is_current_date': single_date == current_date,
|
||||
'is_current_month': single_date.month == selected_date.month and single_date.year == selected_date.year
|
||||
'date': day,
|
||||
'day_of_month': day.day,
|
||||
'is_workout': day in workout_lookup,
|
||||
'workout': get_workout_for_date(workout_lookup, day),
|
||||
'is_current_date': day == current_date,
|
||||
'is_current_month': day.month == selected_date.month and day.year == selected_date.year
|
||||
}
|
||||
for single_date in date_range(start_date, end_date)
|
||||
for workout in [get_workout_for_date(monthly_workouts, single_date)]
|
||||
for day in date_range(start_date, end_date)
|
||||
]
|
||||
|
||||
next_month_date = selected_date + relativedelta(months=1)
|
||||
@@ -500,12 +505,6 @@ def generate_calendar_monthly_view(workouts, selected_date):
|
||||
return calendar_month
|
||||
|
||||
|
||||
def date_range(start_date, end_date):
|
||||
"""Return a list of dates between the given start and end dates (inclusive)."""
|
||||
delta = end_date - start_date
|
||||
return [(start_date + timedelta(days=i)) for i in range(delta.days + 1)]
|
||||
|
||||
|
||||
def generate_daily_duration_sparkline(workouts):
|
||||
"""
|
||||
Generate a sparkline string representation of daily workout durations.
|
||||
@@ -522,14 +521,13 @@ def generate_daily_duration_sparkline(workouts):
|
||||
# Determine date range based on workouts data
|
||||
start_date = workouts[-1]['start_time_date'].date()
|
||||
end_date = workouts[0]['start_time_date'].date()
|
||||
dates_in_range = date_range(start_date, end_date)
|
||||
|
||||
# Build a mapping of dates to their respective durations for easier lookup
|
||||
workouts_by_date = {w['start_time_date'].date(): int(
|
||||
w['duration_minutes']) for w in workouts}
|
||||
|
||||
daily_durations = [workouts_by_date.get(
|
||||
date, 0) for date in dates_in_range]
|
||||
date, 0) for date in date_range(start_date, end_date)]
|
||||
|
||||
# Reverse the list to make the most recent day appear on the right
|
||||
daily_durations.reverse()
|
||||
|
||||
Reference in New Issue
Block a user