Add proper document creation API endpoint
This commit is contained in:
@@ -1,10 +1,13 @@
|
||||
from __future__ import absolute_import
|
||||
|
||||
import tempfile
|
||||
|
||||
from django.core.exceptions import PermissionDenied
|
||||
from django.shortcuts import get_object_or_404
|
||||
|
||||
from rest_framework import generics, status
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.settings import api_settings
|
||||
|
||||
from acls.models import AccessEntry
|
||||
from converter.exceptions import UnkownConvertError, UnknownFileFormat
|
||||
@@ -26,14 +29,15 @@ from .permissions import (PERMISSION_DOCUMENT_CREATE,
|
||||
PERMISSION_DOCUMENT_TYPE_VIEW)
|
||||
from .serializers import (DocumentImageSerializer, DocumentPageSerializer,
|
||||
DocumentSerializer, DocumentTypeSerializer,
|
||||
DocumentVersionSerializer)
|
||||
DocumentVersionSerializer, NewDocumentSerializer)
|
||||
from .settings import DISPLAY_SIZE, ZOOM_MAX_LEVEL, ZOOM_MIN_LEVEL
|
||||
from .tasks import task_get_document_image
|
||||
from .tasks import task_get_document_image, task_new_document
|
||||
|
||||
|
||||
DOCUMENT_IMAGE_TASK_TIMEOUT = 10
|
||||
|
||||
|
||||
class APIDocumentListView(generics.ListCreateAPIView):
|
||||
class APIDocumentListView(generics.ListAPIView):
|
||||
"""
|
||||
Returns a list of all the documents.
|
||||
"""
|
||||
@@ -44,8 +48,51 @@ class APIDocumentListView(generics.ListCreateAPIView):
|
||||
permission_classes = (MayanPermission,)
|
||||
filter_backends = (MayanObjectPermissionsFilter,)
|
||||
mayan_object_permissions = {'GET': [PERMISSION_DOCUMENT_VIEW]}
|
||||
|
||||
|
||||
class APINewDocumentView(generics.GenericAPIView):
|
||||
serializer_class = NewDocumentSerializer
|
||||
|
||||
permission_classes = (MayanPermission,)
|
||||
mayan_view_permissions = {'POST': [PERMISSION_DOCUMENT_CREATE]}
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
"""Create a new document."""
|
||||
|
||||
serializer = self.get_serializer(data=request.DATA, files=request.FILES)
|
||||
|
||||
if serializer.is_valid():
|
||||
print serializer.data
|
||||
temporary_file = tempfile.NamedTemporaryFile(delete=False)
|
||||
source_file = request.FILES['file']
|
||||
for chunk in source_file.chunks():
|
||||
temporary_file.write(chunk)
|
||||
temporary_file.close()
|
||||
source_file.close()
|
||||
|
||||
task_new_document.apply_async(kwargs=dict(
|
||||
file_path=temporary_file.name,
|
||||
document_type_id=serializer.data['document_type'],
|
||||
description=serializer.data['description'],
|
||||
expand=serializer.data['expand'],
|
||||
label=serializer.data['label'],
|
||||
language=serializer.data['language'],
|
||||
user_id=serializer.data['user']
|
||||
), queue='uploads')
|
||||
|
||||
|
||||
headers = self.get_success_headers(serializer.data)
|
||||
return Response(serializer.data, status=status.HTTP_202_ACCEPTED,
|
||||
headers=headers)
|
||||
|
||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
def get_success_headers(self, data):
|
||||
try:
|
||||
return {'Location': data[api_settings.URL_FIELD_NAME]}
|
||||
except (TypeError, KeyError):
|
||||
return {}
|
||||
|
||||
|
||||
class APIDocumentView(generics.RetrieveUpdateDestroyAPIView):
|
||||
"""
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
from __future__ import absolute_import
|
||||
|
||||
from ast import literal_eval
|
||||
import logging
|
||||
|
||||
from django.db import models, transaction
|
||||
|
||||
from common.compressed_files import CompressedFile, NotACompressedFile
|
||||
|
||||
from .settings import RECENT_COUNT
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class DocumentPageTransformationManager(models.Manager):
|
||||
def get_for_document_page(self, document_page):
|
||||
@@ -54,9 +59,38 @@ class DocumentTypeManager(models.Manager):
|
||||
|
||||
|
||||
class DocumentManager(models.Manager):
|
||||
def new_document(self, document_type, file_object, label, command_line=False, description=None, expand=False, language=None, user=None):
|
||||
documents_created = []
|
||||
is_compressed = None
|
||||
|
||||
if expand:
|
||||
try:
|
||||
compressed_file = CompressedFile(file_object)
|
||||
count = 1
|
||||
for compressed_file_child in compressed_file.children():
|
||||
if command_line:
|
||||
print 'Uploading file #%d: %s' % (count, fp)
|
||||
documents_created.append(self.upload_single_document(document_type=document_type, file_object=compressed_file_child, description=description, label=unicode(fp), language=language, user=user))
|
||||
compressed_file_child.close()
|
||||
count += 1
|
||||
|
||||
except NotACompressedFile:
|
||||
is_compressed = False
|
||||
logging.debug('Exception: NotACompressedFile')
|
||||
if command_line:
|
||||
raise
|
||||
documents_created.append(self.upload_single_document(document_type=document_type, file_object=file_object, description=description, label=label, language=language, user=user))
|
||||
else:
|
||||
is_compressed = True
|
||||
else:
|
||||
documents_created.append(self.upload_single_document(document_type=document_type, file_object=file_object, description=description, label=label, language=language, user=user))
|
||||
|
||||
file_object.close()
|
||||
return documents_created
|
||||
|
||||
@transaction.atomic
|
||||
def new_document(self, file_object, document_type, label, user=None, description=None, language=None):
|
||||
document = self.model(document_type=document_type, label=label,
|
||||
description=description, language=language)
|
||||
def upload_single_document(self, document_type, file_object, label, description=None, language=None, user=None):
|
||||
document = self.model(description=description, document_type=document_type, language=language, label=label)
|
||||
document.save(user=user)
|
||||
return document.new_version(file=file_object, user=user)
|
||||
document.new_version(file=file_object, user=user)
|
||||
return document
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
from __future__ import absolute_import
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
|
||||
from rest_framework import serializers
|
||||
|
||||
from .literals import LANGUAGE_CHOICES
|
||||
from .models import Document, DocumentVersion, DocumentPage, DocumentType
|
||||
|
||||
|
||||
@@ -25,6 +28,7 @@ class DocumentImageSerializer(serializers.Serializer):
|
||||
|
||||
class DocumentSerializer(serializers.HyperlinkedModelSerializer):
|
||||
versions = DocumentVersionSerializer(many=True, read_only=True)
|
||||
# TODO: Deprecate, move this as an entry point of DocumentVersion's pages
|
||||
image = serializers.HyperlinkedIdentityField(view_name='document-image')
|
||||
new_version = serializers.HyperlinkedIdentityField(view_name='document-new-version')
|
||||
|
||||
@@ -33,9 +37,20 @@ class DocumentSerializer(serializers.HyperlinkedModelSerializer):
|
||||
model = Document
|
||||
|
||||
|
||||
class DocumentTypeSerializer(serializers.HyperlinkedModelSerializer):
|
||||
class DocumentTypeSerializer(serializers.ModelSerializer):
|
||||
documents = serializers.HyperlinkedIdentityField(view_name='documenttype-document-list')
|
||||
|
||||
class Meta:
|
||||
model = DocumentType
|
||||
fields = ('id', 'url', 'name', 'documents')
|
||||
fields = ('id', 'name', 'documents')
|
||||
|
||||
|
||||
class NewDocumentSerializer(serializers.Serializer):
|
||||
description = serializers.CharField(required=False)
|
||||
document_type = DocumentTypeSerializer()
|
||||
document_type = serializers.ChoiceField(choices=[(document_type.pk, document_type) for document_type in DocumentType.objects.all()])
|
||||
expand = serializers.BooleanField(default=False)
|
||||
file = serializers.FileField()
|
||||
label = serializers.CharField()
|
||||
language = serializers.ChoiceField(choices=LANGUAGE_CHOICES, blank_display_value=None, required=False)
|
||||
user = serializers.ChoiceField(required=False, choices=[(user.pk, user) for user in User.objects.all()])
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
import logging
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
from django.core.files import File
|
||||
|
||||
from mayan.celery import app
|
||||
|
||||
from .models import Document, DocumentVersion
|
||||
from .models import Document, DocumentType, DocumentVersion
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -26,3 +29,26 @@ def task_clear_image_cache():
|
||||
def task_update_page_count(version_id):
|
||||
document_version = DocumentVersion.objects.get(pk=version_id)
|
||||
document_version.update_page_count()
|
||||
|
||||
|
||||
@app.task(ignore_result=True)
|
||||
def task_new_document(document_type_id, file_path, label, description=None, expand=False, language=None, user_id=None):
|
||||
document_type = DocumentType.objects.get(pk=document_type_id)
|
||||
|
||||
if user_id:
|
||||
user = User.objects.get(pk=user_id)
|
||||
else:
|
||||
user = None
|
||||
|
||||
with File(file=open(file_path, mode='rb')) as file_object:
|
||||
new_version = Document.objects.new_document(document_type=document_type, expand=expand, file_object=file_object, label=label, description=description, language=language, user=user)
|
||||
|
||||
# TODO: Report/record how was file uploaded
|
||||
# if result['is_compressed'] is None:
|
||||
# messages.success(request, _(u'File uploaded successfully.'))
|
||||
|
||||
# if result['is_compressed'] is True:
|
||||
# messages.success(request, _(u'File uncompressed successfully and uploaded as individual files.'))
|
||||
|
||||
# if result['is_compressed'] is False:
|
||||
# messages.warning(request, _(u'File was not a compressed file, uploaded as it was.'))
|
||||
|
||||
@@ -5,7 +5,8 @@ from django.conf.urls import patterns, url
|
||||
from .api_views import (APIDocumentView, APIDocumentImageView, APIDocumentListView,
|
||||
APIDocumentPageView, APIDocumentTypeDocumentListView,
|
||||
APIDocumentTypeListView, APIDocumentTypeView,
|
||||
APIDocumentVersionCreateView, APIDocumentVersionView)
|
||||
APIDocumentVersionCreateView, APIDocumentVersionView,
|
||||
APINewDocumentView)
|
||||
from .settings import PRINT_SIZE, DISPLAY_SIZE
|
||||
from .views import DocumentListView
|
||||
|
||||
@@ -72,6 +73,7 @@ urlpatterns = patterns('documents.views',
|
||||
|
||||
api_urls = patterns('',
|
||||
url(r'^documents/$', APIDocumentListView.as_view(), name='document-list'),
|
||||
url(r'^documents/new/$', APINewDocumentView.as_view(), name='newdocument-view'),
|
||||
url(r'^documents/(?P<pk>[0-9]+)/$', APIDocumentView.as_view(), name='document-detail'),
|
||||
url(r'^document_version/(?P<pk>[0-9]+)/$', APIDocumentVersionView.as_view(), name='documentversion-detail'),
|
||||
url(r'^document_page/(?P<pk>[0-9]+)/$', APIDocumentPageView.as_view(), name='documentpage-detail'),
|
||||
|
||||
Reference in New Issue
Block a user