# from django.shortcuts import render from datetime import datetime from itertools import groupby from typing import Callable from django.db.models import Q from django.db.models.functions import TruncMonth from rest_framework import viewsets, mixins from rest_framework.decorators import action from rest_framework.permissions import IsAuthenticated from rest_framework.renderers import StaticHTMLRenderer from rest_framework.response import Response from rest_framework.viewsets import GenericViewSet from myapi.renderers import LatexRenderer, PlainTextRenderer from myapi.serializers import FilmSerializer from myapi.models import Film import myapi.services.com_service as com class AdminFilmViewSet(viewsets.ModelViewSet): queryset = Film.objects.all().order_by("-projection_date") serializer_class = FilmSerializer permission_classes = [IsAuthenticated] def general_com_view(self, com_function: Callable[[Film], str]): film: Film = self.get_object() preview_text = com_function(film) return Response(preview_text) # TODO confirm that latex renderer is not a problem @action(detail=True, methods=["GET"], renderer_classes=[LatexRenderer]) def bocal(self, request, pk=None): return self.general_com_view(com.bocal) @action(detail=True, methods=["GET"]) def facebook(self, request, pk=None): film: Film = self.get_object() fb_text = com.facebook_text(film) fb_title = com.facebook_title(film) return Response( {"title": fb_title, "body": fb_text, "banner_link": film.banner_link} ) @action(detail=True, methods=["GET"], renderer_classes=[StaticHTMLRenderer]) def newsletter(self, request, pk=None): return self.general_com_view(com.mail) @action(detail=True, methods=["GET"], renderer_classes=[PlainTextRenderer]) def ics(self, request, pk=None): return self.general_com_view(com.ics) class FilmViewSet(mixins.RetrieveModelMixin, GenericViewSet): serializer_class = FilmSerializer def get_queryset(self): queryset = Film.objects.all().filter(is_confirmed=True) past = self.request.query_params.get("period", "future") == "past" date_filter = ( Q(projection_date__date__lt=datetime.now()) if past else Q(projection_date__date__gte=datetime.now()) ) ordering = f"{'-' if past else ''}projection_date" return queryset.filter(date_filter).order_by(ordering) @action(detail=False, methods=["GET"]) def home(self, request, *args, **kwargs): queryset = self.filter_queryset(self.get_queryset())[:5] serializer = self.get_serializer(queryset, many=True) return Response(serializer.data) @action(detail=False, methods=["GET"]) def calendar(self, request): qs = self.get_queryset().annotate( projection_month=TruncMonth("projection_date") ) page = self.paginate_queryset(qs) or qs grouped = groupby(page, lambda f: f.projection_month) data = [ { "projection_month": month.strftime("%B %Y"), "films": FilmSerializer(monthly_data, many=True).data, } for (month, monthly_data) in grouped ] return self.get_paginated_response(data)