Add API views to download documents and document versions.
This commit is contained in:
@@ -5,6 +5,7 @@ import logging
|
|||||||
from django.core.exceptions import PermissionDenied
|
from django.core.exceptions import PermissionDenied
|
||||||
from django.shortcuts import get_object_or_404
|
from django.shortcuts import get_object_or_404
|
||||||
|
|
||||||
|
from filetransfers.api import serve_file
|
||||||
from rest_framework import generics, status
|
from rest_framework import generics, status
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
|
|
||||||
@@ -18,19 +19,19 @@ from .models import (
|
|||||||
)
|
)
|
||||||
from .permissions import (
|
from .permissions import (
|
||||||
permission_document_create, permission_document_delete,
|
permission_document_create, permission_document_delete,
|
||||||
permission_document_edit, permission_document_new_version,
|
permission_document_download, permission_document_edit,
|
||||||
permission_document_properties_edit, permission_document_restore,
|
permission_document_new_version, permission_document_properties_edit,
|
||||||
permission_document_trash, permission_document_version_revert,
|
permission_document_restore, permission_document_trash,
|
||||||
permission_document_view, permission_document_type_create,
|
permission_document_version_revert, permission_document_view,
|
||||||
permission_document_type_delete, permission_document_type_edit,
|
permission_document_type_create, permission_document_type_delete,
|
||||||
permission_document_type_view
|
permission_document_type_edit, permission_document_type_view
|
||||||
)
|
)
|
||||||
from .serializers import (
|
from .serializers import (
|
||||||
DeletedDocumentSerializer, DocumentPageImageSerializer,
|
DeletedDocumentSerializer, DocumentPageImageSerializer,
|
||||||
DocumentPageSerializer, DocumentSerializer, DocumentTypeSerializer,
|
DocumentPageSerializer, DocumentSerializer,
|
||||||
DocumentVersionSerializer, DocumentVersionRevertSerializer,
|
DocumentTypeSerializer, DocumentVersionSerializer,
|
||||||
NewDocumentSerializer, NewDocumentVersionSerializer,
|
DocumentVersionRevertSerializer, NewDocumentSerializer,
|
||||||
RecentDocumentSerializer
|
NewDocumentVersionSerializer, RecentDocumentSerializer
|
||||||
)
|
)
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
@@ -86,6 +87,37 @@ class APIDeletedDocumentRestoreView(generics.GenericAPIView):
|
|||||||
return Response(status=status.HTTP_200_OK)
|
return Response(status=status.HTTP_200_OK)
|
||||||
|
|
||||||
|
|
||||||
|
class APIDocumentDownloadView(generics.RetrieveAPIView):
|
||||||
|
"""
|
||||||
|
Download the latest version of a document.
|
||||||
|
---
|
||||||
|
GET:
|
||||||
|
omit_serializer: true
|
||||||
|
parameters:
|
||||||
|
- name: pk
|
||||||
|
paramType: path
|
||||||
|
type: number
|
||||||
|
"""
|
||||||
|
|
||||||
|
mayan_object_permissions = {
|
||||||
|
'GET': (permission_document_download,)
|
||||||
|
}
|
||||||
|
permission_classes = (MayanPermission,)
|
||||||
|
queryset = Document.objects.all()
|
||||||
|
|
||||||
|
def get_serializer_class(self):
|
||||||
|
return None
|
||||||
|
|
||||||
|
def retrieve(self, request, *args, **kwargs):
|
||||||
|
instance = self.get_object()
|
||||||
|
return serve_file(
|
||||||
|
request,
|
||||||
|
instance.latest_version.file,
|
||||||
|
save_as='"%s"' % instance.label,
|
||||||
|
content_type=instance.latest_version.mimetype if instance.latest_version.mimetype else 'application/octet-stream'
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class APIDocumentListView(generics.ListCreateAPIView):
|
class APIDocumentListView(generics.ListCreateAPIView):
|
||||||
"""
|
"""
|
||||||
Returns a list of all the documents.
|
Returns a list of all the documents.
|
||||||
@@ -114,6 +146,37 @@ class APIDocumentListView(generics.ListCreateAPIView):
|
|||||||
return super(APIDocumentListView, self).post(*args, **kwargs)
|
return super(APIDocumentListView, self).post(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
class APIDocumentVersionDownloadView(generics.RetrieveAPIView):
|
||||||
|
"""
|
||||||
|
Download a document version.
|
||||||
|
---
|
||||||
|
GET:
|
||||||
|
omit_serializer: true
|
||||||
|
parameters:
|
||||||
|
- name: pk
|
||||||
|
paramType: path
|
||||||
|
type: number
|
||||||
|
"""
|
||||||
|
|
||||||
|
mayan_object_permissions = {
|
||||||
|
'GET': (permission_document_download,)
|
||||||
|
}
|
||||||
|
permission_classes = (MayanPermission,)
|
||||||
|
queryset = DocumentVersion.objects.all()
|
||||||
|
|
||||||
|
def get_serializer_class(self):
|
||||||
|
return None
|
||||||
|
|
||||||
|
def retrieve(self, request, *args, **kwargs):
|
||||||
|
instance = self.get_object()
|
||||||
|
return serve_file(
|
||||||
|
request,
|
||||||
|
instance.file,
|
||||||
|
save_as='"%s"' % instance.document.label,
|
||||||
|
content_type=instance.mimetype if instance.mimetype else 'application/octet-stream'
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class APIDocumentView(generics.RetrieveUpdateDestroyAPIView):
|
class APIDocumentView(generics.RetrieveUpdateDestroyAPIView):
|
||||||
"""
|
"""
|
||||||
Returns the selected document details.
|
Returns the selected document details.
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ TEST_NON_ASCII_COMPRESSED_DOCUMENT_FILENAME = 'I18N_title_áéíóúüñÑ.png.z
|
|||||||
TEST_NON_ASCII_DOCUMENT_FILENAME = 'I18N_title_áéíóúüñÑ.png'
|
TEST_NON_ASCII_DOCUMENT_FILENAME = 'I18N_title_áéíóúüñÑ.png'
|
||||||
TEST_OFFICE_DOCUMENT = 'simple_2_page_document.doc'
|
TEST_OFFICE_DOCUMENT = 'simple_2_page_document.doc'
|
||||||
TEST_SMALL_DOCUMENT_FILENAME = 'title_page.png'
|
TEST_SMALL_DOCUMENT_FILENAME = 'title_page.png'
|
||||||
|
TEST_SMALL_DOCUMENT_CHECKSUM = 'efa10e6cc21f83078aaa94d5cbe51de67b51af706143bafc7fd6d4c02124879a'
|
||||||
|
|
||||||
# File paths
|
# File paths
|
||||||
TEST_COMPRESSED_DOCUMENT_PATH = os.path.join(
|
TEST_COMPRESSED_DOCUMENT_PATH = os.path.join(
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import io
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from json import loads
|
from json import loads
|
||||||
@@ -17,9 +18,9 @@ from rest_framework.test import APITestCase
|
|||||||
from .literals import (
|
from .literals import (
|
||||||
TEST_ADMIN_EMAIL, TEST_ADMIN_PASSWORD, TEST_ADMIN_USERNAME,
|
TEST_ADMIN_EMAIL, TEST_ADMIN_PASSWORD, TEST_ADMIN_USERNAME,
|
||||||
TEST_DOCUMENT_FILENAME, TEST_DOCUMENT_PATH, TEST_DOCUMENT_TYPE,
|
TEST_DOCUMENT_FILENAME, TEST_DOCUMENT_PATH, TEST_DOCUMENT_TYPE,
|
||||||
TEST_SMALL_DOCUMENT_PATH,
|
TEST_SMALL_DOCUMENT_CHECKSUM, TEST_SMALL_DOCUMENT_PATH,
|
||||||
)
|
)
|
||||||
from ..models import Document, DocumentType
|
from ..models import Document, DocumentType, HASH_FUNCTION
|
||||||
|
|
||||||
|
|
||||||
class DocumentTypeAPITestCase(APITestCase):
|
class DocumentTypeAPITestCase(APITestCase):
|
||||||
@@ -231,5 +232,46 @@ class DocumentAPITestCase(APITestCase):
|
|||||||
|
|
||||||
self.assertEqual(document_version, document.latest_version)
|
self.assertEqual(document_version, document.latest_version)
|
||||||
|
|
||||||
|
def test_document_download(self):
|
||||||
|
with open(TEST_SMALL_DOCUMENT_PATH) as file_object:
|
||||||
|
document = self.document_type.new_document(
|
||||||
|
file_object=File(file_object),
|
||||||
|
)
|
||||||
|
|
||||||
|
response = self.client.get(
|
||||||
|
reverse(
|
||||||
|
'rest_api:document-download', args=(document.pk,)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
buf = io.BytesIO()
|
||||||
|
buf.write(response.content)
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
HASH_FUNCTION(buf.getvalue()), TEST_SMALL_DOCUMENT_CHECKSUM
|
||||||
|
)
|
||||||
|
|
||||||
|
del(buf)
|
||||||
|
|
||||||
|
def test_document_version_download(self):
|
||||||
|
with open(TEST_SMALL_DOCUMENT_PATH) as file_object:
|
||||||
|
document = self.document_type.new_document(
|
||||||
|
file_object=File(file_object),
|
||||||
|
)
|
||||||
|
|
||||||
|
response = self.client.get(
|
||||||
|
reverse(
|
||||||
|
'rest_api:documentversion-download',
|
||||||
|
args=(document.latest_version.pk,)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
buf = io.BytesIO()
|
||||||
|
buf.write(response.content)
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
HASH_FUNCTION(buf.getvalue()), TEST_SMALL_DOCUMENT_CHECKSUM
|
||||||
|
)
|
||||||
|
|
||||||
|
del(buf)
|
||||||
|
|
||||||
#def test_document_set_document_type(self):
|
#def test_document_set_document_type(self):
|
||||||
# pass
|
# pass
|
||||||
|
|||||||
@@ -4,7 +4,8 @@ from django.conf.urls import patterns, url
|
|||||||
|
|
||||||
from .api_views import (
|
from .api_views import (
|
||||||
APIDeletedDocumentListView, APIDeletedDocumentRestoreView,
|
APIDeletedDocumentListView, APIDeletedDocumentRestoreView,
|
||||||
APIDeletedDocumentView, APIDocumentView, APIDocumentListView,
|
APIDeletedDocumentView, APIDocumentDownloadView, APIDocumentView,
|
||||||
|
APIDocumentListView, APIDocumentVersionDownloadView,
|
||||||
APIDocumentPageImageView, APIDocumentPageView,
|
APIDocumentPageImageView, APIDocumentPageView,
|
||||||
APIDocumentTypeDocumentListView, APIDocumentTypeListView,
|
APIDocumentTypeDocumentListView, APIDocumentTypeListView,
|
||||||
APIDocumentTypeView, APIDocumentVersionsListView,
|
APIDocumentTypeView, APIDocumentVersionsListView,
|
||||||
@@ -263,6 +264,10 @@ api_urls = patterns(
|
|||||||
r'^documents/(?P<pk>[0-9]+)/versions/$',
|
r'^documents/(?P<pk>[0-9]+)/versions/$',
|
||||||
APIDocumentVersionsListView.as_view(), name='document-version-list'
|
APIDocumentVersionsListView.as_view(), name='document-version-list'
|
||||||
),
|
),
|
||||||
|
url(
|
||||||
|
r'^documents/(?P<pk>[0-9]+)/download/$',
|
||||||
|
APIDocumentDownloadView.as_view(), name='document-download'
|
||||||
|
),
|
||||||
url(
|
url(
|
||||||
r'^document_version/(?P<pk>[0-9]+)/$',
|
r'^document_version/(?P<pk>[0-9]+)/$',
|
||||||
APIDocumentVersionView.as_view(), name='documentversion-detail'
|
APIDocumentVersionView.as_view(), name='documentversion-detail'
|
||||||
@@ -271,6 +276,10 @@ api_urls = patterns(
|
|||||||
r'^document_version/(?P<pk>[0-9]+)/revert/$',
|
r'^document_version/(?P<pk>[0-9]+)/revert/$',
|
||||||
APIDocumentVersionRevertView.as_view(), name='documentversion-revert'
|
APIDocumentVersionRevertView.as_view(), name='documentversion-revert'
|
||||||
),
|
),
|
||||||
|
url(
|
||||||
|
r'^document_version/(?P<pk>[0-9]+)/download/$',
|
||||||
|
APIDocumentVersionDownloadView.as_view(), name='documentversion-download'
|
||||||
|
),
|
||||||
url(
|
url(
|
||||||
r'^document_page/(?P<pk>[0-9]+)/$', APIDocumentPageView.as_view(),
|
r'^document_page/(?P<pk>[0-9]+)/$', APIDocumentPageView.as_view(),
|
||||||
name='documentpage-detail'
|
name='documentpage-detail'
|
||||||
|
|||||||
Reference in New Issue
Block a user