wip
[wolnelektury.git] / src / catalogue / api / views.py
index 5afec17..b2734d9 100644 (file)
@@ -6,10 +6,11 @@ import os.path
 from urllib.request import urlopen
 from django.conf import settings
 from django.core.files.base import ContentFile
-from django.http import Http404, HttpResponse
+from django.http import Http404, HttpResponse, JsonResponse
 from django.utils.decorators import method_decorator
 from django.views.decorators.cache import never_cache
-from django_filters import rest_framework as filters
+from django_filters import rest_framework as dfilters
+from rest_framework import filters
 from rest_framework.generics import (ListAPIView, RetrieveAPIView,
                                      RetrieveUpdateAPIView, get_object_or_404)
 from rest_framework.permissions import DjangoModelPermissionsOrAnonReadOnly
@@ -18,6 +19,7 @@ from rest_framework import status
 from api.handlers import read_tags
 from api.utils import vary_on_auth
 from catalogue.forms import BookImportForm
+from catalogue.helpers import get_top_level_related_tags
 from catalogue.models import Book, Collection, Tag, Fragment, BookMedia
 from catalogue.models.tag import prefetch_relations
 from club.models import Membership
@@ -184,26 +186,37 @@ class BookList(LegacyListAPIView):
         return Response({}, status=status.HTTP_201_CREATED)
 
 
-class BookFilter(filters.FilterSet):
-    sort = filters.OrderingFilter(
+class BookFilter(dfilters.FilterSet):
+    sort = dfilters.OrderingFilter(
         fields=(
             ('sort_key_author', 'alpha'),
             ('popularity', 'popularity'),
         )
     )
-    tag = filters.ModelMultipleChoiceFilter(
+    tag = dfilters.ModelMultipleChoiceFilter(
         field_name='tag_relations__tag',
         queryset=Tag.objects.filter(category__in=('author', 'epoch', 'genre', 'kind')),
         conjoined=True,
     )
+    translator = dfilters.ModelMultipleChoiceFilter(
+        field_name='translators',
+        queryset=Tag.objects.filter(category='author'),
+        conjoined=True,
+    )
 
 
 class BookList2(ListAPIView):
     permission_classes = [DjangoModelPermissionsOrAnonReadOnly]
     queryset = Book.objects.none()  # Required for DjangoModelPermissions
     serializer_class = serializers.BookSerializer2
-    filter_backends = (filters.DjangoFilterBackend,)
+    filter_backends = (
+        dfilters.DjangoFilterBackend,
+        filters.SearchFilter,
+    )
     filterset_class = BookFilter
+    search_fields = [
+        'title',
+    ]
 
     def get_queryset(self):
         books = Book.objects.all()
@@ -486,3 +499,44 @@ class FragmentView(RetrieveAPIView):
             book__slug=self.kwargs['book'],
             anchor=self.kwargs['anchor']
         )
+
+
+class SuggestedTags(ListAPIView):
+    serializer_class = serializers.FilterTagSerializer
+
+    def get_queryset(self):
+        tag_ids = self.request.GET.getlist('tag', [])
+        search = self.request.GET.get('search')
+        tags = [get_object_or_404(Tag, id=tid) for tid in tag_ids]
+        related_tags = list(t.id for t in get_top_level_related_tags(tags))
+        tags = Tag.objects.filter(id__in=related_tags)
+        if search:
+            tags = tags.filter(name__icontains=search)
+        return tags
+
+
+class BookFragmentView(RetrieveAPIView):
+    serializer_class = serializers.FragmentSerializer2
+
+    def get_object(self):
+        book = get_object_or_404(Book, slug=self.kwargs['slug'])
+        return book.choose_fragment()
+
+
+class BookMediaView(ListAPIView):
+    serializer_class = serializers.MediaSerializer2
+    pagination_class = None
+
+    def get_queryset(self):
+        return BookMedia.objects.filter(book__slug=self.kwargs['slug'], type=self.kwargs['type']).order_by('index')
+
+
+from .tojson import conv
+from lxml import etree
+from rest_framework.views import APIView
+class BookJsonView(APIView):
+    def get(self, request, slug):
+        book = get_object_or_404(Book, slug=slug)
+        js = conv(etree.parse(book.xml_file.path))
+        return JsonResponse(js, json_dumps_params={'ensure_ascii': False})
+