Source code for ls.joyous.models.one_off_events

# ------------------------------------------------------------------------------
# Joyous events models
# ------------------------------------------------------------------------------
import datetime as dt
from django.db import models
from django.db.models.query import ModelIterable
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from wagtail.core.models import Page
from wagtail.admin.edit_handlers import FieldPanel
from wagtail.images.edit_handlers import ImageChooserPanel

from ..utils.telltime import (todayUtc, getAwareDatetime, getLocalDatetime,
        getLocalDate, getLocalTime)
from ..utils.telltime import timeFormat
from ..edit_handlers import TimePanel
from ..forms import FormDefender
from .groups import get_group_model_string
from .event_base import (ThisEvent, EventsByDayList,
        EventManager, EventQuerySet, EventPageForm, EventBase)

# ------------------------------------------------------------------------------
# Helper types and constants
# ------------------------------------------------------------------------------
_1day  = dt.timedelta(days=1)
_2days = dt.timedelta(days=2)

# ------------------------------------------------------------------------------
# Event models
# ------------------------------------------------------------------------------
class SimpleEventQuerySet(EventQuerySet):
    def current(self):
        qs = super().current()
        return qs.filter(date__gte = todayUtc() - _1day)

    def future(self):
        qs = super().future()
        return qs.filter(date__gte = todayUtc() - _1day)

    def past(self):
        qs = super().past()
        return qs.filter(date__lte = todayUtc() + _1day)

    def byDay(self, fromDate, toDate):
        request = self.request
        class ByDayIterable(ModelIterable):
            def __iter__(self):
                evods = EventsByDayList(fromDate, toDate)
                for page in super().__iter__():
                    pageFromDate = getLocalDate(page.date,
                                                page.time_from, page.tz)
                    pageToDate   = getLocalDate(page.date,
                                                page.time_to, page.tz)
                    thisEvent = ThisEvent(page, url=page.get_url(request))
                    evods.add(thisEvent, pageFromDate, pageToDate)
                yield from evods

        qs = self._clone()
        qs._iterable_class = ByDayIterable
        return qs.filter(date__range=(fromDate - _2days, toDate + _2days))

[docs]class SimpleEventPage(EventBase, Page, metaclass=FormDefender): events = EventManager.from_queryset(SimpleEventQuerySet)() class Meta: verbose_name = _("event page") verbose_name_plural = _("event pages") default_manager_name = "objects" parent_page_types = ["joyous.CalendarPage", "joyous.SpecificCalendarPage", "joyous.GeneralCalendarPage", get_group_model_string()] subpage_types = [] base_form_class = EventPageForm date = models.DateField(_("date"), default=dt.date.today) content_panels = Page.content_panels + [ FieldPanel('category'), ImageChooserPanel('image'), FieldPanel('date'), TimePanel('time_from'), TimePanel('time_to'), FieldPanel('tz'), ] + EventBase.content_panels1 # Anything inheriting from models.Model needs its own __init__ or # modeltranslation patch_constructor may break it def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) @property def when(self): """ A string describing when the event occurs (in the local time zone). """ return self._getLocalWhen(self.date)
[docs] def _getFromTime(self, atDate=None): """ Time that the event starts (in the local time zone). """ return getLocalTime(self.date, self.time_from, self.tz)
[docs] def _getFromDt(self): """ Datetime that the event starts (in the local time zone). """ return getLocalDatetime(self.date, self.time_from, self.tz)
[docs] def _getToDt(self): """ Datetime that the event ends (in the local time zone). """ return getLocalDatetime(self.date, self.time_to, self.tz)
# ------------------------------------------------------------------------------ class MultidayEventQuerySet(EventQuerySet): def current(self): qs = super().current() return qs.filter(date_to__gte = todayUtc() - _1day) def future(self): qs = super().future() return qs.filter(date_from__gte = todayUtc() - _1day) def past(self): qs = super().past() return qs.filter(date_from__lte = todayUtc() + _1day) def byDay(self, fromDate, toDate): request = self.request class ByDayIterable(ModelIterable): def __iter__(self): evods = EventsByDayList(fromDate, toDate) for page in super().__iter__(): pageFromDate = getLocalDate(page.date_from, page.time_from, page.tz) pageToDate = getLocalDate(page.date_to, page.time_to, page.tz) thisEvent = ThisEvent(page, url=page.get_url(request)) evods.add(thisEvent, pageFromDate, pageToDate) yield from evods qs = self._clone() qs._iterable_class = ByDayIterable return qs.filter(date_to__gte = fromDate - _2days) \ .filter(date_from__lte = toDate + _2days) class MultidayEventPageForm(EventPageForm): def _checkStartBeforeEnd(self, cleaned_data): startDate = cleaned_data.get('date_from', dt.date.min) endDate = cleaned_data.get('date_to', dt.date.max) if startDate > endDate: self.add_error('date_to', _("Event cannot end before it starts")) elif startDate == endDate: super()._checkStartBeforeEnd(cleaned_data)
[docs]class MultidayEventPage(EventBase, Page, metaclass=FormDefender): events = EventManager.from_queryset(MultidayEventQuerySet)() class Meta: verbose_name = _("multiday event page") verbose_name_plural = _("multiday event pages") default_manager_name = "objects" parent_page_types = ["joyous.CalendarPage", "joyous.SpecificCalendarPage", "joyous.GeneralCalendarPage", get_group_model_string()] subpage_types = [] base_form_class = MultidayEventPageForm date_from = models.DateField(_("start date"), default=dt.date.today) date_to = models.DateField(_("end date"), default=dt.date.today) content_panels = Page.content_panels + [ FieldPanel('category'), ImageChooserPanel('image'), FieldPanel('date_from'), TimePanel('time_from'), FieldPanel('date_to'), TimePanel('time_to'), FieldPanel('tz'), ] + EventBase.content_panels1 def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) @property def when(self): """ A string describing when the event occurs (in the local time zone). """ return self._getLocalWhen(self.date_from, self.date_to)
[docs] def _getFromTime(self, atDate=None): """ Time that the event starts (in the local time zone). """ return getLocalTime(self.date_from, self.time_from, self.tz)
[docs] def _getFromDt(self): """ Datetime that the event starts (in the local time zone). """ return getLocalDatetime(self.date_from, self.time_from, self.tz)
[docs] def _getToDt(self): """ Datetime that the event ends (in the local time zone). """ return getLocalDatetime(self.date_to, self.time_to, self.tz)
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------