Sync deleted bookmarks
[wolnelektury.git] / src / bookmarks / api / views.py
1 from api.utils import never_cache
2
3 from django.db.models import Q
4 from django.http import Http404, JsonResponse
5 from django.shortcuts import render, get_object_or_404
6 from django.utils.timezone import now
7 from django.views.decorators import cache
8 import catalogue.models
9 from wolnelektury.utils import is_ajax
10 from bookmarks import models
11 from lxml import html
12 import re
13 from rest_framework.generics import ListAPIView, ListCreateAPIView, RetrieveUpdateDestroyAPIView
14 from rest_framework import serializers
15 from rest_framework.permissions import SAFE_METHODS, IsAuthenticated, IsAuthenticatedOrReadOnly
16 from api.fields import AbsoluteURLField
17 from catalogue.api.serializers import BookSerializer2
18
19
20 class BookmarkSerializerV3(serializers.ModelSerializer):
21     """Replaced in API v4."""
22     book = serializers.SlugRelatedField(
23         queryset=catalogue.models.Book.objects.all(), slug_field='slug',
24         required=False
25     )
26     href = AbsoluteURLField(view_name='api_bookmark', view_args=['uuid'])
27     timestamp = serializers.IntegerField(required=False)
28     location = serializers.CharField(required=False)
29     
30     class Meta:
31         model = models.Bookmark
32         fields = ['book', 'anchor', 'audio_timestamp', 'mode', 'note', 'href', 'uuid', 'location', 'timestamp', 'deleted']
33         read_only_fields = ['uuid', 'mode']
34
35
36 class BookmarkSerializer(serializers.ModelSerializer):
37     book_slug = serializers.SlugRelatedField(
38         queryset=catalogue.models.Book.objects.all(), slug_field='slug',
39         write_only=True,
40         required=False
41     )
42     book = BookSerializer2(read_only=True)
43     href = AbsoluteURLField(view_name='api_bookmark', view_args=['uuid'])
44     timestamp = serializers.IntegerField(required=False)
45     location = serializers.CharField(required=False)
46     
47     class Meta:
48         model = models.Bookmark
49         fields = ['book_slug', 'book', 'anchor', 'audio_timestamp', 'mode', 'note', 'href', 'uuid', 'location', 'timestamp', 'deleted']
50         read_only_fields = ['uuid', 'mode']
51
52     def create(self, validated_data):
53         book = validated_data.pop('book_slug', None)
54         if book is not None:
55             validated_data['book'] = book
56         return super().create(validated_data)
57
58     def update(self, instance, validated_data):
59         book = validated_data.pop('book_slug', None)
60         if book is not None:
61             validated_data['book'] = book
62         return super().update(instance, validated_data)
63
64 @never_cache
65 class BookmarksView(ListCreateAPIView):
66     permission_classes = [IsAuthenticated]
67
68     def get_serializer_class(self):
69         if self.request.version < 'v4':
70             return BookmarkSerializerV3
71         else:
72             return BookmarkSerializer
73     
74     def get_queryset(self):
75         return self.request.user.bookmark_set.all()
76
77     def perform_create(self, serializer):
78         serializer.save(user=self.request.user)
79
80
81 @never_cache
82 class BookBookmarksView(ListAPIView):
83     permission_classes = [IsAuthenticated]
84     pagination_class = None
85
86     def get_serializer_class(self):
87         if self.request.version < 'v4':
88             return BookmarkSerializerV3
89         else:
90             return BookmarkSerializer
91     
92     def get_queryset(self):
93         return self.request.user.bookmark_set.filter(book__slug=self.kwargs['book'])
94
95
96 @never_cache
97 class BookmarkView(RetrieveUpdateDestroyAPIView):
98     permission_classes = [IsAuthenticatedOrReadOnly]
99     lookup_field = 'uuid'
100
101     def get_serializer_class(self):
102         if self.request.version < 'v4':
103             return BookmarkSerializerV3
104         else:
105             return BookmarkSerializer
106     
107     def get_queryset(self):
108         if self.request.method in SAFE_METHODS:
109             q = Q(deleted=False)
110             if self.request.user.is_authenticated:
111                 q |= Q(user=self.request.user)
112             return models.Bookmark.objects.filter(q)
113         else:
114             return self.request.user.bookmark_set.all()
115
116     def perform_destroy(self, instance):
117         instance.deleted = True
118         instance.updated_at = now()
119         instance.save()