From 4ff58dfe52cf5af913cbc0b0e548f6516421af8c Mon Sep 17 00:00:00 2001
From: Valentin Rigal <rigal@teklia.com>
Date: Thu, 11 Apr 2019 09:32:56 +0000
Subject: [PATCH] Api transcriptions list

---
 arkindex/documents/api/elements.py            | 35 ++++++++++++++++++-
 arkindex/documents/tests/test_elements_api.py | 20 ++++++++++-
 arkindex/project/api_v1.py                    |  6 ++--
 3 files changed, 57 insertions(+), 4 deletions(-)

diff --git a/arkindex/documents/api/elements.py b/arkindex/documents/api/elements.py
index 965ab18b9d..72feeed841 100644
--- a/arkindex/documents/api/elements.py
+++ b/arkindex/documents/api/elements.py
@@ -1,12 +1,18 @@
 from rest_framework.generics import \
     ListAPIView, ListCreateAPIView, RetrieveAPIView, RetrieveUpdateAPIView, RetrieveUpdateDestroyAPIView
+from arkindex.project.pagination import PageNumberPagination
+from rest_framework.exceptions import ValidationError
 from django.db.models import prefetch_related_objects
 from arkindex.documents.serializers.light import PageLightSerializer
 from arkindex.documents.serializers.elements import (
     ElementSerializer, ElementLightSerializer, CorpusSerializer,
     PageSerializer, ActSerializer, SurfaceSerializer,
 )
-from arkindex.documents.models import Element, ElementType, Page, Act, Corpus, Right
+from arkindex.documents.serializers.ml import TranscriptionSerializer
+from arkindex.documents.models import (
+    Element, ElementType, Page, Act, TranscriptionType, Transcription,
+    Corpus, Right,
+)
 from arkindex.project.mixins import CorpusACLMixin
 from arkindex.project.permissions import IsVerifiedOrReadOnly
 
@@ -177,3 +183,30 @@ class ActEdit(RetrieveAPIView):
         act.parent_elements = Element.objects.get_ascending_paths(act.id)
         act.child_elements = Element.objects.get_descending(act.id)
         return act
+
+
+class TranscriptionsPagination(PageNumberPagination):
+    page_size = 100
+
+
+class ElementTranscriptions(ListAPIView):
+    """
+    Get transcriptions corresponding to a specific element
+    Transcriptions can be filtered by type
+    """
+    serializer_class = TranscriptionSerializer
+    pagination_class = TranscriptionsPagination
+
+    def get_queryset(self):
+        queryset = Transcription.objects.filter(
+            element_id=self.kwargs['pk'],
+            element__corpus__in=Corpus.objects.readable(self.request.user),
+        ).prefetch_related('zone__image__server', 'source').order_by('id')
+        req_type = self.request.query_params.get('type')
+        if req_type:
+            try:
+                req_type = TranscriptionType(req_type)
+                queryset = queryset.filter(type=req_type)
+            except ValueError:
+                raise ValidationError({'type': 'Not a valid transcription type'})
+        return queryset
diff --git a/arkindex/documents/tests/test_elements_api.py b/arkindex/documents/tests/test_elements_api.py
index f17b2208e0..482c3d7509 100644
--- a/arkindex/documents/tests/test_elements_api.py
+++ b/arkindex/documents/tests/test_elements_api.py
@@ -1,6 +1,6 @@
 from django.urls import reverse
 from rest_framework import status
-from arkindex.documents.models import Element, ElementType
+from arkindex.documents.models import Element, ElementType, DataSource, TranscriptionType
 from arkindex.project.tests import FixtureAPITestCase
 
 
@@ -10,6 +10,8 @@ class TestElementsAPI(FixtureAPITestCase):
     def setUpTestData(cls):
         super().setUpTestData()
         cls.vol = Element.objects.get(name='Volume 1', type=ElementType.Volume, corpus=cls.corpus)
+        cls.page = Element.objects.filter(type=ElementType.Page, corpus=cls.corpus).first().page
+        cls.src = DataSource.objects.get(slug='test')
 
     def test_get_element(self):
         response = self.client.get(reverse('api:element-retrieve', kwargs={'pk': str(self.vol.id)}))
@@ -42,3 +44,19 @@ class TestElementsAPI(FixtureAPITestCase):
         self.assertEqual(response.json()['name'], 'Untitled (2)')
         self.vol.refresh_from_db()
         self.assertEqual(self.vol.name, 'Untitled (2)')
+
+    def test_get_transcriptions(self):
+        self.page.transcriptions.all().delete()
+        transcriptions = []
+        for i in range(10):
+            transcriptions.append(self.page.transcriptions.create(source_id=self.src.id, type=TranscriptionType.Word))
+        self.client.force_login(self.user)
+        response = self.client.get(reverse('api:element-transcriptions', kwargs={'pk': str(self.page.id)}))
+        self.assertEqual(response.status_code, status.HTTP_200_OK)
+        self.assertEqual(len(response.json()['results']), 10)
+        self.assertEqual(len(transcriptions), 10)
+        # Wrong transcription type
+        url = reverse('api:element-transcriptions', kwargs={'pk': str(self.page.id)})
+        url += '?type=potato'
+        response = self.client.get(url)
+        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
diff --git a/arkindex/project/api_v1.py b/arkindex/project/api_v1.py
index 5284c9f711..cf07fe9053 100644
--- a/arkindex/project/api_v1.py
+++ b/arkindex/project/api_v1.py
@@ -2,8 +2,9 @@ from django.urls import path
 from django.views.generic.base import RedirectView
 
 from arkindex.documents.api.elements import (
-     ElementsList, RelatedElementsList, ElementRetrieve, ElementPages, ElementSurfaces,
-     CorpusList, CorpusRetrieve, CorpusPages, ActEdit, PageDetails, SurfaceDetails,
+    ElementsList, RelatedElementsList, ElementRetrieve, ElementPages, ElementSurfaces,
+    CorpusList, CorpusRetrieve, CorpusPages, ActEdit, PageDetails, SurfaceDetails,
+    ElementTranscriptions,
 )
 from arkindex.documents.api.search import PageSearch, ActSearch
 from arkindex.documents.api.ml import ClassificationBulk, TranscriptionCreate, TranscriptionBulk
@@ -31,6 +32,7 @@ api = [
     path('elements/', ElementsList.as_view(), name='elements'),
     path('element/<uuid:pk>/', ElementRetrieve.as_view(), name='element-retrieve'),
     path('element/<uuid:pk>/history/', ElementHistory.as_view(), name='element-history'),
+    path('element/<uuid:pk>/transcriptions/', ElementTranscriptions.as_view(), name='element-transcriptions'),
     path('page/<uuid:pk>/', PageDetails.as_view(), name='page-details'),
     path('surface/<uuid:pk>/', SurfaceDetails.as_view(), name='surface-details'),
     path('corpus/', CorpusList.as_view(), name='corpus'),
-- 
GitLab