Refactor rest_api app and the method end points are registered. All apps API URL endpoints are now registered under the 'rest_api' namespace.

Update DRF and DRF swagger versions. Update all apps API registration method.
This commit is contained in:
Roberto Rosario
2015-08-06 02:51:23 -04:00
parent ea02172a82
commit 960d60c39d
23 changed files with 680 additions and 418 deletions

View File

@@ -319,13 +319,8 @@
function load_document_image(image) {
$.get( image.attr('data-src'), function(result) {
if (result.status == 'success') {
image.attr('src', result.data);
image.addClass(image.attr('data-post-load-class'));
} else {
image.parent().parent().html('<span class="fa-stack fa-lg"><i class="fa fa-file-o fa-stack-2x"></i><i class="fa fa-times fa-stack-1x text-danger"></i></span>');
set_image_noninteractive(image);
}
})
.fail(function() {
image.parent().parent().html('<span class="fa-stack fa-lg"><i class="fa fa-file-o fa-stack-2x"></i><i class="fa fa-times fa-stack-1x text-danger"></i></span>');

View File

@@ -35,7 +35,7 @@ class CheckoutsApp(MayanAppConfig):
def ready(self):
super(CheckoutsApp, self).ready()
APIEndPoint('checkouts')
APIEndPoint(app=self, version_string='1')
Document.add_to_class(
'check_in',

View File

@@ -96,12 +96,13 @@ class CommonApp(MayanAppConfig):
'common:tools_list'
)
)
user_logged_in.connect(
user_locale_profile_session_config,
dispatch_uid='user_locale_profile_session_config'
)
post_save.connect(
user_locale_profile_create,
dispatch_uid='user_locale_profile_create',
sender=settings.AUTH_USER_MODEL
)
user_logged_in.connect(
user_locale_profile_session_config,
dispatch_uid='user_locale_profile_session_config'
)

View File

@@ -18,6 +18,10 @@ class ConverterApp(MayanAppConfig):
def ready(self):
super(ConverterApp, self).ready()
menu_object.bind_links(
links=(link_transformation_edit, link_transformation_delete),
sources=(Transformation,)
)
menu_sidebar.bind_links(
links=(link_transformation_create,), sources=(Transformation,)
)
@@ -28,7 +32,3 @@ class ConverterApp(MayanAppConfig):
'converter:transformation_list'
)
)
menu_object.bind_links(
links=(link_transformation_edit, link_transformation_delete),
sources=(Transformation,)
)

View File

