From 100528ad0f1d7244da2d30e24ada2907350020f8 Mon Sep 17 00:00:00 2001 From: Mira Weller Date: Thu, 7 Mar 2024 14:39:10 +0100 Subject: [PATCH] start implementing time machine mode (thread local) --- src/pretix/base/models/event.py | 27 +++---- src/pretix/presale/middleware.py | 1 + .../templates/pretixpresale/event/base.html | 11 +++ src/pretix/presale/timemachine.py | 74 +++++++++++++++++++ src/pretix/settings.py | 1 + 5 files changed, 101 insertions(+), 13 deletions(-) create mode 100644 src/pretix/presale/timemachine.py diff --git a/src/pretix/base/models/event.py b/src/pretix/base/models/event.py index 15daa9627b..b102a726c4 100644 --- a/src/pretix/base/models/event.py +++ b/src/pretix/base/models/event.py @@ -76,6 +76,7 @@ from pretix.helpers.thumb import get_thumbnail from ..settings import settings_hierarkey from .organizer import Organizer, Team +from ...presale.timemachine import time_machine_now logger = logging.getLogger(__name__) @@ -243,11 +244,11 @@ class EventMixin: Is true, when ``presale_end`` is set and in the past. """ if self.effective_presale_end: - return now() > self.effective_presale_end + return time_machine_now() > self.effective_presale_end elif self.date_to: - return now() > self.date_to + return time_machine_now() > self.date_to else: - return now().astimezone(self.timezone).date() > self.date_from.astimezone(self.timezone).date() + return time_machine_now().astimezone(self.timezone).date() > self.date_from.astimezone(self.timezone).date() @property def effective_presale_start(self): @@ -267,7 +268,7 @@ class EventMixin: Is true, when ``presale_end`` is not set or in the future and ``presale_start`` is not set or in the past. """ - if self.effective_presale_start and now() < self.effective_presale_start: + if self.effective_presale_start and time_machine_now() < self.effective_presale_start: return False return not self.presale_has_ended @@ -315,11 +316,11 @@ class EventMixin: q_variation = ( Q(active=True) & Q(sales_channels__contains=channel) - & Q(Q(available_from__isnull=True) | Q(available_from__lte=now())) - & Q(Q(available_until__isnull=True) | Q(available_until__gte=now())) + & Q(Q(available_from__isnull=True) | Q(available_from__lte=time_machine_now())) + & Q(Q(available_until__isnull=True) | Q(available_until__gte=time_machine_now())) & Q(item__active=True) - & Q(Q(item__available_from__isnull=True) | Q(item__available_from__lte=now())) - & Q(Q(item__available_until__isnull=True) | Q(item__available_until__gte=now())) + & Q(Q(item__available_from__isnull=True) | Q(item__available_from__lte=time_machine_now())) + & Q(Q(item__available_until__isnull=True) | Q(item__available_until__gte=time_machine_now())) & Q(Q(item__category__isnull=True) | Q(item__category__is_addon=False)) & Q(item__sales_channels__contains=channel) & Q(item__require_bundling=False) @@ -694,7 +695,7 @@ class Event(EventMixin, LoggedModel): @property def presale_has_ended(self): if self.has_subevents: - return self.presale_end and now() > self.presale_end + return self.presale_end and time_machine_now() > self.presale_end else: return super().presale_has_ended @@ -1187,8 +1188,8 @@ class Event(EventMixin, LoggedModel): ) ).filter( Q(active=True) & Q(is_public=True) & ( - Q(Q(date_to__isnull=True) & Q(date_from__gte=now() - timedelta(hours=24))) - | Q(date_to__gte=now() - timedelta(hours=24)) + Q(Q(date_to__isnull=True) & Q(date_from__gte=time_machine_now() - timedelta(hours=24))) + | Q(date_to__gte=time_machine_now() - timedelta(hours=24)) ) ) # order_by doesn't make sense with I18nField if ordering in ("date_ascending", "date_descending"): @@ -1508,7 +1509,7 @@ class SubEvent(EventMixin, LoggedModel): disabled_items=Coalesce( Subquery( SubEventItem.objects.filter( - Q(disabled=True) | Q(available_from__gt=now()) | Q(available_until__lt=now()), + Q(disabled=True) | Q(available_from__gt=time_machine_now()) | Q(available_until__lt=time_machine_now()), subevent=OuterRef('pk'), ).order_by().values('subevent').annotate(items=GroupConcat('item_id', delimiter=',')).values('items'), output_field=models.TextField(), @@ -1519,7 +1520,7 @@ class SubEvent(EventMixin, LoggedModel): disabled_vars=Coalesce( Subquery( SubEventItemVariation.objects.filter( - Q(disabled=True) | Q(available_from__gt=now()) | Q(available_until__lt=now()), + Q(disabled=True) | Q(available_from__gt=time_machine_now()) | Q(available_until__lt=time_machine_now()), subevent=OuterRef('pk'), ).order_by().values('subevent').annotate(items=GroupConcat('variation_id', delimiter=',')).values('items'), output_field=models.TextField(), diff --git a/src/pretix/presale/middleware.py b/src/pretix/presale/middleware.py index 4cbf52a839..42a30f2dae 100644 --- a/src/pretix/presale/middleware.py +++ b/src/pretix/presale/middleware.py @@ -79,3 +79,4 @@ class EventMiddleware: response = response.render() return response + diff --git a/src/pretix/presale/templates/pretixpresale/event/base.html b/src/pretix/presale/templates/pretixpresale/event/base.html index a3c2e48a81..f65b811ce4 100644 --- a/src/pretix/presale/templates/pretixpresale/event/base.html +++ b/src/pretix/presale/templates/pretixpresale/event/base.html @@ -33,6 +33,17 @@ {% endif %} + {% if request.now_dt_is_fake %} +
+
+ + {% trans "You are currently using the time machine. The ticket shop is rendered as if it were" %} {{ request.now_dt }} + + {% trans "Go back to current time" %} + +
+
+ {% endif %}