+@never_cache
+class LikeView2(APIView):
+ permission_classes = [IsAuthenticated]
+
+ def get(self, request, slug):
+ book = get_object_or_404(Book, slug=slug)
+ return Response({"likes": likes(request.user, book)})
+
+ def put(self, request, slug):
+ book = get_object_or_404(Book, slug=slug)
+ models.UserList.like(request.user, book)
+ return Response({"likes": likes(request.user, book)})
+
+ def delete(self, request, slug):
+ book = get_object_or_404(Book, slug=slug)
+ models.UserList.unlike(request.user, book)
+ return Response({"likes": likes(request.user, book)})
+
+
+@never_cache
+class LikesView(APIView):
+ permission_classes = [IsAuthenticated]
+
+ def get(self, request):
+ slugs = request.GET.getlist('slug')
+ books = Book.objects.filter(slug__in=slugs)
+ books = {b.id: b.slug for b in books}
+ ids = books.keys()
+ res = get_sets_for_book_ids(ids, request.user)
+ res = {books[bid]: v for bid, v in res.items()}
+
+ return Response(res)
+
+
+@never_cache
+class MyLikesView(APIView):
+ permission_classes = [IsAuthenticated]
+
+ def get(self, request):
+ ul = models.UserList.get_favorites_list(request.user)
+ if ul is None:
+ return Response([])
+ return Response(
+ ul.userlistitem_set.exclude(deleted=True).exclude(book=None).values_list('book__slug', flat=True)
+ )
+
+
+class UserListItemsField(serializers.Field):
+ def to_representation(self, value):
+ return value.userlistitem_set.exclude(deleted=True).exclude(book=None).values_list('book__slug', flat=True)
+
+ def to_internal_value(self, value):
+ return {'books': catalogue.models.Book.objects.filter(slug__in=value)}
+
+
+class UserListSerializer(serializers.ModelSerializer):
+ client_id = serializers.CharField(write_only=True, required=False)
+ books = UserListItemsField(source='*', required=False)
+ timestamp = serializers.IntegerField(required=False)
+
+ class Meta:
+ model = models.UserList
+ fields = [
+ 'timestamp',
+ 'client_id',
+ 'name',
+ 'slug',
+ 'favorites',
+ 'deleted',
+ 'books',
+ ]
+ read_only_fields = ['favorites']
+ extra_kwargs = {
+ 'slug': {
+ 'required': False
+ }
+ }
+
+ def create(self, validated_data):
+ instance = models.UserList.get_by_name(
+ validated_data['user'],
+ validated_data['name'],
+ create=True
+ )
+ instance.userlistitem_set.all().delete()
+ for book in validated_data['books']:
+ instance.append(book)
+ return instance
+
+ def update(self, instance, validated_data):
+ instance.userlistitem_set.all().delete()
+ for book in validated_data['books']:
+ instance.append(instance)
+ return instance
+
+class UserListBooksSerializer(UserListSerializer):
+ class Meta:
+ model = models.UserList
+ fields = ['books']
+
+
+class UserListItemSerializer(serializers.ModelSerializer):
+ client_id = serializers.CharField(write_only=True, required=False)
+ favorites = serializers.BooleanField(required=False)
+ list_slug = serializers.SlugRelatedField(
+ queryset=models.UserList.objects.all(),
+ source='list',
+ slug_field='slug',
+ required=False,
+ )
+ timestamp = serializers.IntegerField(required=False)
+ book_slug = serializers.SlugRelatedField(
+ queryset=Book.objects.all(),
+ source='book',
+ slug_field='slug',
+ required=False
+ )
+
+ class Meta:
+ model = models.UserListItem
+ fields = [
+ 'client_id',
+ 'uuid',
+ 'order',
+ 'list_slug',
+ 'timestamp',
+ 'favorites',
+ 'deleted',
+
+ 'book_slug',
+ 'fragment',
+ 'quote',
+ 'bookmark',
+ 'note',
+ ]
+ extra_kwargs = {
+ 'order': {
+ 'required': False
+ }
+ }
+
+
+@never_cache
+class ListsView(ListCreateAPIView):
+ permission_classes = [IsAuthenticated]
+ #pagination_class = None
+ serializer_class = UserListSerializer
+
+ def get_queryset(self):
+ return models.UserList.objects.filter(
+ user=self.request.user,
+ favorites=False,
+ deleted=False
+ )
+
+ def perform_create(self, serializer):
+ serializer.save(user=self.request.user)
+
+
+@never_cache
+class ListView(RetrieveUpdateDestroyAPIView):
+ # TODO: check if can modify
+ permission_classes = [IsAuthenticatedOrReadOnly]
+ serializer_class = UserListSerializer
+
+ def get_object(self):
+ if self.request.method in SAFE_METHODS:
+ q = Q(deleted=False)
+ if self.request.user.is_authenticated:
+ q |= Q(user=self.request.user)
+ return get_object_or_404(
+ models.UserList,
+ q,
+ slug=self.kwargs['slug'],
+ )
+ else:
+ return get_object_or_404(
+ models.UserList,
+ slug=self.kwargs['slug'],
+ user=self.request.user)
+
+ def perform_update(self, serializer):
+ serializer.save(user=self.request.user)
+
+ def post(self, request, slug):
+ serializer = UserListBooksSerializer(data=request.data)
+ serializer.is_valid(raise_exception=True)
+ instance = self.get_object()
+ for book in serializer.validated_data['books']:
+ instance.append(book)
+ return Response(self.get_serializer(instance).data)
+
+ def perform_destroy(self, instance):
+ instance.deleted = True
+ instance.updated_at = now()
+ instance.save()
+
+
+@never_cache
+class ListItemView(APIView):
+ permission_classes = [IsAuthenticated]
+
+ def delete(self, request, slug, book):
+ instance = get_object_or_404(
+ models.UserList, slug=slug, user=self.request.user)
+ book = get_object_or_404(catalogue.models.Book, slug=book)
+ instance.remove(book=book)
+ return Response(UserListSerializer(instance).data)
+
+