More views in DRF.
[wolnelektury.git] / src / social / api / views.py
1 # -*- coding: utf-8 -*-
2 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
3 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
4 #
5 from django.http import Http404
6 from rest_framework.generics import ListAPIView, get_object_or_404
7 from rest_framework.permissions import IsAuthenticated
8 from rest_framework.response import Response
9 from rest_framework.views import APIView
10 from api.models import BookUserData
11 from catalogue.api.helpers import order_books, books_after
12 from catalogue.api.serializers import BookSerializer
13 from catalogue.models import Book
14 from social.utils import likes
15
16
17 class LikeView(APIView):
18     permission_classes = [IsAuthenticated]
19
20     def get(self, request, slug):
21         book = get_object_or_404(Book, slug=slug)
22         return Response({"likes": likes(request.user, book)})
23
24     def post(self, request, slug):
25         book = get_object_or_404(Book, slug=slug)
26         action = request.query_params.get('action', 'like')
27         if action == 'like':
28             book.like(request.user)
29         elif action == 'unlike':
30             book.unlike(request.user)
31         return Response({})
32
33
34 class ShelfView(ListAPIView):
35     permission_classes = [IsAuthenticated]
36     serializer_class = BookSerializer
37
38     def get_queryset(self):
39         state = self.kwargs['state']
40         if state not in ('reading', 'complete', 'likes'):
41             raise Http404
42         new_api = self.request.query_params.get('new_api')
43         after = self.request.query_params.get('after')
44         count = int(self.request.query_params.get('count', 50))
45         if state == 'likes':
46             books = Book.tagged.with_any(self.request.user.tag_set.all())
47         else:
48             ids = BookUserData.objects.filter(user=self.request.user, complete=state == 'complete')\
49                 .values_list('book_id', flat=True)
50             books = Book.objects.filter(id__in=list(ids)).distinct()
51             books = order_books(books, new_api)
52         if after:
53             books = books_after(books, after, new_api)
54         if count:
55             books = books[:count]
56
57         return books
58