Refactoring: on sépare la partie calendrier

This commit is contained in:
Jean-Marie Favreau 2023-11-25 16:57:04 +01:00
parent 9daf35b4aa
commit 2a50c04352
2 changed files with 161 additions and 155 deletions

View File

@ -0,0 +1,158 @@
from datetime import datetime, timedelta, date, time
import calendar
def daterange(start, end, step=timedelta(1)):
if end is None:
yield start
else:
curr = start
while curr <= end:
yield curr
curr += step
class CalendarDay:
midnight = time(23, 59, 59)
def __init__(self, d, on_requested_interval = True):
self.date = d
now = date.today()
self.week = d.isocalendar()[1]
self.in_past = d < now
self.today = d == now
self.events = []
self.on_requested_interval = on_requested_interval
self.events_by_category = {}
def is_in_past(self):
return self.in_past
def is_today(self):
return self.today
def is_event_finishing_early_in_this_day(self, event):
if event.end_day is None or event.end_time is None:
return False
if event.start_day == event.end_day:
return False
return event.end_day == self.date and event.end_time < time(8)
def add_event(self, event):
if not self.is_event_finishing_early_in_this_day(event):
self.events.append(event)
if event.category is None:
if not "" in self.events_by_category:
self.events_by_category[""] = []
self.events_by_category[""].append(event)
else:
if not event.category.name in self.events_by_category:
self.events_by_category[event.category.name] = []
self.events_by_category[event.category.name].append(event)
def filter_events(self):
self.events.sort(key=lambda e: CalendarDay.midnight if e.start_time is None else e.start_time)
class CalendarList:
def __init__(self, firstdate, lastdate, filter):
self.firstdate = firstdate
self.lastdate = lastdate
self.now = date.today()
self.filter = filter
# start the first day of the first week
self.c_firstdate = firstdate + timedelta(days=-firstdate.weekday())
# end the last day of the last week
self.c_lastdate = lastdate + timedelta(days=6-lastdate.weekday())
# create a list of CalendarDays
self.create_calendar_days()
# fill CalendarDays with events
self.fill_calendar_days()
# finally, sort each CalendarDay
for i, c in self.calendar_days.items():
c.filter_events()
def today_in_calendar(self):
return self.firstdate <= self.now and self.lastdate >= self.now
def all_in_past(self):
return self.lastdate < self.now
def fill_calendar_days(self):
if self.filter is None:
qs = Event.objects()
else:
qs = self.filter.qs
self.events = qs.filter(start_day__lte=self.c_lastdate, start_day__gte=self.c_firstdate).order_by("start_day", "start_time")
for e in self.events:
for d in daterange(e.start_day, e.end_day):
if d.__str__() in self.calendar_days:
self.calendar_days[d.__str__()].add_event(e)
def create_calendar_days(self):
# create daylist
self.calendar_days = {}
for d in daterange(self.c_firstdate, self.c_lastdate):
self.calendar_days[d.strftime("%Y-%m-%d")] = CalendarDay(d, d >= self.firstdate and d <= self.lastdate)
def is_single_week(self):
return hasattr(self, "week")
def is_full_month(self):
return hasattr(self, "month")
def calendar_days_list(self):
return list(self.calendar_days.values())
class CalendarMonth(CalendarList):
def __init__(self, year, month, filter):
self.year = year
self.month = month
r = calendar.monthrange(year, month)
first = date(year, month, 1)
last = date(year, month, r[1])
super().__init__(first, last, filter)
def get_month_name(self):
return self.firstdate.strftime("%B")
def next_month(self):
return self.lastdate + timedelta(days=7)
def previous_month(self):
return self.firstdate + timedelta(days=-7)
class CalendarWeek(CalendarList):
def __init__(self, year, week, filter):
self.year = year
self.week = week
first = date.fromisocalendar(self.year, self.week, 1)
last = date.fromisocalendar(self.year, self.week, 7)
super().__init__(first, last, filter)
def next_week(self):
return self.firstdate + timedelta(days=7)
def previous_week(self):
return self.firstdate + timedelta(days=-7)

View File

@ -14,8 +14,7 @@ from .celery import create_event_from_submission
from .models import Event, Category, StaticContent from .models import Event, Category, StaticContent
from django.utils import timezone from django.utils import timezone
from enum import StrEnum from enum import StrEnum
from datetime import datetime, timedelta, date, time from datetime import date
import calendar
from django.db.models import Q, F from django.db.models import Q, F
from django.urls import reverse_lazy from django.urls import reverse_lazy
@ -28,6 +27,8 @@ from django.contrib.auth.decorators import login_required
from django.contrib import messages from django.contrib import messages
from django.contrib.messages.views import SuccessMessageMixin from django.contrib.messages.views import SuccessMessageMixin
from .calendar import CalendarMonth, CalendarWeek
import unicodedata import unicodedata
@ -38,159 +39,6 @@ def get_event_qs(request):
return Event.objects.filter(status=Event.STATUS.PUBLISHED) return Event.objects.filter(status=Event.STATUS.PUBLISHED)
def daterange(start, end, step=timedelta(1)):
if end is None:
yield start
else:
curr = start
while curr <= end:
yield curr
curr += step
class CalendarDay:
midnight = time(23, 59, 59)
def __init__(self, d, on_requested_interval = True):
self.date = d
now = date.today()
self.week = d.isocalendar()[1]
self.in_past = d < now
self.today = d == now
self.events = []
self.on_requested_interval = on_requested_interval
self.events_by_category = {}
def is_in_past(self):
return self.in_past
def is_today(self):
return self.today
def is_event_finishing_early_in_this_day(self, event):
if event.end_day is None or event.end_time is None:
return False
if event.start_day == event.end_day:
return False
return event.end_day == self.date and event.end_time < time(8)
def add_event(self, event):
if not self.is_event_finishing_early_in_this_day(event):
self.events.append(event)
if event.category is None:
if not "" in self.events_by_category:
self.events_by_category[""] = []
self.events_by_category[""].append(event)
else:
if not event.category.name in self.events_by_category:
self.events_by_category[event.category.name] = []
self.events_by_category[event.category.name].append(event)
def filter_events(self):
self.events.sort(key=lambda e: CalendarDay.midnight if e.start_time is None else e.start_time)
class CalendarList:
def __init__(self, firstdate, lastdate, filter):
self.firstdate = firstdate
self.lastdate = lastdate
self.now = date.today()
self.filter = filter
# start the first day of the first week
self.c_firstdate = firstdate + timedelta(days=-firstdate.weekday())
# end the last day of the last week
self.c_lastdate = lastdate + timedelta(days=6-lastdate.weekday())
# create a list of CalendarDays
self.create_calendar_days()
# fill CalendarDays with events
self.fill_calendar_days()
# finally, sort each CalendarDay
for i, c in self.calendar_days.items():
c.filter_events()
def today_in_calendar(self):
return self.firstdate <= self.now and self.lastdate >= self.now
def all_in_past(self):
return self.lastdate < self.now
def fill_calendar_days(self):
if self.filter is None:
qs = Event.objects()
else:
qs = self.filter.qs
self.events = qs.filter(start_day__lte=self.c_lastdate, start_day__gte=self.c_firstdate).order_by("start_day", "start_time")
for e in self.events:
for d in daterange(e.start_day, e.end_day):
if d.__str__() in self.calendar_days:
self.calendar_days[d.__str__()].add_event(e)
def create_calendar_days(self):
# create daylist
self.calendar_days = {}
for d in daterange(self.c_firstdate, self.c_lastdate):
self.calendar_days[d.strftime("%Y-%m-%d")] = CalendarDay(d, d >= self.firstdate and d <= self.lastdate)
def is_single_week(self):
return hasattr(self, "week")
def is_full_month(self):
return hasattr(self, "month")
def calendar_days_list(self):
return list(self.calendar_days.values())
class CalendarMonth(CalendarList):
def __init__(self, year, month, filter):
self.year = year
self.month = month
r = calendar.monthrange(year, month)
first = date(year, month, 1)
last = date(year, month, r[1])
super().__init__(first, last, filter)
def get_month_name(self):
return self.firstdate.strftime("%B")
def next_month(self):
return self.lastdate + timedelta(days=7)
def previous_month(self):
return self.firstdate + timedelta(days=-7)
class CalendarWeek(CalendarList):
def __init__(self, year, week, filter):
self.year = year
self.week = week
first = date.fromisocalendar(self.year, self.week, 1)
last = date.fromisocalendar(self.year, self.week, 7)
super().__init__(first, last, filter)
def next_week(self):
return self.firstdate + timedelta(days=7)
def previous_week(self):
return self.firstdate + timedelta(days=-7)
class CategoryCheckboxSelectMultiple(forms.CheckboxSelectMultiple): class CategoryCheckboxSelectMultiple(forms.CheckboxSelectMultiple):