cineclub-site/server/myapi/views/std_views.py

81 lines
3 KiB
Python

# 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, mixins.ListModelMixin, 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 calendar(self, request):
qs = self.get_queryset().annotate(
projection_month=TruncMonth("projection_date")
)
grouped = groupby(qs, 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 Response(data)