Skip to content

Commit

Permalink
Merge pull request #84 from Deep-Chill/issue-77-v2
Browse files Browse the repository at this point in the history
[Work-in-Progress] Allow marking webinar attendance via API endpoint(#77)
  • Loading branch information
smirolo authored Dec 5, 2023
2 parents e021f49 + 27253f4 commit db22fa8
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 6 deletions.
64 changes: 61 additions & 3 deletions pages/api/sequences.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,16 @@
import logging

from django.db import IntegrityError
from django.shortcuts import get_object_or_404
from rest_framework import (response as api_response,
viewsets, status)
from rest_framework.decorators import action
from rest_framework.views import APIView

from ..models import (Sequence, EnumeratedElements)
from ..serializers import (SequenceSerializer, EnumeratedElementSerializer)
from ..models import (Sequence, EnumeratedElements,
SequenceProgress, EnumeratedProgress, LiveEvent)
from ..serializers import (SequenceSerializer,
EnumeratedElementSerializer, AttendanceInputSerializer)

LOGGER = logging.getLogger(__name__)

Expand Down Expand Up @@ -275,8 +279,62 @@ def remove_element(self, request, slug=None, element_rank=None):
try:
element = EnumeratedElements.objects.get(sequence=sequence, rank=element_rank)
element.delete()
return api_response.Response({'detail': 'element removed'}, status=status.HTTP_200_OK)
return api_response.Response(
{'detail': 'element removed'}, status=status.HTTP_200_OK)
except EnumeratedElements.DoesNotExist:
return api_response.Response({'detail': 'element not found in sequence'},
status=status.HTTP_404_NOT_FOUND)
return api_response.Response({'detail': 'Invalid rank'}, status=status.HTTP_400_BAD_REQUEST)


class LiveEventAttendanceAPIView(APIView):
'''
Allows marking a user's attendance to a Live Event.
The user's EnumeratedProgress viewing duration for the event is updated to
meet the minimum viewing duration requirement of the associated EnumeratedElement.
**Tags**: attendance, live events
'''
def post(self, request, *args, **kwargs):
"""
- **Mark a User's attendance at a Live Event**
.. code-block:: http
POST /api/sequences/{sequence}/{rank}/{username}/mark-attendance HTTP/1.1
Responds
.. code-block:: json
{
"detail": "Attendance marked successfully"
}
"""

input_serializer = AttendanceInputSerializer(data=self.kwargs)
input_serializer.is_valid(raise_exception=True)

sequence = input_serializer.validated_data['sequence']
user = input_serializer.validated_data['username']
rank = input_serializer.validated_data['rank']

sequence_progress, _ = SequenceProgress.objects.get_or_create(
user=user, sequence=sequence)
enumerated_progress, _ = EnumeratedProgress.objects.get_or_create(
progress=sequence_progress, rank=rank)
enumerated_element = get_object_or_404(
EnumeratedElements, rank=rank, sequence=sequence)
page_element = enumerated_element.page_element
live_event = LiveEvent.objects.filter(element=page_element).first()

# We use if live_event to confirm the existence of the LiveEvent object
if live_event and enumerated_progress.viewing_duration <= enumerated_element.min_viewing_duration:
enumerated_progress.viewing_duration = enumerated_element.min_viewing_duration
enumerated_progress.save()
return api_response.Response(
{'detail': 'Attendance marked successfully'}, status=status.HTTP_200_OK)
return api_response.Response(
{'detail': 'Attendance not marked'}, status=status.HTTP_400_BAD_REQUEST)
2 changes: 1 addition & 1 deletion pages/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,7 @@ class SequenceProgress(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
extra = get_extra_field_class()(null=True, blank=True,
help_text=_("Extra meta data (can be stringify JSON)"))
completion_date = models.DateTimeField(
completion_date = models.DateTimeField(blank=True, null=True,
help_text=_("Time when the user completed the Sequence"))

def __str__(self):
Expand Down
16 changes: 16 additions & 0 deletions pages/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
from rest_framework import serializers
from django.contrib.auth import get_user_model
from django.db import transaction
from django.shortcuts import get_object_or_404


from . import settings
Expand Down Expand Up @@ -368,3 +369,18 @@ class EnumeratedProgressPingSerializer(serializers.ModelSerializer):
class Meta:
model = EnumeratedProgress
fields = ('created_at', 'viewing_duration', 'last_ping_time')

class AttendanceInputSerializer(serializers.Serializer):
"""
Serializer to validate input to mark users' attendance
to a LiveEvent(LiveEventAttendanceAPIView)
"""
sequence = serializers.SlugField()
username = serializers.CharField()
rank = serializers.IntegerField()

def validate_sequence(self, value):
return get_object_or_404(Sequence, slug=value)

def validate_username(self, value):
return get_object_or_404(get_user_model(), username=value)
2 changes: 1 addition & 1 deletion pages/urls/api/progress.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
"""

from ...api.progress import EnumeratedProgressAPIView
from django.urls import path
from ...compat import path

urlpatterns = [
path('<slug:sequence>',
Expand Down
7 changes: 6 additions & 1 deletion pages/urls/api/sequences.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,17 @@
API URLs for sequence objects
"""

from ...api.sequences import (SequenceAPIView)
from ...api.sequences import (SequenceAPIView, LiveEventAttendanceAPIView)
from rest_framework.routers import DefaultRouter

from ...compat import path

router = DefaultRouter(trailing_slash=False)
router.register(r'sequences',
SequenceAPIView,
basename='api_sequences')
urlpatterns = [
path('sequences/<slug:sequence>/<int:rank>/<username>/mark-attendance',
LiveEventAttendanceAPIView.as_view(),
name='api_mark_attendance')
] + router.urls

0 comments on commit db22fa8

Please sign in to comment.