@@ -39,7 +39,7 @@ class DocumentIndexingApp(MayanAppConfig):
def ready(self):
super(DocumentIndexingApp, self).ready()
APIEndPoint('indexes', app_name='document_indexing')
APIEndPoint(app=self, version_string='1')
app.conf.CELERY_QUEUES.append(
Queue('indexing', Exchange('indexing'), routing_key='indexing'),
@@ -85,15 +85,6 @@ class DocumentIndexingApp(MayanAppConfig):
menu_setup.bind_links(links=(link_index_setup,))
menu_tools.bind_links(links=(link_rebuild_index_instances,))
post_document_created.connect(
document_created_index_update,
dispatch_uid='document_created_index_update', sender=Document
)
post_save.connect(
document_metadata_index_update,
dispatch_uid='document_metadata_index_update',
sender=DocumentMetadata
)
post_delete.connect(
document_index_delete, dispatch_uid='document_index_delete',
sender=Document
@@ -103,3 +94,12 @@ class DocumentIndexingApp(MayanAppConfig):
dispatch_uid='document_metadata_index_post_delete',
sender=DocumentMetadata
)
post_document_created.connect(
document_created_index_update,
dispatch_uid='document_created_index_update', sender=Document
)
post_save.connect(
document_metadata_index_update,
dispatch_uid='document_metadata_index_update',
sender=DocumentMetadata
)

File diff suppressed because it is too large Load Diff

View File

@@ -80,7 +80,7 @@ class DocumentsApp(MayanAppConfig):
def ready(self):
super(DocumentsApp, self).ready()
APIEndPoint('documents')
APIEndPoint(app=self, version_string='1')
MissingItem(
label=_('Create a document type'),

View File

@@ -20,7 +20,9 @@ from converter import (
converter_class, TransformationResize, TransformationRotate,
TransformationZoom
)
from converter.exceptions import InvalidOfficeFormat, UnknownFileFormat
from converter.exceptions import (
InvalidOfficeFormat, PageCountError, UnknownFileFormat
)
from converter.literals import DEFAULT_ZOOM_LEVEL, DEFAULT_ROTATION
from converter.models import Transformation
from mimetype.api import get_mimetype
@@ -150,6 +152,7 @@ class Document(models.Model):
in_trash = models.BooleanField(
default=False, editable=False, verbose_name=_('In trash?')
)
#TODO: set editable to False
deleted_date_time = models.DateTimeField(
blank=True, editable=True, null=True,
verbose_name=_('Date and time trashed')
@@ -431,12 +434,11 @@ class DocumentVersion(models.Model):
file_object=file_object, mime_type=self.mimetype
)
detected_pages = converter.get_page_count()
except UnknownFileFormat:
except PageCountError:
# If converter backend doesn't understand the format,
# use 1 as the total page count
detected_pages = 1
# TODO: should be no pages instead?
pass
else:
with transaction.atomic():
self.pages.all().delete()
@@ -670,8 +672,8 @@ class DocumentPage(models.Model):
as_base64 = kwargs.pop('as_base64', False)
transformations = kwargs.pop('transformations', [])
size = kwargs.pop('size', setting_display_size.value)
rotation = kwargs.pop('rotation', DEFAULT_ROTATION)
zoom_level = kwargs.pop('zoom', DEFAULT_ZOOM_LEVEL)
rotation = int(kwargs.pop('rotation', DEFAULT_ROTATION) or DEFAULT_ROTATION)
zoom_level = int(kwargs.pop('zoom', DEFAULT_ZOOM_LEVEL) or DEFAULT_ZOOM_LEVEL)
if zoom_level < setting_zoom_min_level.value:
zoom_level = setting_zoom_min_level.value

View File

@@ -2,66 +2,181 @@ from __future__ import unicode_literals
from rest_framework import serializers
from .models import (Document, DocumentVersion, DocumentPage, DocumentType,
RecentDocument)
from .settings import setting_language, setting_language_choices
from common.models import SharedUploadedFile
from .literals import DOCUMENT_IMAGE_TASK_TIMEOUT
from .models import (
Document, DocumentVersion, DocumentPage, DocumentType, RecentDocument
)
from .settings import setting_language
from .tasks import task_get_document_page_image, task_upload_new_version
class DocumentPageImageSerializer(serializers.Serializer):
data = serializers.SerializerMethodField()
def get_data(self, instance):
request = self.context['request']
size = request.GET.get('size')
zoom = request.GET.get('zoom')
rotation = request.GET.get('rotation')
task = task_get_document_page_image.apply_async(
kwargs=dict(
document_page_id=instance.pk, size=size, zoom=zoom,
rotation=rotation, as_base64=True
)
)
# TODO: prepend 'data:%s;base64,%s' based on format specified in
# async call
return task.get(timeout=DOCUMENT_IMAGE_TASK_TIMEOUT)
class DocumentPageSerializer(serializers.HyperlinkedModelSerializer):
image = serializers.HyperlinkedIdentityField(
view_name='rest_api:documentpage-image'
)
class Meta:
extra_kwargs = {
'url': {'view_name': 'rest_api:documentpage-detail'},
'document_version': {'view_name': 'rest_api:documentversion-detail'}
}
model = DocumentPage
class DocumentVersionSerializer(serializers.HyperlinkedModelSerializer):
pages = DocumentPageSerializer(many=True, required=False, read_only=True)
class Meta:
model = DocumentVersion
read_only_fields = ('document',)
class DocumentImageSerializer(serializers.Serializer):
status = serializers.CharField()
data = serializers.CharField()
class DocumentTypeSerializer(serializers.ModelSerializer):
documents = serializers.SerializerMethodField('get_documents_count')
class Meta:
model = DocumentType
fields = ('id', 'name', 'documents')
class DocumentTypeSerializer(serializers.HyperlinkedModelSerializer):
documents = serializers.HyperlinkedIdentityField(
view_name='rest_api:documenttype-document-list',
)
documents_count = serializers.SerializerMethodField()
def get_documents_count(self, obj):
return obj.documents.count()
class DocumentSerializer(serializers.ModelSerializer):
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'
class Meta:
extra_kwargs = {
'url': {'view_name': 'rest_api:documenttype-detail'},
}
fields = (
'delete_time_period', 'delete_time_unit', 'documents',
'documents_count', 'id', 'label', 'trash_time_period',
'trash_time_unit', 'url'
)
document_type = DocumentTypeSerializer()
model = DocumentType
class DocumentVersionSerializer(serializers.HyperlinkedModelSerializer):
pages = DocumentPageSerializer(many=True, required=False, read_only=True)
revert = serializers.HyperlinkedIdentityField(view_name='rest_api:documentversion-revert')
class Meta:
extra_kwargs = {
'document': {'view_name': 'rest_api:document-detail'},
'file': {'use_url': False},
'url': {'view_name': 'rest_api:documentversion-detail'},
}
model = DocumentVersion
read_only_fields = ('document', 'file')
class DocumentVersionRevertSerializer(DocumentVersionSerializer):
class Meta(DocumentVersionSerializer.Meta):
read_only_fields = ('comment', 'document',)
class NewDocumentVersionSerializer(serializers.Serializer):
comment = serializers.CharField(allow_blank=True)
file = serializers.FileField(use_url=False)
def save(self, document, _user):
shared_uploaded_file = SharedUploadedFile.objects.create(
file=self.validated_data['file']
)
task_upload_new_version.delay(
comment=self.validated_data.get('comment', ''),
document_id=document.pk,
shared_uploaded_file_id=shared_uploaded_file.pk, user_id=_user.pk
)
class DeletedDocumentSerializer(serializers.HyperlinkedModelSerializer):
document_type_label = serializers.SerializerMethodField()
restore = serializers.HyperlinkedIdentityField(view_name='rest_api:deleteddocument-restore')
def get_document_type_label(self, instance):
return instance.document_type.label
class Meta:
extra_kwargs = {
'document_type': {'view_name': 'rest_api:documenttype-detail'},
'url': {'view_name': 'rest_api:deleteddocument-detail'}
}
fields = (
'id', 'label', 'image', 'new_version', 'uuid', 'document_type',
'description', 'date_added', 'versions'
'date_added', 'deleted_date_time', 'description', 'document_type',
'document_type_label', 'id', 'label', 'language', 'restore',
'url', 'uuid',
)
model = Document
read_only_fields = (
'deleted_date_time', 'description', 'document_type', 'label',
'language'
)
class DocumentSerializer(serializers.HyperlinkedModelSerializer):
document_type_label = serializers.SerializerMethodField()
latest_version = DocumentVersionSerializer(many=False, read_only=True)
versions = serializers.HyperlinkedIdentityField(
view_name='rest_api:document-version-list',
)
def get_document_type_label(self, instance):
return instance.document_type.label
class Meta:
extra_kwargs = {
'document_type': {'view_name': 'rest_api:documenttype-detail'},
'url': {'view_name': 'rest_api:document-detail'}
}
fields = (
'date_added', 'description', 'document_type', 'document_type_label',
'id', 'label', 'language', 'latest_version', 'url', 'uuid',
'versions',
)
model = Document
class NewDocumentSerializer(serializers.Serializer):
description = serializers.CharField(required=False)
document_type = serializers.IntegerField()
file = serializers.FileField()
label = serializers.CharField(required=False)
language = serializers.ChoiceField(
blank_display_value=None, choices=setting_language_choices.value,
default=setting_language.value, required=False
class NewDocumentSerializer(serializers.ModelSerializer):
file = serializers.FileField(write_only=True)
def save(self, _user):
document = Document.objects.create(
description=self.validated_data.get('description', ''),
document_type=self.validated_data['document_type'],
label=self.validated_data.get('label', unicode(self.validated_data['file'])),
language=self.validated_data.get('language', setting_language.value)
)
document.save(_user=_user)
shared_uploaded_file = SharedUploadedFile.objects.create(
file=self.validated_data['file']
)
task_upload_new_version.delay(
document_id=document.pk,
shared_uploaded_file_id=shared_uploaded_file.pk, user_id=_user.pk
)
self.instance = document
return document
class Meta:
fields = (
'description', 'document_type', 'id', 'file', 'label', 'language',
)
model = Document
class RecentDocumentSerializer(serializers.ModelSerializer):

View File

@@ -181,7 +181,7 @@ def task_upload_new_version(self, document_id, shared_uploaded_file_id, user_id,
with shared_file.open() as file_object:
document_version = DocumentVersion(
document=document, comment=comment, file=file_object
document=document, comment=comment or '', file=file_object
)
try:
document_version.save(_user=user)

View File

@@ -5,25 +5,23 @@ from __future__ import unicode_literals
from json import loads
from django.contrib.auth.models import User
from django.core.files import File
from django.core.urlresolvers import reverse
from django.test import TestCase
from rest_framework import status
from rest_framework.test import APIClient
from rest_framework.test import APITestCase
from .models import Document, DocumentType
from .test_models import (
TEST_ADMIN_PASSWORD, TEST_ADMIN_USERNAME, TEST_ADMIN_EMAIL,
TEST_SMALL_DOCUMENT_FILENAME, TEST_DOCUMENT_PATH,
TEST_SMALL_DOCUMENT_PATH,
TEST_DOCUMENT_TYPE
TEST_ADMIN_EMAIL, TEST_ADMIN_PASSWORD, TEST_ADMIN_USERNAME,
TEST_DOCUMENT_FILENAME, TEST_DOCUMENT_PATH, TEST_DOCUMENT_TYPE,
TEST_SMALL_DOCUMENT_FILENAME, TEST_SMALL_DOCUMENT_PATH,
)
class DocumentAPICreateDocumentTestCase(TestCase):
class DocumentTypeAPITestCase(APITestCase):
"""
Functional test to make sure all the moving parts to create a document
from the API are working correctly
Test the document type API endpoints
"""
def setUp(self):
@@ -31,6 +29,65 @@ class DocumentAPICreateDocumentTestCase(TestCase):
username=TEST_ADMIN_USERNAME, email=TEST_ADMIN_EMAIL,
password=TEST_ADMIN_PASSWORD
)
self.client.force_authenticate(user=self.admin_user)
def testDown(self):
self.admin_user.delete()
def test_document_type_create(self):
self.assertEqual(DocumentType.objects.all().count(), 0)
self.client.post(reverse('rest_api:documenttype-list'), {'label': TEST_DOCUMENT_TYPE})
self.assertEqual(DocumentType.objects.all().count(), 1)
self.assertEqual(DocumentType.objects.all().first().label, TEST_DOCUMENT_TYPE)
def test_document_type_edit_via_put(self):
document_type = DocumentType.objects.create(label=TEST_DOCUMENT_TYPE)
self.client.put(
reverse('rest_api:documenttype-detail', args=[document_type.pk]),
{'label': TEST_DOCUMENT_TYPE + 'edited'}
)
document_type = DocumentType.objects.get(pk=document_type.pk)
self.assertEqual(document_type.label, TEST_DOCUMENT_TYPE + 'edited')
def test_document_type_edit_via_patch(self):
document_type = DocumentType.objects.create(label=TEST_DOCUMENT_TYPE)
self.client.patch(
reverse('rest_api:documenttype-detail', args=[document_type.pk]),
{'label': TEST_DOCUMENT_TYPE + 'edited'}
)
document_type = DocumentType.objects.get(pk=document_type.pk)
self.assertEqual(document_type.label, TEST_DOCUMENT_TYPE + 'edited')
def test_document_type_delete(self):
document_type = DocumentType.objects.create(label=TEST_DOCUMENT_TYPE)
self.client.delete(
reverse('rest_api:documenttype-detail', args=(document_type.pk,))
)
self.assertEqual(DocumentType.objects.all().count(), 0)
class DocumentAPITestCase(APITestCase):
"""
Test document API endpoints
"""
def setUp(self):
self.admin_user = User.objects.create_superuser(
username=TEST_ADMIN_USERNAME, email=TEST_ADMIN_EMAIL,
password=TEST_ADMIN_PASSWORD
)
self.client.force_authenticate(user=self.admin_user)
self.document_type = DocumentType.objects.create(
label=TEST_DOCUMENT_TYPE
)
@@ -40,90 +97,133 @@ class DocumentAPICreateDocumentTestCase(TestCase):
ocr_settings.save()
def tearDown(self):
self.document_type.delete()
self.admin_user.delete()
self.document_type.delete()
def test_uploading_a_document_using_token_auth(self):
# Get the an user token
token_client = APIClient()
response = token_client.post(
reverse('auth_token_obtain'), {
'username': TEST_ADMIN_USERNAME,
'password': TEST_ADMIN_PASSWORD
}
)
# Be able to get authentication token
self.assertEqual(response.status_code, status.HTTP_200_OK)
# Make sure a token was returned
self.assertTrue('token' in response.content)
token = loads(response.content)['token']
# Create a new client to simulate a different request
document_client = APIClient()
# Create a blank document with no token in the header
# TODO: Fix, must not be able to create the document with API token
# with open(TEST_SMALL_DOCUMENT_PATH) as file_descriptor:
# response = document_client.post(reverse('document-list'), {'document_type': self.document_type.pk, 'file': file_descriptor})
# Make sure toke authentication is working, should fail
# TODO: FIX failing test: self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
document_client.credentials(HTTP_AUTHORIZATION='Token ' + token)
# Create a blank document
with open(TEST_SMALL_DOCUMENT_PATH) as file_descriptor:
document_response = document_client.post(
reverse('document-list'), {
def test_document_upload(self):
with open(TEST_DOCUMENT_PATH) as file_descriptor:
document_response = self.client.post(
reverse('rest_api:document-list'), {
'document_type': self.document_type.pk,
'file': file_descriptor
}
)
document_data = loads(document_response.content)
self.assertEqual(document_response.status_code, status.HTTP_201_CREATED)
# The document was created in the DB?
self.assertEqual(Document.objects.count(), 1)
new_version_url = reverse(
'document-new-version', args=[Document.objects.first().pk]
)
with open(TEST_DOCUMENT_PATH) as file_descriptor:
response = document_client.post(
new_version_url, {'file': file_descriptor}
)
# Make sure the document uploaded correctly
document = Document.objects.first()
self.assertEqual(document.pk, document_data['id'])
self.assertEqual(document.versions.count(), 1)
self.assertEqual(document.exists(), True)
self.assertEqual(document.size, 272213)
self.assertEqual(document.file_mimetype, 'application/pdf')
self.assertEqual(document.file_mime_encoding, 'binary')
self.assertEqual(document.label, TEST_SMALL_DOCUMENT_FILENAME)
self.assertEqual(document.label, TEST_DOCUMENT_FILENAME)
self.assertEqual(
document.checksum,
'c637ffab6b8bb026ed3784afdb07663fddc60099853fae2be93890852a69ecf3'
)
self.assertEqual(document.page_count, 47)
# Make sure we can edit the document via the API
document_url = reverse(
'document-detail', args=[Document.objects.first().pk]
def test_document_move_to_trash(self):
with open(TEST_SMALL_DOCUMENT_PATH) as file_object:
document = self.document_type.new_document(
file_object=File(file_object),
)
response = document_client.post(
document_url, {'description': 'edited test document'}
)
self.client.delete(reverse('rest_api:document-detail', args=(document.pk,)))
# self.assertTrue(document.description, 'edited test document')
# Make sure we can delete the document via the API
response = document_client.delete(document_url)
# The document was deleted from the the DB?
self.assertEqual(Document.objects.count(), 0)
self.assertEqual(Document.trash.count(), 1)
def test_deleted_document_delete_from_trash(self):
with open(TEST_SMALL_DOCUMENT_PATH) as file_object:
document = self.document_type.new_document(
file_object=File(file_object),
)
document.delete()
self.assertEqual(Document.objects.count(), 0)
self.assertEqual(Document.trash.count(), 1)
self.client.delete(reverse('rest_api:deleteddocument-detail', args=(document.pk,)))
self.assertEqual(Document.trash.count(), 0)
def test_deleted_document_restore(self):
with open(TEST_SMALL_DOCUMENT_PATH) as file_object:
document = self.document_type.new_document(
file_object=File(file_object),
)
document.delete()
self.client.post(reverse('rest_api:deleteddocument-restore', args=(document.pk,)))
self.assertEqual(Document.trash.count(), 0)
self.assertEqual(Document.objects.count(), 1)
def test_document_new_version_upload(self):
with open(TEST_SMALL_DOCUMENT_PATH) as file_object:
document = self.document_type.new_document(
file_object=File(file_object),
)
with open(TEST_DOCUMENT_PATH) as file_descriptor:
response = self.client.post(
reverse(
'rest_api:document-version-list', args=(document.pk,)
), {
'comment': '',
'file': file_descriptor,
}
)
print response
self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED)
self.assertEqual(document.versions.count(), 2)
self.assertEqual(document.exists(), True)
self.assertEqual(document.size, 272213)
self.assertEqual(document.file_mimetype, 'application/pdf')
self.assertEqual(document.file_mime_encoding, 'binary')
self.assertEqual(
document.checksum,
'c637ffab6b8bb026ed3784afdb07663fddc60099853fae2be93890852a69ecf3'
)
self.assertEqual(document.page_count, 47)
def test_document_version_revert(self):
with open(TEST_SMALL_DOCUMENT_PATH) as file_object:
document = self.document_type.new_document(
file_object=File(file_object),
)
with open(TEST_DOCUMENT_PATH) as file_object:
document.new_version(file_object=File(file_object))
document_version = document.versions.first()
self.assertEqual(document.versions.count(), 2)
self.client.post(
reverse(
'rest_api:documentversion-revert', args=(document_version.pk,)
)
)
self.assertEqual(document.versions.count(), 1)
self.assertEqual(document_version, document.latest_version)
#def test_document_set_document_type(self):
# pass

View File

@@ -18,8 +18,9 @@ TEST_SMALL_DOCUMENT_FILENAME = 'title_page.png'
TEST_MULTI_PAGE_TIFF = 'multi_page.tiff'
TEST_NON_ASCII_DOCUMENT_FILENAME = 'I18N_title_áéíóúüñÑ.png'
TEST_NON_ASCII_COMPRESSED_DOCUMENT_FILENAME = 'I18N_title_áéíóúüñÑ.png.zip'
TEST_DOCUMENT_FILENAME = 'mayan_11_1.pdf'
TEST_DOCUMENT_PATH = os.path.join(
settings.BASE_DIR, 'contrib', 'sample_documents', 'mayan_11_1.pdf'
settings.BASE_DIR, 'contrib', 'sample_documents', TEST_DOCUMENT_FILENAME
)
TEST_SMALL_DOCUMENT_PATH = os.path.join(
settings.BASE_DIR, 'contrib', 'sample_documents',

View File

@@ -3,10 +3,12 @@ from __future__ import unicode_literals
from django.conf.urls import patterns, url
from .api_views import (
APIDocumentView, APIDocumentImageView, APIDocumentListView,
APIDocumentPageView, APIDocumentTypeDocumentListView,
APIDocumentTypeListView, APIDocumentTypeView,
APIDocumentVersionCreateView, APIDocumentVersionView,
APIDeletedDocumentListView, APIDeletedDocumentRestoreView,
APIDeletedDocumentView, APIDocumentView, APIDocumentListView,
APIDocumentPageImageView, APIDocumentPageView,
APIDocumentTypeDocumentListView, APIDocumentTypeListView,
APIDocumentTypeView, APIDocumentVersionsListView,
APIDocumentVersionRevertView, APIDocumentVersionView,
APIRecentDocumentListView
)
from .settings import setting_print_size, setting_display_size
@@ -229,6 +231,18 @@ urlpatterns = patterns(
api_urls = patterns(
'',
url(
r'^deleted_documents/$', APIDeletedDocumentListView.as_view(),
name='deleteddocument-list'
),
url(
r'^deleted_documents/(?P<pk>[0-9]+)/$',
APIDeletedDocumentView.as_view(), name='deleteddocument-detail'
),
url(
r'^deleted_documents/(?P<pk>[0-9]+)/restore/$',
APIDeletedDocumentRestoreView.as_view(), name='deleteddocument-restore'
),
url(r'^documents/$', APIDocumentListView.as_view(), name='document-list'),
url(
r'^documents/recent/$', APIRecentDocumentListView.as_view(),
@@ -238,33 +252,37 @@ api_urls = patterns(
r'^documents/(?P<pk>[0-9]+)/$', APIDocumentView.as_view(),
name='document-detail'
),
url(
r'^documents/(?P<pk>[0-9]+)/versions/$',
APIDocumentVersionsListView.as_view(), name='document-version-list'
),
url(
r'^document_version/(?P<pk>[0-9]+)/$',
APIDocumentVersionView.as_view(), name='documentversion-detail'
),
url(
r'^document_version/(?P<pk>[0-9]+)/revert/$',
APIDocumentVersionRevertView.as_view(), name='documentversion-revert'
),
url(
r'^document_page/(?P<pk>[0-9]+)/$', APIDocumentPageView.as_view(),
name='documentpage-detail'
),
url(
r'^documents/(?P<pk>[0-9]+)/image/$', APIDocumentImageView.as_view(),
name='document-image'
r'^document_page/(?P<pk>[0-9]+)/image/$',
APIDocumentPageImageView.as_view(), name='documentpage-image'
),
url(
r'^documents/(?P<pk>[0-9]+)/new_version/$',
APIDocumentVersionCreateView.as_view(), name='document-new-version'
),
url(
r'^documenttypes/(?P<pk>[0-9]+)/documents/$',
r'^document_types/(?P<pk>[0-9]+)/documents/$',
APIDocumentTypeDocumentListView.as_view(),
name='documenttype-document-list'
),
url(
r'^documenttypes/(?P<pk>[0-9]+)/$', APIDocumentTypeView.as_view(),
r'^document_types/(?P<pk>[0-9]+)/$', APIDocumentTypeView.as_view(),
name='documenttype-detail'
),
url(
r'^documenttypes/$', APIDocumentTypeListView.as_view(),
r'^document_types/$', APIDocumentTypeListView.as_view(),
name='documenttype-list'
),
)

View File

@@ -99,11 +99,12 @@ def document_html_widget(document_page, click_view=None, click_view_arguments=No
alt_text = _('Document page image')
if not document_page:
return mark_safe('<span class="fa-stack fa-lg"><i class="fa fa-file-o fa-stack-2x"></i><i class="fa fa-question fa-stack-1x text-danger"></i></span>')
document = document_page.document
page = document_page.page_number
query_dict = {
'page': page,
'zoom': zoom,
'rotation': rotation,
'size': size,
@@ -117,12 +118,12 @@ def document_html_widget(document_page, click_view=None, click_view_arguments=No
query_string = urlencode(query_dict)
preview_view = '%s?%s' % (
reverse('document-image', args=[document.pk]), query_string
reverse('rest_api:documentpage-image', args=[document_page.pk]), query_string
)
result.append(
'<div class="tc" id="document-%d-%d">' % (
document.pk, page if page else 1
document.pk, document_page.page_number if document_page.page_number else 1
)
)

View File

@@ -17,7 +17,7 @@ class DynamicSearchApp(MayanAppConfig):
def ready(self):
super(DynamicSearchApp, self).ready()
APIEndPoint('search', app_name='dynamic_search')
APIEndPoint(app=self, version_string='1')
menu_facet.bind_links(
links=(link_search, link_search_advanced),

View File

@@ -35,7 +35,7 @@ class FoldersApp(MayanAppConfig):
def ready(self):
super(FoldersApp, self).ready()
APIEndPoint('folders')
APIEndPoint(app=self, version_string='1')
ModelPermission.register(
model=Document, permissions=(
@@ -52,6 +52,11 @@ class FoldersApp(MayanAppConfig):
)
)
SourceColumn(
source=Folder, label=_('Created'), attribute='datetime_created'
)
SourceColumn(source=Folder, label=_('User'), attribute='user')
menu_facet.bind_links(
links=(link_document_folder_list,), sources=(Document,)
)
@@ -79,8 +84,3 @@ class FoldersApp(MayanAppConfig):
'folders:document_folder_list', 'folders:folder_add_document'
)
)
SourceColumn(
source=Folder, label=_('Created'), attribute='datetime_created'
)
SourceColumn(source=Folder, label=_('User'), attribute='user')

View File

@@ -54,7 +54,7 @@ class MetadataApp(MayanAppConfig):
def ready(self):
super(MetadataApp, self).ready()
APIEndPoint('metadata')
APIEndPoint(app=self, version_string='1')
Document.add_to_class(
'metadata_value_of', DocumentMetadataHelper.constructor

View File

@@ -55,7 +55,7 @@ class OCRApp(MayanAppConfig):
def ready(self):
super(OCRApp, self).ready()
APIEndPoint('ocr')
APIEndPoint(app=self, version_string='1')
Document.add_to_class('submit_for_ocr', document_ocr_submit)
DocumentVersion.add_to_class(

View File

@@ -24,7 +24,7 @@ class PermissionsApp(MayanAppConfig):
def ready(self):
super(PermissionsApp, self).ready()
APIEndPoint('permissions')
APIEndPoint(app=self, version_string='1')
menu_object.bind_links(
links=(

View File

@@ -45,7 +45,7 @@ class SourcesApp(MayanAppConfig):
def ready(self):
super(SourcesApp, self).ready()
APIEndPoint('sources')
APIEndPoint(app=self, version_string='1')
MissingItem(
label=_('Create a document source'),

View File

@@ -36,7 +36,7 @@ class TagsApp(MayanAppConfig):
def ready(self):
super(TagsApp, self).ready()
APIEndPoint('tags')
APIEndPoint(app=self, version_string='1')
ModelPermission.register(
model=Document, permissions=(

View File

@@ -28,7 +28,7 @@ class UserManagementApp(MayanAppConfig):
def ready(self):
super(UserManagementApp, self).ready()
APIEndPoint('users', app_name='user_management')
APIEndPoint(app=self, version_string='1')
MetadataLookup(description=_('All the groups.'), name='group', value=Group.objects.all())
MetadataLookup(description=_('All the users.'), name='users', value=get_user_model().objects.all())

View File

@@ -16,10 +16,10 @@ django-filetransfers==0.1.0
django-pagination==1.0.7
django-model-utils==2.2
django-mptt==0.7.4
django-rest-swagger==0.2.0
django-rest-swagger==0.3.3
django-suit==0.2.13
django-widget-tweaks==1.3
djangorestframework==2.4.4
djangorestframework==3.1.3
fusepy==2.0.2