from django_filters.rest_framework import DjangoFilterBackend from rest_framework import status, viewsets from rest_framework.decorators import action from rest_framework.filters import OrderingFilter, SearchFilter from rest_framework.permissions import IsAuthenticated from rest_framework.response import Response from apps.annotations.models import Bookmark, Note from apps.annotations.permissions import IsOwner from apps.annotations.serializers import ( BookmarkCreateSerializer, BookmarkSerializer, NoteCreateSerializer, NoteSerializer, ) class BookmarkViewSet(viewsets.ModelViewSet): """CRUD for user ebook markers (passage anchors + optional thoughts).""" permission_classes = [IsAuthenticated, IsOwner] filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter] filterset_fields = ["ebook"] search_fields = ["location_text", "content", "chapter_title"] ordering_fields = ["chapter_index", "epub_cfi", "created_at"] ordering = ["chapter_index", "epub_cfi"] def get_serializer_class(self): if self.action == "create": return BookmarkCreateSerializer return BookmarkSerializer def get_queryset(self): return Bookmark.objects.filter(user=self.request.user).select_related("ebook") def perform_create(self, serializer): serializer.save(user=self.request.user) @action(detail=False, methods=["delete"], url_path="batch-delete") def batch_delete(self, request): ids = request.data.get("ids", []) if not ids: return Response( {"detail": "No ids provided."}, status=status.HTTP_400_BAD_REQUEST ) deleted, _ = Bookmark.objects.filter( id__in=ids, user=request.user ).delete() return Response({"deleted": deleted}, status=status.HTTP_200_OK) class NoteViewSet(viewsets.ModelViewSet): """Legacy notes API (catalog Book FK).""" permission_classes = [IsAuthenticated, IsOwner] filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter] filterset_fields = ["book"] search_fields = ["content", "location_text"] ordering_fields = ["created_at", "page"] ordering = ["-created_at"] def get_serializer_class(self): if self.action == "create": return NoteCreateSerializer return NoteSerializer def get_queryset(self): return Note.objects.filter(user=self.request.user).select_related("book") def perform_create(self, serializer): serializer.save(user=self.request.user) @action(detail=False, methods=["delete"], url_path="batch-delete") def batch_delete(self, request): ids = request.data.get("ids", []) if not ids: return Response( {"detail": "No ids provided."}, status=status.HTTP_400_BAD_REQUEST ) deleted, _ = Note.objects.filter( id__in=ids, user=request.user ).delete() return Response({"deleted": deleted}, status=status.HTTP_200_OK)