Skip to content

Commit

Permalink
add api route to get participations for user (#1222)
Browse files Browse the repository at this point in the history
Co-authored-by: Felix Rindt <[email protected]>
  • Loading branch information
jeriox and felixrindt authored Mar 16, 2024
1 parent b8e4e61 commit 028e08f
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 4 deletions.
6 changes: 6 additions & 0 deletions ephios/api/fields.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from rest_framework.fields import ChoiceField


class ChoiceDisplayField(ChoiceField):
def to_representation(self, value):
return {"value": value, "label": self.choices[value]}
15 changes: 13 additions & 2 deletions ephios/api/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,23 @@
ApplicationDetail,
ApplicationUpdate,
)
from ephios.api.views.events import EventViewSet
from ephios.api.views.users import UserProfileMeView
from ephios.api.views.events import EventViewSet, ShiftViewSet
from ephios.api.views.users import (
UserByMailView,
UserParticipationView,
UserProfileMeView,
UserViewSet,
)
from ephios.extra.permissions import staff_required

router = routers.DefaultRouter()
router.register(r"events", EventViewSet)
router.register(r"shifts", ShiftViewSet)
router.register(r"users", UserViewSet)
router.register(r"users/by_email", UserByMailView, basename="user-by-email")
router.register(
r"users/(?P<user>[\d]+)/participations", UserParticipationView, basename="user-participations"
)

app_name = "api"
urlpatterns = [
Expand Down
38 changes: 37 additions & 1 deletion ephios/api/views/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
from rest_framework.permissions import DjangoObjectPermissions
from rest_framework_guardian import filters as guardian_filters

from ephios.core.models import Event, EventType, Shift
from ephios.api.fields import ChoiceDisplayField
from ephios.core.models import AbstractParticipation, Event, EventType, LocalParticipation, Shift
from ephios.core.templatetags.settings_extras import make_absolute


Expand Down Expand Up @@ -69,6 +70,14 @@ class Meta:
]


class ShiftViewSet(viewsets.ReadOnlyModelViewSet):
serializer_class = ShiftSerializer
permission_classes = [DjangoObjectPermissions, IsAuthenticatedOrTokenHasScope]
filter_backends = [guardian_filters.ObjectPermissionsFilter]
required_scopes = ["PUBLIC_READ"]
queryset = Shift.objects.all()


class EventViewSet(viewsets.ReadOnlyModelViewSet):
serializer_class = EventSerializer
filterset_fields = ["type"]
Expand Down Expand Up @@ -96,3 +105,30 @@ class EventViewSet(viewsets.ReadOnlyModelViewSet):
.prefetch_related(Prefetch("shifts__participations"))
.order_by("start_time")
)


class ParticipationSerializer(serializers.ModelSerializer):
event_title = serializers.CharField(source="shift.event.title")
state = ChoiceDisplayField(choices=AbstractParticipation.States.choices)
duration = serializers.SerializerMethodField()

class Meta:
model = LocalParticipation
fields = [
"id",
"shift",
"event_title",
"state",
"comment",
"start_time",
"end_time",
"duration",
]

def build_unknown_field(self, field_name, model_class):
if field_name in {"start_time", "end_time"}:
return self.build_property_field(field_name, model_class)
return super().build_unknown_field(field_name, model_class)

def get_duration(self, obj):
return (obj.end_time - obj.start_time).total_seconds()
46 changes: 45 additions & 1 deletion ephios/api/views/users.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
from django.db.models import Q
from django.utils import timezone
from django_filters.rest_framework import DjangoFilterBackend
from oauth2_provider.contrib.rest_framework import IsAuthenticatedOrTokenHasScope
from rest_framework import viewsets
from rest_framework.exceptions import PermissionDenied
from rest_framework.fields import SerializerMethodField
from rest_framework.filters import SearchFilter
from rest_framework.generics import RetrieveAPIView
from rest_framework.mixins import RetrieveModelMixin
from rest_framework.permissions import DjangoObjectPermissions
from rest_framework.relations import SlugRelatedField
from rest_framework.serializers import ModelSerializer
from rest_framework.viewsets import GenericViewSet
from rest_framework_guardian.filters import ObjectPermissionsFilter

from ephios.core.models import Qualification, UserProfile
from ephios.api.views.events import ParticipationSerializer
from ephios.core.models import LocalParticipation, Qualification, UserProfile
from ephios.core.services.qualification import collect_all_included_qualifications


Expand Down Expand Up @@ -35,6 +43,7 @@ class UserProfileSerializer(ModelSerializer):
class Meta:
model = UserProfile
fields = [
"id",
"display_name",
"date_of_birth",
"email",
Expand All @@ -61,3 +70,38 @@ def get_object(self):
if self.request.user is None:
raise PermissionDenied()
return self.request.user


class UserViewSet(viewsets.ReadOnlyModelViewSet):
serializer_class = UserProfileSerializer
queryset = UserProfile.objects.all()
permission_classes = [IsAuthenticatedOrTokenHasScope, DjangoObjectPermissions]
required_scopes = ["CONFIDENTIAL_READ"]
search_fields = ["display_name", "email"]

filter_backends = [
DjangoFilterBackend,
SearchFilter,
ObjectPermissionsFilter,
]


class UserByMailView(RetrieveModelMixin, GenericViewSet):
serializer_class = UserProfileSerializer
queryset = UserProfile.objects.all()
permission_classes = [IsAuthenticatedOrTokenHasScope, DjangoObjectPermissions]
required_scopes = ["CONFIDENTIAL_READ"]
filter_backends = [ObjectPermissionsFilter]
lookup_url_kwarg = "email"
lookup_field = "email"


class UserParticipationView(viewsets.ReadOnlyModelViewSet):
serializer_class = ParticipationSerializer
permission_classes = [IsAuthenticatedOrTokenHasScope]
filter_backends = [ObjectPermissionsFilter, DjangoFilterBackend]
filterset_fields = ["state"]
required_scopes = ["CONFIDENTIAL_READ"]

def get_queryset(self):
return LocalParticipation.objects.filter(user=self.kwargs["user"])

0 comments on commit 028e08f

Please sign in to comment.