From 2a50c043520c1ee80801305a9783225be6b85c0c Mon Sep 17 00:00:00 2001 From: Jean-Marie Favreau Date: Sat, 25 Nov 2023 16:57:04 +0100 Subject: [PATCH] =?UTF-8?q?Refactoring:=20on=20s=C3=A9pare=20la=20partie?= =?UTF-8?q?=20calendrier?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/agenda_culturel/calendar.py | 158 ++++++++++++++++++++++++++++++++ src/agenda_culturel/views.py | 158 +------------------------------- 2 files changed, 161 insertions(+), 155 deletions(-) create mode 100644 src/agenda_culturel/calendar.py diff --git a/src/agenda_culturel/calendar.py b/src/agenda_culturel/calendar.py new file mode 100644 index 0000000..c641801 --- /dev/null +++ b/src/agenda_culturel/calendar.py @@ -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) + diff --git a/src/agenda_culturel/views.py b/src/agenda_culturel/views.py index 4c5a579..6d29a4b 100644 --- a/src/agenda_culturel/views.py +++ b/src/agenda_culturel/views.py @@ -14,8 +14,7 @@ from .celery import create_event_from_submission from .models import Event, Category, StaticContent from django.utils import timezone from enum import StrEnum -from datetime import datetime, timedelta, date, time -import calendar +from datetime import date from django.db.models import Q, F 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.messages.views import SuccessMessageMixin +from .calendar import CalendarMonth, CalendarWeek + import unicodedata @@ -38,159 +39,6 @@ def get_event_qs(request): 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):