diff --git a/arkindex/documents/api.py b/arkindex/documents/api.py index 1220edd60a53866d93613247cd8e1aec130d7308..b562625e6fd2dcb0f2aa419f93f4af787607e433 100644 --- a/arkindex/documents/api.py +++ b/arkindex/documents/api.py @@ -1,7 +1,7 @@ from rest_framework.generics import \ ListAPIView, RetrieveAPIView, CreateAPIView from rest_framework.permissions import IsAuthenticated -from rest_framework.exceptions import APIException +from rest_framework.exceptions import ValidationError from rest_framework.response import Response from rest_framework import status from django.conf import settings @@ -167,7 +167,7 @@ class TranscriptionCreate(CreateAPIView): ElementType.Line, ElementType.Word, ElementType.Character): - raise APIException(detail="This endpoint can only import transcriptions.") + raise ValidationError("This endpoint can only import transcriptions.") element = serializer.validated_data['element'] # Create a zone on the page's image @@ -217,7 +217,15 @@ class TranscriptionCreate(CreateAPIView): return Response({'id': obj.id}, status=status.HTTP_201_CREATED, headers=headers) -class TranscriptionSearch(ListAPIView): +class SearchAPIMixin(object): + def get(self, request, *args, **kwargs): + q = request.query_params.get('q') + if not q or q.isspace(): + raise ValidationError('A search query is required') + return super().get(request, *args, **kwargs) + + +class TranscriptionSearch(SearchAPIMixin, ListAPIView): """ Search and list transcriptions, using pagination """ @@ -225,6 +233,8 @@ class TranscriptionSearch(ListAPIView): def get_queryset(self): query = self.request.query_params.get('q') + if not query: + return corpus = self.request.query_params.get('corpus') type = self.request.query_params.get('type') return ESQuerySet( @@ -239,7 +249,7 @@ class TranscriptionSearch(ListAPIView): ) -class ActSearch(ListAPIView): +class ActSearch(SearchAPIMixin, ListAPIView): """ Search for acts containing a specific word """ @@ -247,6 +257,8 @@ class ActSearch(ListAPIView): def get_queryset(self): query = self.request.query_params.get('q') + if not query: + return corpus = self.request.query_params.get('corpus') type = self.request.query_params.get('type') return ESQuerySet( diff --git a/arkindex/documents/managers.py b/arkindex/documents/managers.py index 4c45b8c10e31d1b219b4d95d8d230d9f2a9d2725..a2e448bd477925ccf668b28c0713e2d4baafbbe5 100644 --- a/arkindex/documents/managers.py +++ b/arkindex/documents/managers.py @@ -18,10 +18,10 @@ class ElementManager(models.Manager): for parent in self.filter(id__in=chain(*paths)) } return [ - [ - parents[parent_id] + filter(None, [ + parents.get(parent_id) for parent_id in path - ] + ]) for path in paths ] diff --git a/arkindex/documents/serializers.py b/arkindex/documents/serializers.py index 4bbe15d134062cbec879ad5412ff00a9103ae766..d4149b3627f93f21fd498a45a5296c19eaefe3b9 100644 --- a/arkindex/documents/serializers.py +++ b/arkindex/documents/serializers.py @@ -344,7 +344,8 @@ class ActPageCanvasManifestSerializer(PageCanvasManifestSerializer): "@type": "sc:AnnotationList", "label": surface.name } - for surface in Element.objects.get_descending(page.act.id).filter( + for surface in Element.objects.get_descending( + page.act.id, type=ElementType.Surface, zone__image_id=page.zone.image_id ) @@ -445,16 +446,18 @@ class ActManifestSerializer(ManifestSerializer): def get_canvases(self, act): assert isinstance(act, Act) - image_ids = Element.objects \ - .get_descending(act.id) \ - .filter(type=ElementType.Surface) \ - .values_list('zone__image_id', flat=True) + image_ids = list(Element.objects + .get_descending(act.id, type=ElementType.Surface) + .values_list('zone__image_id', flat=True)) pages = Page.objects \ .filter(zone__image_id__in=image_ids) \ - .select_related('zone__image') - for p in pages: + .select_related('zone__image__server') + # This query gives unordered pages so we reorder them manually + ordered_pages = sorted(pages, key=lambda p: image_ids.index(p.zone.image_id)) + # Add act info for canvas serializer + for p in ordered_pages: p.act = act - return pages + return ordered_pages class AnnotationSerializer(ABC, serializers.BaseSerializer): diff --git a/arkindex/documents/tests/test_element_manager.py b/arkindex/documents/tests/test_element_manager.py index 8fb615c19a1be1b74f6a6feffc5145d32c6211c1..534d6854fb7e719e1a5ebe25a291a8bbf7024e58 100644 --- a/arkindex/documents/tests/test_element_manager.py +++ b/arkindex/documents/tests/test_element_manager.py @@ -63,4 +63,5 @@ class TestElementManager(TestCase): def test_get_ascending_paths(self): paths = Element.objects.get_ascending_paths(self.act.id) - self.assertCountEqual(paths, [[self.reg, self.vol, self.p1]]) + self.assertEqual(len(paths), 1) + self.assertSequenceEqual(list(paths[0]), [self.reg, self.vol, self.p1]) diff --git a/arkindex/documents/tests/test_transcription_create.py b/arkindex/documents/tests/test_transcription_create.py index 1e06d0707a818dd8f92da0d920fe86e4111abfd2..602fff86f0986e80d1e42995c5b88ad5a0b7b93b 100644 --- a/arkindex/documents/tests/test_transcription_create.py +++ b/arkindex/documents/tests/test_transcription_create.py @@ -72,7 +72,7 @@ class TestTranscriptionCreate(APITestCase): "text": "NEKUDOTAYIM", "score": 0.83, }) - self.assertEqual(response.status_code, status.HTTP_500_INTERNAL_SERVER_ERROR) + self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) def test_unique_zone(self): """