From d160d7a21c70131bee5283c21edf74fe059c85c7 Mon Sep 17 00:00:00 2001 From: Ernesto Rico Schmidt <ernesto@helsinki.at> Date: Mon, 14 Feb 2022 12:46:48 -0400 Subject: [PATCH] Fix datetime usage --- program/management/commands/addnote.py | 4 +-- program/management/commands/export_showlog.py | 4 +-- program/models.py | 16 +++++----- program/serializers.py | 2 +- program/utils.py | 16 +++++++++- program/views.py | 30 +++++++++---------- 6 files changed, 42 insertions(+), 30 deletions(-) diff --git a/program/management/commands/addnote.py b/program/management/commands/addnote.py index fafb33fc..7b8aff6a 100644 --- a/program/management/commands/addnote.py +++ b/program/management/commands/addnote.py @@ -1,10 +1,10 @@ from django.core.management.base import BaseCommand, CommandError from django.core.exceptions import ValidationError -from datetime import datetime import sys from program.models import Show, TimeSlot, Note +from program.utils import parse_date class Command(BaseCommand): @@ -30,7 +30,7 @@ class Command(BaseCommand): raise CommandError(dne) try: - start = datetime.strptime(start_date, '%Y-%m-%d') + start = parse_date(start_date) except ValueError as ve: raise CommandError(ve) else: diff --git a/program/management/commands/export_showlog.py b/program/management/commands/export_showlog.py index 41c20217..e5c86a83 100644 --- a/program/management/commands/export_showlog.py +++ b/program/management/commands/export_showlog.py @@ -25,8 +25,8 @@ class Command(BaseCommand): self.stdout.write(self.style.NOTICE, f"# Radio Helsinki Sendungslog {year}") - start = datetime.strptime('%d__01__01__00__00' % (year), '%Y__%m__%d__%H__%M') - end = datetime.strptime('%d__01__01__00__00' % (year+1), '%Y__%m__%d__%H__%M') + start = datetime(year, 1, 1, 0, 0) + end = datetime(year+1, 1, 1, 0, 0) currentDate = None for ts in TimeSlot.objects.filter(end__gt=start, start__lt=end).select_related('schedule').select_related('show'): diff --git a/program/models.py b/program/models.py index 306be0a9..fe9dafa7 100644 --- a/program/models.py +++ b/program/models.py @@ -18,9 +18,7 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. # -import json from datetime import datetime, time, timedelta -from urllib.request import urlopen from dateutil.relativedelta import relativedelta from dateutil.rrule import rrule @@ -34,7 +32,7 @@ from django.utils.translation import gettext_lazy as _ from versatileimagefield.fields import VersatileImageField, PPOIField from steering.settings import THUMBNAIL_SIZES, AUTO_SET_UNTIL_DATE_TO_END_OF_YEAR, AUTO_SET_UNTIL_DATE_TO_DAYS_IN_FUTURE -from .utils import parse_datetime +from program.utils import parse_datetime, parse_date, parse_time class Type(models.Model): @@ -321,7 +319,7 @@ class Schedule(models.Model): add_days_no = int(sdl['add_days_no']) if sdl['add_days_no'] > 0 else None add_business_days_only = True if 'add_business_days_only' in sdl and sdl['add_business_days_only'] is True else False - dstart = datetime.strptime(str(sdl['dstart']), '%Y-%m-%d').date() + dstart = parse_date(str(sdl['dstart'])) # Schedule mustn't start in the past when adding if pk is None and dstart < timezone.now().date(): @@ -330,18 +328,18 @@ class Schedule(models.Model): tstart = sdl['tstart'] + ':00' if len(str(sdl['tstart'])) == 5 else sdl['tstart'] tend = sdl['tend'] + ':00' if len(str(sdl['tend'])) == 5 else sdl['tend'] - tstart = datetime.strptime(str(tstart), '%H:%M:%S').time() - tend = datetime.strptime(str(tend), '%H:%M:%S').time() + tstart = parse_time(str(tstart)) + tend = parse_time(str(tend)) if sdl['until']: - until = datetime.strptime(str(sdl['until']), '%Y-%m-%d').date() + until = parse_date(str(sdl['until'])) else: # If no until date was set # Set it to the end of the year # Or add x days if AUTO_SET_UNTIL_DATE_TO_END_OF_YEAR: - now = timezone.now() - until = datetime.strptime(str(now.year) + '-12-31', '%Y-%m-%d').date() + year = timezone.now().year + until = parse_date(f'{year}-12-31') else: until = dstart + timedelta(days=+AUTO_SET_UNTIL_DATE_TO_DAYS_IN_FUTURE) diff --git a/program/serializers.py b/program/serializers.py index 8c138fce..5af1f180 100644 --- a/program/serializers.py +++ b/program/serializers.py @@ -28,7 +28,7 @@ from profile.serializers import ProfileSerializer from program.models import Show, Schedule, TimeSlot, Category, FundingCategory, Host, Topic, MusicFocus, Note, Type, Language, \ RRule, Link from steering.settings import THUMBNAIL_SIZES -from .utils import get_audio_url +from program.utils import get_audio_url class UserSerializer(serializers.ModelSerializer): diff --git a/program/utils.py b/program/utils.py index 18d7d751..518c3499 100644 --- a/program/utils.py +++ b/program/utils.py @@ -18,7 +18,7 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. # -from datetime import datetime +from datetime import datetime, date, time import requests from django.utils import timezone @@ -38,6 +38,20 @@ def parse_datetime(date_string: str) -> datetime: return timezone.make_aware(parsed_datetime) +def parse_date(date_string: str) -> date: + """ + parse a date string and return a date object + """ + return datetime.strptime(date_string, "%Y-%m-%d").date() + + +def parse_time(date_string: str) -> time: + """ + parse a time string and return a time object + """ + return datetime.strptime(date_string, "%H:%M:%S").time() + + def get_audio_url(cba_id): """ Retrieve the direct URL to the mp3 in CBA diff --git a/program/views.py b/program/views.py index 70520900..ead86f4a 100644 --- a/program/views.py +++ b/program/views.py @@ -36,15 +36,16 @@ from program.models import Type, MusicFocus, Language, Note, Show, Category, Fun from program.serializers import TypeSerializer, LanguageSerializer, MusicFocusSerializer, NoteSerializer, ShowSerializer, \ ScheduleSerializer, CategorySerializer, FundingCategorySerializer, TopicSerializer, TimeSlotSerializer, HostSerializer, \ UserSerializer +from program.utils import parse_date logger = logging.getLogger(__name__) def json_day_schedule(request, year=None, month=None, day=None): if year is None and month is None and day is None: - today = timezone.make_aware(datetime.combine(date.today(), time(0, 0))) + today = timezone.make_aware(datetime.combine(timezone.now(), time(0, 0))) else: - today = timezone.make_aware(datetime.strptime('%s__%s__%s__00__00' % (year, month, day), '%Y__%m__%d__%H__%M')) + today = timezone.make_aware(datetime.combine(date(year, month, day), time(0, 0))) timeslots = TimeSlot.objects.get_24h_timeslots(today).select_related('schedule').select_related('show') schedule = [] @@ -75,16 +76,16 @@ def json_playout(request): """ if request.GET.get('start') is None: - start = timezone.make_aware(datetime.combine(date.today(), time(0, 0))) + start = timezone.make_aware(datetime.combine(timezone.now(), time(0, 0))) else: - start = timezone.make_aware(datetime.combine(datetime.strptime(request.GET.get('start'), '%Y-%m-%d').date(), time(0, 0))) + start = timezone.make_aware(datetime.combine(parse_date(request.GET.get('start')), time(0, 0))) if request.GET.get('end') is None: # If no end was given, return the next week timeslots = TimeSlot.objects.get_7d_timeslots(start).select_related('schedule').select_related('show') else: # Otherwise return the given timerange - end = timezone.make_aware(datetime.combine(datetime.strptime(request.GET.get('end'), '%Y-%m-%d').date(), time(23, 59))) + end = timezone.make_aware(datetime.combine(parse_date(request.GET.get('end')), time(23, 59))) timeslots = TimeSlot.objects.get_timerange_timeslots(start, end).select_related('schedule').select_related('show') schedule = [] @@ -264,10 +265,10 @@ class APIShowViewSet(viewsets.ModelViewSet): # TODO: Really consider dstart? (=currently active, not just upcoming ones) # Add limit for future? show_ids = Schedule.objects.filter(Q(rrule_id__gt=1, - dstart__lte=date.today(), - until__gte=date.today()) | + dstart__lte=timezone.now(), + until__gte=timezone.now()) | Q(rrule_id=1, - dstart__gte=date.today()) + dstart__gte=timezone.now()) ).distinct().values_list('show_id', flat=True) # Filter active shows based on timeslots as well as on the is_active flag @@ -539,12 +540,12 @@ class APITimeSlotViewSet(viewsets.ModelViewSet): # Filters # Return next 60 days by default - start = timezone.make_aware(datetime.combine(date.today(), time(0, 0))) + start = timezone.make_aware(datetime.combine(timezone.now(), time(0, 0))) end = start + timedelta(days=60) if ('start' in self.request.query_params) and ('end' in self.request.query_params): - start = timezone.make_aware(datetime.combine(datetime.strptime(self.request.query_params.get('start'), '%Y-%m-%d').date(), time(0, 0))) - end = timezone.make_aware(datetime.combine(datetime.strptime(self.request.query_params.get('end'), '%Y-%m-%d').date(), time(23, 59))) + start = timezone.make_aware(datetime.combine(parse_date(self.request.query_params.get('start')), time(0, 0))) + end = timezone.make_aware(datetime.combine(parse_date(self.request.query_params.get('end')), time(23, 59))) default_order = '-start' order = self.request.query_params.get('order', default_order) @@ -555,12 +556,11 @@ class APITimeSlotViewSet(viewsets.ModelViewSet): if order.lstrip('-') not in model_fields: order = default_order - if 'surrounding' in self.request.query_params: - today = timezone.make_aware(datetime.today()) + now = timezone.now() - nearest_timeslots_in_future = TimeSlot.objects.filter(start__gte=today).order_by('start').values_list('id', flat=True)[:5] - nearest_timeslots_in_past = TimeSlot.objects.filter(start__lt=today).order_by('-start').values_list('id', flat=True)[:5] + nearest_timeslots_in_future = TimeSlot.objects.filter(start__gte=now).order_by('start').values_list('id', flat=True)[:5] + nearest_timeslots_in_past = TimeSlot.objects.filter(start__lt=now).order_by('-start').values_list('id', flat=True)[:5] relevant_timeslot_ids = list(nearest_timeslots_in_future) + list(nearest_timeslots_in_past) return TimeSlot.objects.filter(id__in=relevant_timeslot_ids).order_by(order) -- GitLab