Commit b332bc03 authored by Luko van der Maas's avatar Luko van der Maas Committed by Sébastiaan Versteeg
Browse files

Merge branch 'fix/birthdays-calendar' into 'master'

Fix the birthdays calendar by refactoring the start/end date query parsing

Closes #764

See merge request thalia/concrexit!1049

(cherry picked from commit 4943127f)

168a2222 Fix the birthdays calendar by refactoring the start/end date query parsing
parent 22e9c9cd
"""Defines the viewsets of the events package""" """Defines the viewsets of the events package"""
from datetime import datetime
from django.utils import timezone from django.utils import timezone
from pytz.exceptions import InvalidTimeError
from rest_framework import viewsets, filters from rest_framework import viewsets, filters
from rest_framework.decorators import action from rest_framework.decorators import action
from rest_framework.exceptions import ParseError, PermissionDenied, NotFound from rest_framework.exceptions import PermissionDenied, NotFound
from rest_framework.generics import get_object_or_404 from rest_framework.generics import get_object_or_404
from rest_framework.mixins import RetrieveModelMixin, UpdateModelMixin from rest_framework.mixins import RetrieveModelMixin, UpdateModelMixin
from rest_framework.permissions import ( from rest_framework.permissions import (
...@@ -26,27 +24,7 @@ from events.api.serializers import ( ...@@ -26,27 +24,7 @@ from events.api.serializers import (
RegistrationListSerializer, RegistrationSerializer) RegistrationListSerializer, RegistrationSerializer)
from events.exceptions import RegistrationError from events.exceptions import RegistrationError
from events.models import Event, Registration from events.models import Event, Registration
from utils.snippets import extract_date_range
def _extract_date(param):
"""Extract the date from an arbitrary string"""
if param is None:
return None
try:
return timezone.make_aware(
datetime.strptime(param, '%Y-%m-%dT%H:%M:%S'))
except ValueError:
return timezone.make_aware(datetime.strptime(param, '%Y-%m-%d'))
def _extract_date_range(request):
"""Extract a date range from an arbitrary string"""
try:
start = _extract_date(request.query_params['start'])
end = _extract_date(request.query_params['end'])
except (ValueError, KeyError, InvalidTimeError) as e:
raise ParseError(detail='start or end query parameters invalid') from e
return end, start
class EventViewset(viewsets.ReadOnlyModelViewSet): class EventViewset(viewsets.ReadOnlyModelViewSet):
...@@ -65,14 +43,7 @@ class EventViewset(viewsets.ReadOnlyModelViewSet): ...@@ -65,14 +43,7 @@ class EventViewset(viewsets.ReadOnlyModelViewSet):
if self.action == 'retrieve': if self.action == 'retrieve':
return queryset return queryset
try: start, end = extract_date_range(self.request, allow_empty=True)
start = _extract_date(self.request.query_params.get('start', None))
except (ValueError, InvalidTimeError) as e:
raise ParseError(detail='start query parameter invalid') from e
try:
end = _extract_date(self.request.query_params.get('end', None))
except (ValueError, InvalidTimeError) as e:
raise ParseError(detail='end query parameter invalid') from e
if start is not None: if start is not None:
queryset = queryset.filter(start__gte=start) queryset = queryset.filter(start__gte=start)
...@@ -150,7 +121,7 @@ class EventViewset(viewsets.ReadOnlyModelViewSet): ...@@ -150,7 +121,7 @@ class EventViewset(viewsets.ReadOnlyModelViewSet):
:return: response containing the data :return: response containing the data
""" """
end, start = _extract_date_range(request) start, end = extract_date_range(request)
queryset = Event.objects.filter( queryset = Event.objects.filter(
end__gte=start, end__gte=start,
...@@ -172,7 +143,7 @@ class EventViewset(viewsets.ReadOnlyModelViewSet): ...@@ -172,7 +143,7 @@ class EventViewset(viewsets.ReadOnlyModelViewSet):
:param request: the request object :param request: the request object
:return: response containing the data :return: response containing the data
""" """
end, start = _extract_date_range(request) start, end = extract_date_range(request)
queryset = Event.objects.filter( queryset = Event.objects.filter(
end__gte=start, end__gte=start,
......
import copy import copy
from datetime import datetime
from django.utils import timezone
from pytz.exceptions import InvalidTimeError
from rest_framework import permissions from rest_framework import permissions
from rest_framework import viewsets, filters from rest_framework import viewsets, filters
from rest_framework.decorators import action from rest_framework.decorators import action
from rest_framework.exceptions import ParseError
from rest_framework.response import Response from rest_framework.response import Response
from members.api.serializers import (MemberBirthdaySerializer, from members.api.serializers import (MemberBirthdaySerializer,
MemberRetrieveSerializer, MemberRetrieveSerializer,
MemberListSerializer) MemberListSerializer)
from members.models import Member from members.models import Member
from utils.snippets import extract_date_range
def _extract_date(param):
"""Extract the date from an arbitrary string"""
if param is None:
return None
try:
return timezone.make_aware(
datetime.strptime(param, '%Y-%m-%dT%H:%M:%S'))
except ValueError:
return timezone.make_aware(datetime.strptime(param, '%Y-%m-%d'))
def _extract_date_range(request):
"""Extract a date range from an arbitrary string"""
try:
start = _extract_date(request.query_params['start'])
end = _extract_date(request.query_params['end'])
except (ValueError, KeyError, InvalidTimeError) as e:
raise ParseError(detail='start or end query parameters invalid') from e
return end, start
class MemberViewset(viewsets.ReadOnlyModelViewSet): class MemberViewset(viewsets.ReadOnlyModelViewSet):
...@@ -77,14 +53,7 @@ class MemberViewset(viewsets.ReadOnlyModelViewSet): ...@@ -77,14 +53,7 @@ class MemberViewset(viewsets.ReadOnlyModelViewSet):
@action(detail=False) @action(detail=False)
def birthdays(self, request): def birthdays(self, request):
try: start, end = extract_date_range(request)
start = timezone.make_aware(
datetime.strptime(request.query_params['start'], '%Y-%m-%d')
)
end = _extract_date(request.query_params['end'])
except (ValueError, KeyError, InvalidTimeError) as e:
raise ParseError(
detail='start or end query parameters invalid') from e
queryset = ( queryset = (
Member.current_members Member.current_members
......
from datetime import datetime
from django.utils import timezone from django.utils import timezone
from pytz.exceptions import InvalidTimeError
from rest_framework import viewsets, filters from rest_framework import viewsets, filters
from rest_framework.decorators import action from rest_framework.decorators import action
from rest_framework.exceptions import ParseError
from rest_framework.permissions import ( from rest_framework.permissions import (
IsAuthenticatedOrReadOnly, IsAuthenticated IsAuthenticatedOrReadOnly, IsAuthenticated
) )
from rest_framework.response import Response from rest_framework.response import Response
from partners.api.serializers import ( from partners.api.serializers import (
PartnerEventCalendarJSSerializer, PartnerEventSerializer, PartnerEventCalendarJSSerializer, PartnerEventSerializer,
PartnerSerializer PartnerSerializer
) )
from partners.models import Partner, PartnerEvent from partners.models import Partner, PartnerEvent
from utils.snippets import extract_date_range
def _extract_date(param):
"""Extract the date from an arbitrary string"""
if param is None:
return None
try:
return timezone.make_aware(
datetime.strptime(param, '%Y-%m-%dT%H:%M:%S'))
except ValueError:
return timezone.make_aware(datetime.strptime(param, '%Y-%m-%d'))
def _extract_date_range(request):
"""Extract a date range from an arbitrary string"""
try:
start = _extract_date(request.query_params['start'])
end = _extract_date(request.query_params['end'])
except (ValueError, KeyError, InvalidTimeError) as e:
raise ParseError(detail='start or end query parameters invalid') from e
return end, start
class PartnerViewset(viewsets.ReadOnlyModelViewSet): class PartnerViewset(viewsets.ReadOnlyModelViewSet):
...@@ -44,7 +20,7 @@ class PartnerViewset(viewsets.ReadOnlyModelViewSet): ...@@ -44,7 +20,7 @@ class PartnerViewset(viewsets.ReadOnlyModelViewSet):
@action(detail=False, permission_classes=(IsAuthenticatedOrReadOnly,)) @action(detail=False, permission_classes=(IsAuthenticatedOrReadOnly,))
def calendarjs(self, request): def calendarjs(self, request):
end, start = _extract_date_range(request) start, end = extract_date_range(request)
queryset = PartnerEvent.objects.filter( queryset = PartnerEvent.objects.filter(
end__gte=start, end__gte=start,
......
...@@ -2,10 +2,13 @@ ...@@ -2,10 +2,13 @@
import hmac import hmac
from _sha1 import sha1 from _sha1 import sha1
from base64 import urlsafe_b64decode, urlsafe_b64encode from base64 import urlsafe_b64decode, urlsafe_b64encode
from datetime import datetime
from django.conf import settings from django.conf import settings
from django.utils import timezone from django.utils import timezone
from django.template.defaultfilters import urlencode from django.template.defaultfilters import urlencode
from pytz import InvalidTimeError
from rest_framework.exceptions import ParseError
def datetime_to_lectureyear(date): def datetime_to_lectureyear(date):
...@@ -50,3 +53,34 @@ def create_google_maps_url(location, zoom, size): ...@@ -50,3 +53,34 @@ def create_google_maps_url(location, zoom, size):
maps_url += f"&signature={encoded_signature.decode('utf-8')}" maps_url += f"&signature={encoded_signature.decode('utf-8')}"
return "https://maps.googleapis.com" + maps_url return "https://maps.googleapis.com" + maps_url
def _extract_date(param):
"""Extract the date from an arbitrary string"""
if param is None:
return None
try:
return timezone.make_aware(
datetime.strptime(param, '%Y-%m-%dT%H:%M:%S'))
except ValueError:
return timezone.make_aware(datetime.strptime(param, '%Y-%m-%d'))
def extract_date_range(request, allow_empty=False):
"""Extract a date range from an arbitrary string"""
default_value = ''
if allow_empty:
default_value = None
try:
start = _extract_date(request.query_params.get('start', default_value))
except (ValueError, InvalidTimeError) as e:
raise ParseError(detail='start query parameter invalid') from e
try:
end = _extract_date(request.query_params.get('end', default_value))
except (ValueError, InvalidTimeError) as e:
raise ParseError(detail='end query parameter invalid') from e
return start, end
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment