Refactor the parsing app API
Add additional API and view tests. Add success and multi document titles strings. Make use of external mixin in the document type submit view. Puntuate all view text strings. Signed-off-by: Roberto Rosario <Roberto.Rosario@mayan-edms.com>
This commit is contained in:
@@ -2,47 +2,104 @@ from __future__ import absolute_import, unicode_literals
|
||||
|
||||
from django.shortcuts import get_object_or_404
|
||||
|
||||
from rest_framework import generics
|
||||
from rest_framework import status
|
||||
from rest_framework.decorators import action
|
||||
from rest_framework.response import Response
|
||||
|
||||
from mayan.apps.documents.models import Document
|
||||
from mayan.apps.rest_api.permissions import MayanPermission
|
||||
from mayan.apps.documents.models import Document, DocumentVersion
|
||||
from mayan.apps.rest_api.viewsets import MayanAPIViewSet, MayanAPIGenericViewSet
|
||||
|
||||
from .models import DocumentPageContent
|
||||
from .permissions import permission_content_view
|
||||
from .serializers import DocumentPageContentSerializer
|
||||
from .permissions import permission_content_view, permission_parse_document
|
||||
from .serializers import (
|
||||
DocumentParsingSerializer, DocumentPageParsingSerializer,
|
||||
DocumentVersionParsingSerializer
|
||||
)
|
||||
|
||||
|
||||
class APIDocumentPageContentView(generics.RetrieveAPIView):
|
||||
"""
|
||||
Returns the content of the selected document page.
|
||||
"""
|
||||
lookup_url_kwarg = 'document_page_id'
|
||||
mayan_object_permissions = {
|
||||
'GET': (permission_content_view,),
|
||||
class DocumentParsingAPIViewSet(MayanAPIGenericViewSet):
|
||||
lookup_url_kwarg = 'document_id'
|
||||
object_permission_map = {
|
||||
'parsing_content': permission_content_view,
|
||||
'parsing_submit': permission_parse_document,
|
||||
}
|
||||
permission_classes = (MayanPermission,)
|
||||
serializer_class = DocumentPageContentSerializer
|
||||
queryset = Document.objects.all()
|
||||
serializer_class = DocumentParsingSerializer
|
||||
|
||||
def get_document(self):
|
||||
return get_object_or_404(klass=Document, pk=self.kwargs['document_id'])
|
||||
|
||||
def get_document_version(self):
|
||||
return get_object_or_404(
|
||||
klass=self.get_document().versions.all(),
|
||||
pk=self.kwargs['document_version_id']
|
||||
@action(
|
||||
detail=True, url_name='content', url_path='parsing'
|
||||
)
|
||||
def parsing_content(self, request, *args, **kwargs):
|
||||
instance = self.get_object()
|
||||
serializer = self.get_serializer(instance)
|
||||
headers = self.get_success_headers(data=serializer.data)
|
||||
return Response(
|
||||
serializer.data, status=status.HTTP_200_OK, headers=headers
|
||||
)
|
||||
|
||||
def get_queryset(self):
|
||||
return self.get_document_version().pages.all()
|
||||
|
||||
def retrieve(self, request, *args, **kwargs):
|
||||
@action(
|
||||
detail=True, methods=('post',), url_name='submit',
|
||||
url_path='parsing/submit'
|
||||
)
|
||||
def parsing_submit(self, request, *args, **kwargs):
|
||||
instance = self.get_object()
|
||||
instance.submit_for_parsing(_user=request.user)
|
||||
return Response(
|
||||
data=None, status=status.HTTP_202_ACCEPTED
|
||||
)
|
||||
|
||||
try:
|
||||
content = instance.content
|
||||
except DocumentPageContent.DoesNotExist:
|
||||
content = DocumentPageContent.objects.none()
|
||||
|
||||
serializer = self.get_serializer(content)
|
||||
return Response(serializer.data)
|
||||
class DocumentVersionParsingAPIViewSet(MayanAPIViewSet):
|
||||
lookup_url_kwarg = 'document_version_id'
|
||||
object_permission_map = {
|
||||
'parsing_content': permission_content_view,
|
||||
'parsing_submit': permission_parse_document,
|
||||
}
|
||||
queryset = DocumentVersion.objects.all()
|
||||
serializer_class = DocumentVersionParsingSerializer
|
||||
|
||||
@action(
|
||||
detail=True, url_name='content', url_path='parsing'
|
||||
)
|
||||
def parsing_content(self, request, *args, **kwargs):
|
||||
instance = self.get_object()
|
||||
serializer = self.get_serializer(instance)
|
||||
headers = self.get_success_headers(data=serializer.data)
|
||||
return Response(
|
||||
serializer.data, status=status.HTTP_200_OK, headers=headers
|
||||
)
|
||||
|
||||
@action(
|
||||
detail=True, methods=('post',), url_name='submit',
|
||||
url_path='parsing/submit'
|
||||
)
|
||||
def parsing_submit(self, request, *args, **kwargs):
|
||||
instance = self.get_object()
|
||||
instance.submit_for_parsing(_user=request.user)
|
||||
return Response(
|
||||
data=None, status=status.HTTP_202_ACCEPTED
|
||||
)
|
||||
|
||||
|
||||
class DocumentPageParsingAPIViewSet(MayanAPIGenericViewSet):
|
||||
lookup_url_kwarg = 'document_page_id'
|
||||
object_permission_map = {
|
||||
'parsing_content': permission_content_view,
|
||||
}
|
||||
serializer_class = DocumentPageParsingSerializer
|
||||
|
||||
def get_queryset(self):
|
||||
return get_object_or_404(
|
||||
klass=DocumentVersion, document_id=self.kwargs['document_id'],
|
||||
pk=self.kwargs['document_version_id']
|
||||
).pages.all()
|
||||
|
||||
@action(
|
||||
detail=True, url_name='content', url_path='parsing'
|
||||
)
|
||||
def parsing_content(self, request, *args, **kwargs):
|
||||
instance = self.get_object()
|
||||
serializer = self.get_serializer(instance)
|
||||
headers = self.get_success_headers(data=serializer.data)
|
||||
return Response(
|
||||
serializer.data, status=status.HTTP_200_OK, headers=headers
|
||||
)
|
||||
|
||||
@@ -17,6 +17,8 @@ from mayan.apps.common.classes import ModelAttribute, ModelField
|
||||
from mayan.apps.documents.search import document_page_search, document_search
|
||||
from mayan.apps.documents.signals import post_version_upload
|
||||
from mayan.apps.navigation import SourceColumn
|
||||
from mayan.apps.rest_api.fields import HyperlinkField
|
||||
from mayan.apps.rest_api.serializers import LazyExtraFieldsSerializerMixin
|
||||
from mayan.celery import app
|
||||
|
||||
from .handlers import (
|
||||
@@ -31,9 +33,9 @@ from .links import (
|
||||
link_error_list
|
||||
)
|
||||
from .methods import (
|
||||
method_document_submit_for_parsing,
|
||||
method_document_version_submit_for_parsing,
|
||||
method_get_document_content, method_get_document_version_content
|
||||
method_document_get_content, method_document_page_get_content,
|
||||
method_document_submit_for_parsing, method_document_version_get_content,
|
||||
method_document_version_submit_for_parsing
|
||||
)
|
||||
from .permissions import (
|
||||
permission_content_view, permission_document_type_parsing_setup,
|
||||
@@ -79,16 +81,95 @@ class DocumentParsingApp(MayanAppConfig):
|
||||
value=method_document_submit_for_parsing
|
||||
)
|
||||
Document.add_to_class(
|
||||
name='get_content', value=method_get_document_content
|
||||
name='get_content', value=method_document_get_content
|
||||
)
|
||||
DocumentPage.add_to_class(
|
||||
name='get_content', value=method_document_page_get_content
|
||||
)
|
||||
DocumentVersion.add_to_class(
|
||||
name='get_content', value=method_get_document_version_content
|
||||
name='get_content', value=method_document_version_get_content
|
||||
)
|
||||
DocumentVersion.add_to_class(
|
||||
name='submit_for_parsing',
|
||||
value=method_document_version_submit_for_parsing
|
||||
)
|
||||
|
||||
LazyExtraFieldsSerializerMixin.add_field(
|
||||
dotted_path='mayan.apps.documents.serializers.DocumentPageSerializer',
|
||||
field_name='parsing_content_url',
|
||||
field=HyperlinkField(
|
||||
view_kwargs=(
|
||||
{
|
||||
'lookup_field': 'document_version__document_id',
|
||||
'lookup_url_kwarg': 'document_id',
|
||||
},
|
||||
{
|
||||
'lookup_field': 'document_version_id',
|
||||
'lookup_url_kwarg': 'document_version_id',
|
||||
},
|
||||
{
|
||||
'lookup_field': 'pk',
|
||||
'lookup_url_kwarg': 'document_page_id',
|
||||
}
|
||||
),
|
||||
view_name='rest_api:document_page-parsing-content'
|
||||
)
|
||||
)
|
||||
|
||||
LazyExtraFieldsSerializerMixin.add_field(
|
||||
dotted_path='mayan.apps.documents.serializers.DocumentSerializer',
|
||||
field_name='parsing_content_url',
|
||||
field=HyperlinkField(
|
||||
lookup_url_kwarg='document_id',
|
||||
view_name='rest_api:document-parsing-content'
|
||||
)
|
||||
)
|
||||
|
||||
LazyExtraFieldsSerializerMixin.add_field(
|
||||
dotted_path='mayan.apps.documents.serializers.DocumentSerializer',
|
||||
field_name='parsing_submit_url',
|
||||
field=HyperlinkField(
|
||||
lookup_url_kwarg='document_id',
|
||||
view_name='rest_api:document-parsing-submit'
|
||||
)
|
||||
)
|
||||
|
||||
LazyExtraFieldsSerializerMixin.add_field(
|
||||
dotted_path='mayan.apps.documents.serializers.DocumentVersionSerializer',
|
||||
field_name='parsing_submit_url',
|
||||
field=HyperlinkField(
|
||||
view_kwargs=(
|
||||
{
|
||||
'lookup_field': 'document_id',
|
||||
'lookup_url_kwarg': 'document_id',
|
||||
},
|
||||
{
|
||||
'lookup_field': 'pk',
|
||||
'lookup_url_kwarg': 'document_version_id',
|
||||
}
|
||||
),
|
||||
view_name='rest_api:document_version-parsing-submit'
|
||||
)
|
||||
)
|
||||
|
||||
LazyExtraFieldsSerializerMixin.add_field(
|
||||
dotted_path='mayan.apps.documents.serializers.DocumentVersionSerializer',
|
||||
field_name='parsing_content_url',
|
||||
field=HyperlinkField(
|
||||
view_kwargs=(
|
||||
{
|
||||
'lookup_field': 'document_id',
|
||||
'lookup_url_kwarg': 'document_id',
|
||||
},
|
||||
{
|
||||
'lookup_field': 'pk',
|
||||
'lookup_url_kwarg': 'document_version_id',
|
||||
}
|
||||
),
|
||||
view_name='rest_api:document_version-parsing-content'
|
||||
)
|
||||
)
|
||||
|
||||
ModelAttribute(model=Document, name='get_content')
|
||||
|
||||
ModelField(
|
||||
|
||||
@@ -2,6 +2,7 @@ from __future__ import unicode_literals
|
||||
|
||||
from datetime import timedelta
|
||||
|
||||
from django.apps import apps
|
||||
from django.utils.timezone import now
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
@@ -9,48 +10,62 @@ from mayan.apps.common.settings import settings_db_sync_task_delay
|
||||
|
||||
from .events import event_parsing_document_version_submit
|
||||
from .tasks import task_parse_document_version
|
||||
from .utils import get_document_version_content_iterator
|
||||
|
||||
|
||||
def method_document_submit_for_parsing(self):
|
||||
latest_version = self.latest_version
|
||||
# Don't error out if document has no version
|
||||
if latest_version:
|
||||
latest_version.submit_for_parsing()
|
||||
|
||||
|
||||
def method_document_version_submit_for_parsing(self):
|
||||
event_parsing_document_version_submit.commit(
|
||||
action_object=self.document, target=self
|
||||
)
|
||||
|
||||
task_parse_document_version.apply_async(
|
||||
eta=now() + timedelta(seconds=settings_db_sync_task_delay.value),
|
||||
kwargs={'document_version_pk': self.pk},
|
||||
)
|
||||
|
||||
|
||||
def method_get_document_content(self):
|
||||
def method_document_get_content(self):
|
||||
latest_version = self.latest_version
|
||||
|
||||
if latest_version:
|
||||
return latest_version.get_content()
|
||||
|
||||
|
||||
method_get_document_content.help_text = _(
|
||||
method_document_get_content.help_text = _(
|
||||
'Return the parsed content of the document.'
|
||||
)
|
||||
method_get_document_content.short_description = _(
|
||||
method_document_get_content.short_description = _(
|
||||
'get_content()'
|
||||
)
|
||||
|
||||
|
||||
def method_get_document_version_content(self):
|
||||
return ' '.join(
|
||||
get_document_version_content_iterator(document_version=self)
|
||||
def method_document_page_get_content(self):
|
||||
DocumentPageContent = apps.get_model(
|
||||
app_label='document_parsing', model_name='DocumentPageContent'
|
||||
)
|
||||
|
||||
try:
|
||||
page_content = self.content.content
|
||||
except DocumentPageContent.DoesNotExist:
|
||||
return ''
|
||||
else:
|
||||
return page_content
|
||||
|
||||
method_get_document_version_content.help_text = _(
|
||||
|
||||
def method_document_submit_for_parsing(self, _user=None):
|
||||
latest_version = self.latest_version
|
||||
# Don't error out if document has no version
|
||||
if latest_version:
|
||||
latest_version.submit_for_parsing(_user=_user)
|
||||
|
||||
|
||||
def method_document_version_get_content(self):
|
||||
result = []
|
||||
for page in self.pages.all():
|
||||
result.append(page.get_content())
|
||||
|
||||
return ''.join(result)
|
||||
|
||||
|
||||
method_document_version_get_content.help_text = _(
|
||||
'Return the parsed content of the document version.'
|
||||
)
|
||||
|
||||
|
||||
def method_document_version_submit_for_parsing(self, _user=None):
|
||||
event_parsing_document_version_submit.commit(
|
||||
action_object=self.document, actor=_user, target=self
|
||||
)
|
||||
|
||||
task_parse_document_version.apply_async(
|
||||
eta=now() + timedelta(seconds=settings_db_sync_task_delay.value),
|
||||
kwargs={'document_version_pk': self.pk},
|
||||
)
|
||||
|
||||
@@ -2,10 +2,20 @@ from __future__ import unicode_literals
|
||||
|
||||
from rest_framework import serializers
|
||||
|
||||
from .models import DocumentPageContent
|
||||
|
||||
class DocumentPageParsingSerializer(serializers.Serializer):
|
||||
text = serializers.CharField(
|
||||
read_only=True, source='get_content'
|
||||
)
|
||||
|
||||
|
||||
class DocumentPageContentSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
fields = ('content',)
|
||||
model = DocumentPageContent
|
||||
class DocumentParsingSerializer(serializers.Serializer):
|
||||
text = serializers.CharField(
|
||||
read_only=True, source='get_content'
|
||||
)
|
||||
|
||||
|
||||
class DocumentVersionParsingSerializer(serializers.Serializer):
|
||||
text = serializers.CharField(
|
||||
read_only=True, source='get_content'
|
||||
)
|
||||
|
||||
@@ -7,35 +7,134 @@ from rest_framework import status
|
||||
from mayan.apps.documents.tests import TEST_HYBRID_DOCUMENT, DocumentTestMixin
|
||||
from mayan.apps.rest_api.tests import BaseAPITestCase
|
||||
|
||||
from ..permissions import permission_content_view
|
||||
from ..permissions import permission_content_view, permission_parse_document
|
||||
|
||||
TEST_DOCUMENT_CONTENT = 'Sample text'
|
||||
from .literals import TEST_DOCUMENT_CONTENT
|
||||
|
||||
|
||||
@override_settings(DOCUMENT_PARSING_AUTO_PARSING=True)
|
||||
class DocumentParsingAPITestCase(DocumentTestMixin, BaseAPITestCase):
|
||||
test_document_filename = TEST_HYBRID_DOCUMENT
|
||||
class DocumentParsingSubmitAPITestCase(DocumentTestMixin, BaseAPITestCase):
|
||||
def _request_document_parsing_submit_view(self):
|
||||
return self.post(
|
||||
viewname='rest_api:document-parsing-submit',
|
||||
kwargs={'document_id': self.document.pk}
|
||||
)
|
||||
|
||||
def _request_document_page_content_view(self):
|
||||
return self.get(
|
||||
viewname='rest_api:document-page-content-view',
|
||||
kargs={
|
||||
def test_submit_document_no_permission(self):
|
||||
response = self._request_document_parsing_submit_view()
|
||||
self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
|
||||
|
||||
self.assertFalse(hasattr(self.document.pages.first(), 'content'))
|
||||
|
||||
#TODO: mock OCR here
|
||||
def test_submit_document_with_access(self):
|
||||
self.grant_access(
|
||||
obj=self.document, permission=permission_parse_document
|
||||
)
|
||||
response = self._request_document_parsing_submit_view()
|
||||
self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED)
|
||||
|
||||
self.assertTrue(hasattr(self.document.pages.first(), 'content'))
|
||||
|
||||
def _request_document_version_parsing_submit_view(self):
|
||||
return self.post(
|
||||
viewname='rest_api:document_version-parsing-submit',
|
||||
kwargs={
|
||||
'document_id': self.document.pk,
|
||||
'version_id': self.document.latest_version.pk,
|
||||
'page_id': self.document.latest_version.pages.first().pk
|
||||
'document_version_id': self.document.latest_version.pk
|
||||
}
|
||||
)
|
||||
|
||||
def test_get_document_version_page_content_no_access(self):
|
||||
response = self._request_document_page_content_view()
|
||||
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
|
||||
def test_submit_document_version_no_permission(self):
|
||||
response = self._request_document_version_parsing_submit_view()
|
||||
self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
|
||||
|
||||
def test_get_document_version_page_content_with_access(self):
|
||||
self.assertFalse(hasattr(self.document.pages.first(), 'content'))
|
||||
|
||||
def test_submit_document_version_with_access(self):
|
||||
self.grant_access(
|
||||
permission=permission_content_view, obj=self.document
|
||||
obj=self.document, permission=permission_parse_document
|
||||
)
|
||||
response = self._request_document_version_parsing_submit_view()
|
||||
self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED)
|
||||
|
||||
self.assertTrue(hasattr(self.document.pages.first(), 'content'))
|
||||
|
||||
|
||||
@override_settings(DOCUMENT_PARSING_AUTO_PARSING=True)
|
||||
class DocumentParsingContentAPITestCase(DocumentTestMixin, BaseAPITestCase):
|
||||
test_document_filename = TEST_HYBRID_DOCUMENT
|
||||
|
||||
def _request_document_content_view(self):
|
||||
return self.get(
|
||||
viewname='rest_api:document-parsing-content',
|
||||
kwargs={
|
||||
'document_id': self.test_document.pk,
|
||||
}
|
||||
)
|
||||
|
||||
def test_get_document_content_no_permission(self):
|
||||
response = self._request_document_content_view()
|
||||
self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
|
||||
|
||||
def test_get_document_content_with_access(self):
|
||||
self.grant_access(
|
||||
obj=self.document, permission=permission_content_view
|
||||
)
|
||||
|
||||
response = self._request_document_content_view()
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
self.assertTrue(
|
||||
TEST_DOCUMENT_CONTENT in response.data['text']
|
||||
)
|
||||
|
||||
def _request_document_page_content_view(self):
|
||||
latest_version = self.test_document.latest_version
|
||||
|
||||
return self.get(
|
||||
viewname='rest_api:document_page-parsing-content',
|
||||
kwargs={
|
||||
'document_id': self.test_document.pk,
|
||||
'document_version_id': latest_version.pk,
|
||||
'document_page_id': latest_version.pages.first().pk
|
||||
}
|
||||
)
|
||||
|
||||
def test_get_document_page_content_no_access(self):
|
||||
response = self._request_document_page_content_view()
|
||||
self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
|
||||
|
||||
def test_get_document_page_content_with_access(self):
|
||||
self.grant_access(
|
||||
obj=self.document, permission=permission_content_view
|
||||
)
|
||||
response = self._request_document_page_content_view()
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
self.assertTrue(
|
||||
TEST_DOCUMENT_CONTENT in response.data['content']
|
||||
TEST_DOCUMENT_CONTENT in response.data['text']
|
||||
)
|
||||
|
||||
def _request_document_version_content_view(self):
|
||||
latest_version = self.test_document.latest_version
|
||||
|
||||
return self.get(
|
||||
viewname='rest_api:document_version-parsing-content',
|
||||
kwargs={
|
||||
'document_id': self.test_document.pk,
|
||||
'document_version_id': latest_version.pk,
|
||||
}
|
||||
)
|
||||
|
||||
def test_get_document_version_content_no_permission(self):
|
||||
response = self._request_document_version_content_view()
|
||||
self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
|
||||
|
||||
def test_get_document_version_content_with_access(self):
|
||||
self.grant_access(
|
||||
obj=self.document, permission=permission_content_view
|
||||
)
|
||||
|
||||
response = self._request_document_version_content_view()
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
self.assertTrue(
|
||||
TEST_DOCUMENT_CONTENT in response.data['text']
|
||||
)
|
||||
|
||||
@@ -25,20 +25,19 @@ class DocumentContentViewsTestCase(GenericDocumentViewTestCase):
|
||||
def _request_document_content_view(self):
|
||||
return self.get(
|
||||
viewname='document_parsing:document_content',
|
||||
kwargs={'document_id': self.document.pk}
|
||||
kwargs={'document_id': self.test_document.pk}
|
||||
)
|
||||
|
||||
def test_document_content_view_no_permissions(self):
|
||||
response = self._request_document_content_view()
|
||||
|
||||
self.assertEqual(response.status_code, 404)
|
||||
|
||||
def test_document_content_view_with_access(self):
|
||||
self.grant_access(
|
||||
permission=permission_content_view, obj=self.document
|
||||
obj=self.test_document, permission=permission_content_view
|
||||
)
|
||||
response = self._request_document_content_view()
|
||||
|
||||
response = self._request_document_content_view()
|
||||
self.assertContains(
|
||||
response=response, text=TEST_DOCUMENT_CONTENT, status_code=200
|
||||
)
|
||||
@@ -46,21 +45,20 @@ class DocumentContentViewsTestCase(GenericDocumentViewTestCase):
|
||||
def _request_document_page_content_view(self):
|
||||
return self.get(
|
||||
viewname='document_parsing:document_page_content', kwargs={
|
||||
'document_page_id': self.document.pages.first().pk
|
||||
'document_page_id': self.test_document.pages.first().pk
|
||||
}
|
||||
)
|
||||
|
||||
def test_document_page_content_view_no_permissions(self):
|
||||
response = self._request_document_page_content_view()
|
||||
|
||||
self.assertEqual(response.status_code, 404)
|
||||
|
||||
def test_document_page_content_view_with_access(self):
|
||||
self.grant_access(
|
||||
permission=permission_content_view, obj=self.document
|
||||
permission=permission_content_view, obj=self.test_document
|
||||
)
|
||||
response = self._request_document_page_content_view()
|
||||
|
||||
response = self._request_document_page_content_view()
|
||||
self.assertContains(
|
||||
response=response, text=TEST_DOCUMENT_CONTENT, status_code=200
|
||||
)
|
||||
@@ -68,7 +66,7 @@ class DocumentContentViewsTestCase(GenericDocumentViewTestCase):
|
||||
def _request_document_content_download_view(self):
|
||||
return self.get(
|
||||
viewname='document_parsing:document_content_download',
|
||||
kwargs={'document_id': self.document.pk}
|
||||
kwargs={'document_id': self.test_document.pk}
|
||||
)
|
||||
|
||||
def test_document_parsing_download_view_no_permission(self):
|
||||
@@ -78,16 +76,72 @@ class DocumentContentViewsTestCase(GenericDocumentViewTestCase):
|
||||
def test_download_view_with_access(self):
|
||||
self.expected_content_type = 'application/octet-stream; charset=utf-8'
|
||||
self.grant_access(
|
||||
permission=permission_content_view, obj=self.document
|
||||
permission=permission_content_view, obj=self.test_document
|
||||
)
|
||||
|
||||
response = self._request_document_content_download_view()
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
self.assert_download_response(
|
||||
response=response, content=(
|
||||
''.join(get_document_content_iterator(document=self.document))
|
||||
),
|
||||
content=(
|
||||
''.join(get_document_content_iterator(document=self.test_document))
|
||||
), response=response
|
||||
)
|
||||
|
||||
|
||||
class DocumentSubmitViewsTestCase(GenericDocumentViewTestCase):
|
||||
_skip_file_descriptor_test = True
|
||||
|
||||
# Ensure we use a PDF file
|
||||
test_document_filename = TEST_HYBRID_DOCUMENT
|
||||
|
||||
def _request_document_submit_view(self):
|
||||
return self.post(
|
||||
viewname='document_parsing:document_submit',
|
||||
kwargs={'document_id': self.test_document.pk}
|
||||
)
|
||||
|
||||
def test_document_submit_view_no_permission(self):
|
||||
response = self._request_document_submit_view()
|
||||
self.assertEqual(response.status_code, 404)
|
||||
|
||||
self.assertEqual(self.test_document.get_content(), '')
|
||||
|
||||
def test_document_submit_view_with_access(self):
|
||||
self.grant_access(
|
||||
obj=self.test_document, permission=permission_parse_document
|
||||
)
|
||||
|
||||
response = self._request_document_submit_view()
|
||||
self.assertEqual(response.status_code, 302)
|
||||
|
||||
self.assertTrue(
|
||||
TEST_DOCUMENT_CONTENT in self.test_document.get_content()
|
||||
)
|
||||
|
||||
def _request_multiple_document_submit_view(self):
|
||||
return self.post(
|
||||
viewname='document_parsing:document_multiple_submit',
|
||||
data={
|
||||
'id_list': self.test_document.pk,
|
||||
}
|
||||
)
|
||||
|
||||
def test_multiple_document_submit_view_no_permission(self):
|
||||
response = self._request_multiple_document_submit_view()
|
||||
self.assertEqual(response.status_code, 404)
|
||||
|
||||
self.assertEqual(self.test_document.get_content(), '')
|
||||
|
||||
def test_multiple_document_submit_view_with_access(self):
|
||||
self.grant_access(
|
||||
obj=self.test_document, permission=permission_parse_document
|
||||
)
|
||||
|
||||
response = self._request_multiple_document_submit_view()
|
||||
self.assertEqual(response.status_code, 302)
|
||||
|
||||
self.assertTrue(
|
||||
TEST_DOCUMENT_CONTENT in self.test_document.get_content()
|
||||
)
|
||||
|
||||
|
||||
@@ -98,17 +152,17 @@ class DocumentTypeViewsTestCase(GenericDocumentViewTestCase):
|
||||
def _request_document_type_parsing_settings_view(self):
|
||||
return self.get(
|
||||
viewname='document_parsing:document_type_parsing_settings',
|
||||
kwargs={'document_type_id': self.document.document_type.pk}
|
||||
kwargs={'document_type_id': self.test_document.document_type.pk}
|
||||
)
|
||||
|
||||
def test_document_type_parsing_settings_view_no_permission(self):
|
||||
response = self._request_document_type_parsing_settings_view()
|
||||
self.assertEqual(response.status_code, 403)
|
||||
self.assertEqual(response.status_code, 404)
|
||||
|
||||
def test_document_type_parsing_settings_view_with_access(self):
|
||||
self.grant_access(
|
||||
permission=permission_document_type_parsing_setup,
|
||||
obj=self.document.document_type
|
||||
obj=self.test_document.document_type,
|
||||
permission=permission_document_type_parsing_setup
|
||||
)
|
||||
response = self._request_document_type_parsing_settings_view()
|
||||
|
||||
@@ -117,7 +171,7 @@ class DocumentTypeViewsTestCase(GenericDocumentViewTestCase):
|
||||
def _request_document_type_submit_view(self):
|
||||
return self.post(
|
||||
viewname='document_parsing:document_type_submit', data={
|
||||
'document_type': self.document_type.pk,
|
||||
'document_type': self.test_document_type.pk,
|
||||
}
|
||||
)
|
||||
|
||||
@@ -125,15 +179,15 @@ class DocumentTypeViewsTestCase(GenericDocumentViewTestCase):
|
||||
response = self._request_document_type_submit_view()
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertTrue(
|
||||
TEST_DOCUMENT_CONTENT not in self.document.get_content()
|
||||
TEST_DOCUMENT_CONTENT not in self.test_document.get_content()
|
||||
)
|
||||
|
||||
def test_document_type_submit_view_with_access(self):
|
||||
self.grant_access(
|
||||
obj=self.document_type, permission=permission_parse_document,
|
||||
obj=self.test_document_type, permission=permission_parse_document
|
||||
)
|
||||
response = self._request_document_type_submit_view()
|
||||
self.assertEqual(response.status_code, 302)
|
||||
self.assertTrue(
|
||||
TEST_DOCUMENT_CONTENT in self.document.get_content()
|
||||
TEST_DOCUMENT_CONTENT in self.test_document.get_content()
|
||||
)
|
||||
|
||||
@@ -2,7 +2,10 @@ from __future__ import unicode_literals
|
||||
|
||||
from django.conf.urls import url
|
||||
|
||||
from .api_views import APIDocumentPageContentView
|
||||
from .api_views import (
|
||||
DocumentParsingAPIViewSet, DocumentPageParsingAPIViewSet,
|
||||
DocumentVersionParsingAPIViewSet
|
||||
)
|
||||
from .views import (
|
||||
DocumentContentDownloadView, DocumentContentView, DocumentPageContentView,
|
||||
DocumentParsingErrorsListView, DocumentSubmitView,
|
||||
@@ -51,10 +54,20 @@ urlpatterns = [
|
||||
)
|
||||
]
|
||||
|
||||
api_urls = [
|
||||
url(
|
||||
regex=r'^documents/(?P<document_id>\d+)/versions/(?P<document_version_id>\d+)/pages/(?P<document_page_id>\d+)/content/$',
|
||||
view=APIDocumentPageContentView.as_view(),
|
||||
name='document-page-content-view'
|
||||
)
|
||||
]
|
||||
|
||||
api_router_entries = (
|
||||
{
|
||||
'prefix': r'documents',
|
||||
'viewset': DocumentParsingAPIViewSet, 'basename': 'document-parsing'
|
||||
},
|
||||
{
|
||||
'prefix': r'documents/(?P<document_id>\d+)/document_versions',
|
||||
'viewset': DocumentVersionParsingAPIViewSet,
|
||||
'basename': 'document_version-parsing'
|
||||
},
|
||||
{
|
||||
'prefix': r'documents/(?P<document_id>\d+)/document_versions/(?P<document_version_id>\d+)/document_pages',
|
||||
'viewset': DocumentPageParsingAPIViewSet,
|
||||
'basename': 'document_page-parsing'
|
||||
},
|
||||
)
|
||||
|
||||
@@ -6,12 +6,12 @@ from django.http import HttpResponseRedirect
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django.urls import reverse_lazy
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.translation import ungettext
|
||||
|
||||
from mayan.apps.common.generics import (
|
||||
FormView, MultipleObjectConfirmActionView, SingleObjectDetailView,
|
||||
SingleObjectDownloadView, SingleObjectEditView, SingleObjectListView
|
||||
)
|
||||
from mayan.apps.common.mixins import ExternalObjectMixin
|
||||
from mayan.apps.documents.forms import DocumentTypeFilteredSelectForm
|
||||
from mayan.apps.documents.models import Document, DocumentPage, DocumentType
|
||||
|
||||
@@ -42,7 +42,7 @@ class DocumentContentView(SingleObjectDetailView):
|
||||
'document': self.get_object(),
|
||||
'hide_labels': True,
|
||||
'object': self.get_object(),
|
||||
'title': _('Content for document: %s') % self.get_object(),
|
||||
'title': _('Content for document: %s.') % self.get_object(),
|
||||
}
|
||||
|
||||
|
||||
@@ -79,7 +79,7 @@ class DocumentPageContentView(SingleObjectDetailView):
|
||||
return {
|
||||
'hide_labels': True,
|
||||
'object': self.get_object(),
|
||||
'title': _('Content for document page: %s') % self.get_object(),
|
||||
'title': _('Content for document page: %s.') % self.get_object(),
|
||||
}
|
||||
|
||||
|
||||
@@ -94,7 +94,7 @@ class DocumentParsingErrorsListView(SingleObjectListView):
|
||||
'hide_object': True,
|
||||
'object': self.get_document(),
|
||||
'title': _(
|
||||
'Parsing errors for document: %s'
|
||||
'Parsing errors for document: %s.'
|
||||
) % self.get_document(),
|
||||
}
|
||||
|
||||
@@ -105,57 +105,39 @@ class DocumentParsingErrorsListView(SingleObjectListView):
|
||||
class DocumentSubmitView(MultipleObjectConfirmActionView):
|
||||
model = Document
|
||||
object_permission = permission_parse_document
|
||||
pk_url_kwarg = 'document_id'
|
||||
success_message_single = _(
|
||||
'Document "%(object)s" added to the parsing queue.'
|
||||
)
|
||||
success_message_singular = _(
|
||||
'%(count)d document added to the parsing queue'
|
||||
'%(count)d document added to the parsing queue.'
|
||||
)
|
||||
success_message_plural = _(
|
||||
'%(count)d documents added to the parsing queue'
|
||||
'%(count)d documents added to the parsing queue.'
|
||||
)
|
||||
|
||||
def get_extra_context(self):
|
||||
queryset = self.get_queryset()
|
||||
|
||||
result = {
|
||||
'title': ungettext(
|
||||
singular='Submit %(count)d document to the parsing queue?',
|
||||
plural='Submit %(count)d documents to the parsing queue',
|
||||
number=queryset.count()
|
||||
) % {
|
||||
'count': queryset.count(),
|
||||
}
|
||||
}
|
||||
|
||||
if queryset.count() == 1:
|
||||
result.update(
|
||||
{
|
||||
'object': queryset.first(),
|
||||
'title': _(
|
||||
'Submit document "%s" to the parsing queue'
|
||||
) % queryset.first()
|
||||
}
|
||||
)
|
||||
|
||||
return result
|
||||
title_single = _('Submit the document "%(object)s" to the parsing queue.')
|
||||
title_singular = _('Submit %(count)d document to the parsing queue.')
|
||||
title_plural = _('Submit %(count)d documents to the parsing queue.')
|
||||
|
||||
def object_action(self, instance, form=None):
|
||||
instance.submit_for_parsing()
|
||||
|
||||
|
||||
class DocumentTypeSettingsEditView(SingleObjectEditView):
|
||||
class DocumentTypeSettingsEditView(ExternalObjectMixin, SingleObjectEditView):
|
||||
external_object_class = DocumentType
|
||||
external_object_permission = permission_document_type_parsing_setup
|
||||
external_object_pk_url_kwarg = 'document_type_id'
|
||||
fields = ('auto_parsing',)
|
||||
object_permission = permission_document_type_parsing_setup
|
||||
post_action_redirect = reverse_lazy(viewname='documents:document_type_list')
|
||||
|
||||
def get_document_type(self):
|
||||
return get_object_or_404(
|
||||
klass=DocumentType, pk=self.kwargs['document_type_id']
|
||||
)
|
||||
return self.external_object
|
||||
|
||||
def get_extra_context(self):
|
||||
return {
|
||||
'object': self.get_document_type(),
|
||||
'title': _(
|
||||
'Edit parsing settings for document type: %s'
|
||||
'Edit parsing settings for document type: %s.'
|
||||
) % self.get_document_type()
|
||||
}
|
||||
|
||||
@@ -165,7 +147,7 @@ class DocumentTypeSettingsEditView(SingleObjectEditView):
|
||||
|
||||
class DocumentTypeSubmitView(FormView):
|
||||
extra_context = {
|
||||
'title': _('Submit all documents of a type for parsing')
|
||||
'title': _('Submit all documents of a type for parsing.')
|
||||
}
|
||||
form_class = DocumentTypeFilteredSelectForm
|
||||
post_action_redirect = reverse_lazy(viewname='common:tools_list')
|
||||
@@ -198,7 +180,7 @@ class DocumentTypeSubmitView(FormView):
|
||||
class ParseErrorListView(SingleObjectListView):
|
||||
extra_context = {
|
||||
'hide_object': True,
|
||||
'title': _('Parsing errors'),
|
||||
'title': _('Parsing errors.'),
|
||||
}
|
||||
view_permission = permission_document_type_parsing_setup
|
||||
|
||||
|
||||
Reference in New Issue
Block a user