From f70897b44c6009bc9c983d00773ef303c3f9289b Mon Sep 17 00:00:00 2001 From: Jonathan Weth <git@jonathanweth.de> Date: Wed, 12 Feb 2020 20:09:16 +0100 Subject: [PATCH] Move prev/next functions to TimePeriod model Close #65 --- aleksis/apps/chronos/models.py | 42 ++++++++++++++++++++++ aleksis/apps/chronos/util/prev_next.py | 48 -------------------------- aleksis/apps/chronos/views.py | 21 ++++++----- 3 files changed, 52 insertions(+), 59 deletions(-) delete mode 100644 aleksis/apps/chronos/util/prev_next.py diff --git a/aleksis/apps/chronos/models.py b/aleksis/apps/chronos/models.py index 0f9c5f9e..70fb2bed 100644 --- a/aleksis/apps/chronos/models.py +++ b/aleksis/apps/chronos/models.py @@ -9,6 +9,8 @@ from django.db import models from django.db.models import F, Max, Min, Q from django.db.models.functions import Coalesce from django.http.request import QueryDict +from django.urls import reverse +from django.utils import timezone from django.utils.decorators import classproperty from django.utils.translation import ugettext_lazy as _ @@ -246,6 +248,46 @@ class TimePeriod(models.Model): return wanted_week[self.weekday] + @classmethod + def get_next_relevant_day(cls, day: Optional[date] = None, time: Optional[time] = None, prev: bool = False) -> date: + """ Returns next (previous) day with lessons depending on date and time """ + + if day is None: + day = timezone.now().date() + + if time is not None and not prev: + if time > cls.time_max: + day += timedelta(days=1) + + cw = CalendarWeek.from_date(day) + + if day.weekday() > cls.weekday_max: + if prev: + day = cw[cls.weekday_max] + else: + cw += 1 + day = cw[cls.weekday_min] + elif day.weekday() < TimePeriod.weekday_min: + if prev: + cw -= 1 + day = cw[cls.weekday_max] + else: + day = cw[cls.weekday_min] + + return day + + @classmethod + def get_prev_next_by_day(cls, day: date, url: str) -> Tuple[str, str]: + """ Build URLs for previous/next day """ + + day_prev = cls.get_next_relevant_day(day - timedelta(days=1), prev=True) + day_next = cls.get_next_relevant_day(day + timedelta(days=1)) + + url_prev = reverse(url, args=[day_prev.year, day_prev.month, day_prev.day]) + url_next = reverse(url, args=[day_next.year, day_next.month, day_next.day]) + + return url_prev, url_next + @classproperty def period_min(cls) -> int: return cls.objects.aggregate(period__min=Coalesce(Min("period"), 1)).get("period__min") diff --git a/aleksis/apps/chronos/util/prev_next.py b/aleksis/apps/chronos/util/prev_next.py deleted file mode 100644 index 4f954c30..00000000 --- a/aleksis/apps/chronos/util/prev_next.py +++ /dev/null @@ -1,48 +0,0 @@ -from datetime import timedelta, date, time -from typing import Optional, Tuple - -from calendarweek import CalendarWeek -from django.urls import reverse -from django.utils import timezone - -from ..models import TimePeriod - - -def get_next_relevant_day(day: Optional[date] = None, time: Optional[time] = None, prev: bool = False) -> date: - """ Returns next (previous) day with lessons depending on date and time """ - - if day is None: - day = timezone.now().date() - - if time is not None and not prev: - if time > TimePeriod.time_max: - day += timedelta(days=1) - - cw = CalendarWeek.from_date(day) - - if day.weekday() > TimePeriod.weekday_max: - if prev: - day = cw[TimePeriod.weekday_max] - else: - cw += 1 - day = cw[TimePeriod.weekday_min] - elif day.weekday() < TimePeriod.weekday_min: - if prev: - cw -= 1 - day = cw[TimePeriod.weekday_max] - else: - day = cw[TimePeriod.weekday_min] - - return day - - -def get_prev_next_by_day(day: date, url: str) -> Tuple[str, str]: - """ Build URLs for previous/next day """ - - day_prev = get_next_relevant_day(day - timedelta(days=1), prev=True) - day_next = get_next_relevant_day(day + timedelta(days=1)) - - url_prev = reverse(url, args=[day_prev.year, day_prev.month, day_prev.day]) - url_next = reverse(url, args=[day_next.year, day_next.month, day_next.day]) - - return url_prev, url_next diff --git a/aleksis/apps/chronos/views.py b/aleksis/apps/chronos/views.py index 388307c0..cbeb7e85 100644 --- a/aleksis/apps/chronos/views.py +++ b/aleksis/apps/chronos/views.py @@ -19,7 +19,6 @@ from .forms import LessonSubstitutionForm from .models import LessonPeriod, LessonSubstitution, TimePeriod, Room from .tables import LessonsTable from .util.js import date_unix -from .util.prev_next import get_next_relevant_day, get_prev_next_by_day from .util.weeks import CalendarWeek, get_weeks_for_year from aleksis.core.util.core_helpers import has_person @@ -56,9 +55,9 @@ def my_timetable( if day: wanted_day = timezone.datetime(year=year, month=month, day=day).date() - wanted_day = get_next_relevant_day(wanted_day) + wanted_day = TimePeriod.get_next_relevant_day(wanted_day) else: - wanted_day = get_next_relevant_day(timezone.now().date(), datetime.now().time()) + wanted_day = TimePeriod.get_next_relevant_day(timezone.now().date(), datetime.now().time()) if has_person(request.user): person = request.user.person @@ -98,7 +97,7 @@ def my_timetable( context["periods"] = TimePeriod.get_times_dict() context["smart"] = True - context["url_prev"], context["url_next"] = get_prev_next_by_day( + context["url_prev"], context["url_next"] = TimePeriod.get_prev_next_by_day( wanted_day, "my_timetable_by_date" ) @@ -209,9 +208,9 @@ def lessons_day( if day: wanted_day = timezone.datetime(year=year, month=month, day=day).date() - wanted_day = get_next_relevant_day(wanted_day) + wanted_day = TimePeriod.get_next_relevant_day(wanted_day) else: - wanted_day = get_next_relevant_day(timezone.now().date(), datetime.now().time()) + wanted_day = TimePeriod.get_next_relevant_day(timezone.now().date(), datetime.now().time()) # Get lessons lesson_periods = LessonPeriod.objects.on_day(wanted_day) @@ -229,7 +228,7 @@ def lessons_day( "dest": reverse("lessons_day") } - context["url_prev"], context["url_next"] = get_prev_next_by_day( + context["url_prev"], context["url_next"] = TimePeriod.get_prev_next_by_day( wanted_day, "lessons_day_by_date" ) @@ -305,9 +304,9 @@ def substitutions( if day: wanted_day = timezone.datetime(year=year, month=month, day=day).date() - wanted_day = get_next_relevant_day(wanted_day) + wanted_day = TimePeriod.get_next_relevant_day(wanted_day) else: - wanted_day = get_next_relevant_day(timezone.now().date(), datetime.now().time()) + wanted_day = TimePeriod.get_next_relevant_day(timezone.now().date(), datetime.now().time()) day_number = config.CHRONOS_SUBSTITUTIONS_PRINT_DAY_NUMBER day_contexts = {} @@ -316,7 +315,7 @@ def substitutions( next_day = wanted_day for i in range(day_number): day_contexts[next_day] = {"day": next_day} - next_day = get_next_relevant_day(next_day + timedelta(days=1)) + next_day = TimePeriod.get_next_relevant_day(next_day + timedelta(days=1)) else: day_contexts = {wanted_day: {"day": wanted_day}} @@ -332,7 +331,7 @@ def substitutions( "dest": reverse("substitutions"), } - context["url_prev"], context["url_next"] = get_prev_next_by_day( + context["url_prev"], context["url_next"] = TimePeriod.get_prev_next_by_day( wanted_day, "substitutions_by_date" ) -- GitLab