Update documents app

Rename the DeletedDocument proxy model to a TrashedDocument.

Rename the deleted_document views to trashed_document.

Rename the document and deleted_document URL parameters to
trashed_document.

Update URL parameters to the '_id' form.

Add keyword arguments.

Update use of .filter_by_access().

Enclose trashed document restore method in a transaction.

Sort arguments.

Update app for compliance with MERCs 5 and 6.

Add document page view tests.

Add favorite document view tests.

Movernize tests.

Replace use of urlencode with furl.

Update views to use ExternalObjectMixin.

Refactor the document and version download views.

Rename the DocumentDocumentTypeEditView to DocumentChangeTypeView.

Move the trashed document views to their own module.

Signed-off-by: Roberto Rosario <Roberto.Rosario@mayan-edms.com>
This commit is contained in:
Roberto Rosario
2019-01-28 05:25:48 -04:00
parent 7532429b0b
commit 74dfa53787
40 changed files with 1914 additions and 1615 deletions
+10 -10
View File
@@ -3,8 +3,8 @@ from __future__ import unicode_literals
from django.contrib import admin from django.contrib import admin
from .models import ( from .models import (
DeletedDocument, Document, DocumentPage, DocumentType, Document, DocumentPage, DocumentType, DocumentTypeFilename, DocumentVersion,
DocumentTypeFilename, DocumentVersion, DuplicatedDocument, RecentDocument DuplicatedDocument, RecentDocument, TrashedDocument
) )
@@ -29,14 +29,6 @@ class DocumentVersionInline(admin.StackedInline):
allow_add = True allow_add = True
@admin.register(DeletedDocument)
class DeletedDocumentAdmin(admin.ModelAdmin):
date_hierarchy = 'deleted_date_time'
list_filter = ('document_type',)
list_display = ('uuid', 'label', 'document_type', 'deleted_date_time')
readonly_fields = ('uuid', 'document_type')
@admin.register(Document) @admin.register(Document)
class DocumentAdmin(admin.ModelAdmin): class DocumentAdmin(admin.ModelAdmin):
date_hierarchy = 'date_added' date_hierarchy = 'date_added'
@@ -69,3 +61,11 @@ class RecentDocumentAdmin(admin.ModelAdmin):
list_display_links = ('document', 'datetime_accessed') list_display_links = ('document', 'datetime_accessed')
list_filter = ('user',) list_filter = ('user',)
readonly_fields = ('user', 'document', 'datetime_accessed') readonly_fields = ('user', 'document', 'datetime_accessed')
@admin.register(TrashedDocument)
class TrashedDocumentAdmin(admin.ModelAdmin):
date_hierarchy = 'deleted_date_time'
list_filter = ('document_type',)
list_display = ('uuid', 'label', 'document_type', 'deleted_date_time')
readonly_fields = ('uuid', 'document_type')
+199 -37
View File
@@ -9,7 +9,7 @@ from django.shortcuts import get_object_or_404
from django.views.decorators.cache import cache_control, patch_cache_control from django.views.decorators.cache import cache_control, patch_cache_control
from django_downloadview import DownloadMixin, VirtualFile from django_downloadview import DownloadMixin, VirtualFile
from rest_framework import generics, status from rest_framework import generics, status, viewsets
from rest_framework.response import Response from rest_framework.response import Response
from mayan.apps.acls.models import AccessControlList from mayan.apps.acls.models import AccessControlList
@@ -17,12 +17,12 @@ from mayan.apps.rest_api.filters import MayanObjectPermissionsFilter
from mayan.apps.rest_api.permissions import MayanPermission from mayan.apps.rest_api.permissions import MayanPermission
from .literals import DOCUMENT_IMAGE_TASK_TIMEOUT from .literals import DOCUMENT_IMAGE_TASK_TIMEOUT
from .models import Document, DocumentType, RecentDocument from .models import Document, DocumentVersion, DocumentType, RecentDocument
from .permissions import ( from .permissions import (
permission_document_create, permission_document_delete, permission_document_create, permission_trashed_document_delete,
permission_document_download, permission_document_edit, permission_document_download, permission_document_edit,
permission_document_new_version, permission_document_properties_edit, permission_document_new_version, permission_document_properties_edit,
permission_document_restore, permission_document_trash, permission_trashed_document_restore, permission_document_trash,
permission_document_type_create, permission_document_type_delete, permission_document_type_create, permission_document_type_delete,
permission_document_type_edit, permission_document_type_view, permission_document_type_edit, permission_document_type_view,
permission_document_version_revert, permission_document_version_view, permission_document_version_revert, permission_document_version_view,
@@ -30,10 +30,11 @@ from .permissions import (
) )
from .serializers import ( from .serializers import (
DeletedDocumentSerializer, DocumentPageSerializer, DocumentSerializer, DeletedDocumentSerializer, DocumentPageSerializer, DocumentSerializer,
DocumentTypeSerializer, DocumentVersionSerializer, NewDocumentSerializer, DocumentTypeSerializer, DocumentVersionSerializer,# NewDocumentSerializer,
NewDocumentVersionSerializer, RecentDocumentSerializer, #NewDocumentVersionSerializer, RecentDocumentSerializer,
WritableDocumentSerializer, WritableDocumentTypeSerializer, RecentDocumentSerializer,
WritableDocumentVersionSerializer #WritableDocumentSerializer, WritableDocumentTypeSerializer,
#WritableDocumentVersionSerializer
) )
from .settings import settings_document_page_image_cache_time from .settings import settings_document_page_image_cache_time
from .tasks import task_generate_document_page_image from .tasks import task_generate_document_page_image
@@ -41,12 +42,172 @@ from .tasks import task_generate_document_page_image
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
from rest_framework.decorators import action, detail_route
from rest_framework.response import Response
class DocumentViewSet(viewsets.ModelViewSet):
lookup_field = 'pk'
lookup_url_kwarg = 'document_id'
queryset = Document.objects.all()
serializer_class = DocumentSerializer
"""
@action(
detail=True, lookup_field='pk', lookup_url_kwarg='document_id',
url_name='document-version-list', url_path='document_versions'
)
def document_version_list(self, request, *args, **kwargs):
serializer = DocumentVersionSerializer(
instance=self.get_object().versions.all(), many=True,
context={'request': request}
)
return Response(serializer.data)
"""
class DocumentPageViewSet(viewsets.ModelViewSet):
lookup_field = 'pk'
lookup_url_kwarg = 'document_page_id'
serializer_class = DocumentPageSerializer
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, lookup_field='pk', lookup_url_kwarg='document_page_id',
url_name='image', url_path='image'
)
@cache_control(private=True)
def document_page_image(self, request, *args, **kwargs):
"""
asdasd
"""
transformation_dict = {
'kwargs': {},
'name': {}
}
transformation_list = []
querystring = furl()
querystring.args.update(self.request.GET)
querystring.args.update(self.request.POST)
for key, value in querystring.args.items():
if key.startswith('transformation_'):
literal, index, element = key.split('_')
transformation_dict[element][index] = value
for order, identifier in transformation_dict['name'].items():
if order in transformation_dict['kwargs'].keys():
kwargs = {}
for kwargs_entry in transformation_dict['kwargs'][order].split(','):
key, value = kwargs_entry.split(':')
kwargs[key] = float(value)
transformation_list.append({
'name': identifier,
'kwargs': kwargs
})
width = request.GET.get('width')
height = request.GET.get('height')
zoom = request.GET.get('zoom')
if zoom:
zoom = int(zoom)
rotation = request.GET.get('rotation')
if rotation:
rotation = int(rotation)
task = task_generate_document_page_image.apply_async(
kwargs=dict(
document_page_id=self.get_object().pk, width=width,
height=height, zoom=zoom, rotation=rotation,
transformation_list=transformation_list
)
)
cache_filename = task.get(timeout=DOCUMENT_IMAGE_TASK_TIMEOUT)
with self.get_object().cache_partition.get_file(filename=cache_filename).open() as file_object:
response = HttpResponse(file_object.read(), content_type='image')
if '_hash' in request.GET:
patch_cache_control(
response,
max_age=settings_document_page_image_cache_time.value
)
return response
"""
@action(
detail=True, lookup_field='pk', lookup_url_kwarg='document_page_id',
url_name='document-page-list', url_path='document_pages'
)
def document_page_list(self, request, *args, **kwargs):
serializer = DocumentPageSerializer(
instance=self.get_object().versions.all(), many=True,
context={'request': request}
)
return Response(serializer.data)
"""
class DocumentTypeViewSet(viewsets.ModelViewSet):
lookup_field = 'pk'
lookup_url_kwarg = 'document_type_id'
queryset = DocumentType.objects.all()
serializer_class = DocumentTypeSerializer
@action(
detail=True, lookup_field='pk', lookup_url_kwarg='document_type_id',
url_name='document-list', url_path='documents'
)
def document_list(self, request, *args, **kwargs):
serializer = DocumentSerializer(
instance=self.get_object().documents.all(), many=True,
context={'request': request}
)
return Response(serializer.data)
class DocumentVersionViewSet(viewsets.ModelViewSet):
lookup_field = 'pk'
lookup_url_kwarg = 'document_version_id'
serializer_class = DocumentVersionSerializer
"""
@action(
detail=True, lookup_field='pk', lookup_url_kwarg='document_version_id',
url_name='document-pages-list', url_path='document_pages'
)
def document_pages_list(self, request, *args, **kwargs):
serializer = DocumentPageSerializer(
instance=self.get_object().pages.all(), many=True,
context={'request': request}
)
return Response(serializer.data)
"""
def get_queryset(self):
return get_object_or_404(
klass=Document, pk=self.kwargs['document_id']
).versions.all()
'''
class APIDeletedDocumentListView(generics.ListAPIView): class APIDeletedDocumentListView(generics.ListAPIView):
""" """
Returns a list of all the trashed documents. Returns a list of all the trashed documents.
""" """
filter_backends = (MayanObjectPermissionsFilter,) filter_backends = (MayanObjectPermissionsFilter,)
lookup_url_kwarg = 'document_pk' lookup_url_kwarg = 'document_id'
mayan_object_permissions = {'GET': (permission_document_view,)} mayan_object_permissions = {'GET': (permission_document_view,)}
permission_classes = (MayanPermission,) permission_classes = (MayanPermission,)
queryset = Document.trash.all() queryset = Document.trash.all()
@@ -59,9 +220,9 @@ class APIDeletedDocumentView(generics.RetrieveDestroyAPIView):
delete: Delete the trashed document. delete: Delete the trashed document.
get: Retreive the details of the trashed document. get: Retreive the details of the trashed document.
""" """
lookup_url_kwarg = 'document_pk' lookup_url_kwarg = 'document_id'
mayan_object_permissions = { mayan_object_permissions = {
'DELETE': (permission_document_delete,), 'DELETE': (permission_trashed_document_delete,),
'GET': (permission_document_view,) 'GET': (permission_document_view,)
} }
permission_classes = (MayanPermission,) permission_classes = (MayanPermission,)
@@ -73,9 +234,9 @@ class APIDeletedDocumentRestoreView(generics.GenericAPIView):
""" """
post: Restore a trashed document. post: Restore a trashed document.
""" """
lookup_url_kwarg = 'document_pk' lookup_url_kwarg = 'document_id'
mayan_object_permissions = { mayan_object_permissions = {
'POST': (permission_document_restore,) 'POST': (permission_trashed_document_restore,)
} }
permission_classes = (MayanPermission,) permission_classes = (MayanPermission,)
queryset = Document.trash.all() queryset = Document.trash.all()
@@ -95,7 +256,7 @@ class APIDocumentDownloadView(DownloadMixin, generics.RetrieveAPIView):
""" """
get: Download the latest version of a document. get: Download the latest version of a document.
""" """
lookup_url_kwarg = 'document_pk' lookup_url_kwarg = 'document_id'
mayan_object_permissions = { mayan_object_permissions = {
'GET': (permission_document_download,) 'GET': (permission_document_download,)
} }
@@ -146,7 +307,7 @@ class APIDocumentListView(generics.ListCreateAPIView):
def perform_create(self, serializer): def perform_create(self, serializer):
AccessControlList.objects.check_access( AccessControlList.objects.check_access(
permissions=(permission_document_create,), user=self.request.user, permission=permission_document_create,), user=self.request.user,
obj=serializer.validated_data['document_type'] obj=serializer.validated_data['document_type']
) )
serializer.save(_user=self.request.user) serializer.save(_user=self.request.user)
@@ -156,7 +317,7 @@ class APIDocumentPageImageView(generics.RetrieveAPIView):
""" """
get: Returns an image representation of the selected document. get: Returns an image representation of the selected document.
""" """
lookup_url_kwarg = 'document_page_pk' lookup_url_kwarg = 'document_page_id'
def get_document(self): def get_document(self):
if self.request.method == 'GET': if self.request.method == 'GET':
@@ -165,7 +326,7 @@ class APIDocumentPageImageView(generics.RetrieveAPIView):
permission_required = permission_document_edit permission_required = permission_document_edit
document = get_object_or_404( document = get_object_or_404(
klass=Document.passthrough, pk=self.kwargs['document_pk'] klass=Document.passthrough, pk=self.kwargs['document_id']
) )
AccessControlList.objects.check_access( AccessControlList.objects.check_access(
@@ -175,7 +336,7 @@ class APIDocumentPageImageView(generics.RetrieveAPIView):
def get_document_version(self): def get_document_version(self):
return get_object_or_404( return get_object_or_404(
klass=self.get_document().versions.all(), pk=self.kwargs['document_version_pk'] klass=self.get_document().versions.all(), pk=self.kwargs['document_version_id']
) )
def get_queryset(self): def get_queryset(self):
@@ -253,7 +414,7 @@ class APIDocumentPageView(generics.RetrieveUpdateAPIView):
patch: Edit the selected document page. patch: Edit the selected document page.
put: Edit the selected document page. put: Edit the selected document page.
""" """
lookup_url_kwarg = 'document_page_pk' lookup_url_kwarg = 'document_page_id'
serializer_class = DocumentPageSerializer serializer_class = DocumentPageSerializer
def get_document(self): def get_document(self):
@@ -263,7 +424,7 @@ class APIDocumentPageView(generics.RetrieveUpdateAPIView):
permission_required = permission_document_edit permission_required = permission_document_edit
document = get_object_or_404( document = get_object_or_404(
klass=Document, pk=self.kwargs['document_pk'] klass=Document, pk=self.kwargs['document_id']
) )
AccessControlList.objects.check_access( AccessControlList.objects.check_access(
@@ -274,7 +435,7 @@ class APIDocumentPageView(generics.RetrieveUpdateAPIView):
def get_document_version(self): def get_document_version(self):
return get_object_or_404( return get_object_or_404(
klass=self.get_document().versions.all(), klass=self.get_document().versions.all(),
pk=self.kwargs['document_version_pk'] pk=self.kwargs['document_version_id']
) )
def get_queryset(self): def get_queryset(self):
@@ -287,7 +448,7 @@ class APIDocumentTypeListView(generics.ListCreateAPIView):
post: Create a new document type. post: Create a new document type.
""" """
filter_backends = (MayanObjectPermissionsFilter,) filter_backends = (MayanObjectPermissionsFilter,)
lookup_url_kwarg = 'document_type_pk' lookup_url_kwarg = 'document_type_id'
mayan_object_permissions = {'GET': (permission_document_type_view,)} mayan_object_permissions = {'GET': (permission_document_type_view,)}
mayan_view_permissions = {'POST': (permission_document_type_create,)} mayan_view_permissions = {'POST': (permission_document_type_create,)}
permission_classes = (MayanPermission,) permission_classes = (MayanPermission,)
@@ -314,7 +475,7 @@ class APIDocumentTypeView(generics.RetrieveUpdateDestroyAPIView):
patch: Edit the properties of the selected document type. patch: Edit the properties of the selected document type.
put: Edit the properties of the selected document type. put: Edit the properties of the selected document type.
""" """
lookup_url_kwarg = 'document_type_pk' lookup_url_kwarg = 'document_type_id'
mayan_object_permissions = { mayan_object_permissions = {
'GET': (permission_document_type_view,), 'GET': (permission_document_type_view,),
'PUT': (permission_document_type_edit,), 'PUT': (permission_document_type_edit,),
@@ -342,13 +503,13 @@ class APIDocumentTypeDocumentListView(generics.ListAPIView):
Returns a list of all the documents of a particular document type. Returns a list of all the documents of a particular document type.
""" """
filter_backends = (MayanObjectPermissionsFilter,) filter_backends = (MayanObjectPermissionsFilter,)
lookup_url_kwarg = 'document_type_pk' lookup_url_kwarg = 'document_type_id'
mayan_object_permissions = {'GET': (permission_document_view,)} mayan_object_permissions = {'GET': (permission_document_view,)}
serializer_class = DocumentSerializer serializer_class = DocumentSerializer
def get_queryset(self): def get_queryset(self):
document_type = get_object_or_404( document_type = get_object_or_404(
klass=DocumentType, pk=self.kwargs['document_type_pk'] klass=DocumentType, pk=self.kwargs['document_type_id']
) )
AccessControlList.objects.check_access( AccessControlList.objects.check_access(
permissions=permission_document_type_view, user=self.request.user, permissions=permission_document_type_view, user=self.request.user,
@@ -362,15 +523,15 @@ class APIDocumentVersionDownloadView(DownloadMixin, generics.RetrieveAPIView):
""" """
get: Download a document version. get: Download a document version.
""" """
lookup_url_kwarg = 'document_version_pk' lookup_url_kwarg = 'document_version_id'
def get_document(self): def get_document(self):
document = get_object_or_404( document = get_object_or_404(
klass=Document, pk=self.kwargs['document_pk'] klass=Document, pk=self.kwargs['document_id']
) )
AccessControlList.objects.check_access( AccessControlList.objects.check_access(
permissions=(permission_document_download,), user=self.request.user, permission=permission_document_download,), user=self.request.user,
obj=document obj=document
) )
return document return document
@@ -418,7 +579,7 @@ class APIDocumentView(generics.RetrieveUpdateDestroyAPIView):
patch: Edit the properties of the selected document. patch: Edit the properties of the selected document.
put: Edit the properties of the selected document. put: Edit the properties of the selected document.
""" """
lookup_url_kwarg = 'document_pk' lookup_url_kwarg = 'document_id'
mayan_object_permissions = { mayan_object_permissions = {
'GET': (permission_document_view,), 'GET': (permission_document_view,),
'PUT': (permission_document_properties_edit,), 'PUT': (permission_document_properties_edit,),
@@ -463,7 +624,7 @@ class APIDocumentVersionPageListView(generics.ListAPIView):
def get_document(self): def get_document(self):
document = get_object_or_404( document = get_object_or_404(
klass=Document, pk=self.kwargs['document_pk'] klass=Document, pk=self.kwargs['document_id']
) )
AccessControlList.objects.check_access( AccessControlList.objects.check_access(
@@ -474,7 +635,7 @@ class APIDocumentVersionPageListView(generics.ListAPIView):
def get_document_version(self): def get_document_version(self):
return get_object_or_404( return get_object_or_404(
klass=self.get_document().versions.all(), klass=self.get_document().versions.all(),
pk=self.kwargs['document_version_pk'] pk=self.kwargs['document_version_id']
) )
def get_queryset(self): def get_queryset(self):
@@ -490,7 +651,7 @@ class APIDocumentVersionsListView(generics.ListCreateAPIView):
mayan_object_permissions = { mayan_object_permissions = {
'GET': (permission_document_version_view,), 'GET': (permission_document_version_view,),
} }
mayan_permission_attribute_check = 'document' #mayan_permission_attribute_check = 'document'
permission_classes = (MayanPermission,) permission_classes = (MayanPermission,)
def create(self, request, *args, **kwargs): def create(self, request, *args, **kwargs):
@@ -514,16 +675,16 @@ class APIDocumentVersionsListView(generics.ListCreateAPIView):
def get_queryset(self): def get_queryset(self):
return get_object_or_404( return get_object_or_404(
klass=Document, pk=self.kwargs['document_pk'] klass=Document, pk=self.kwargs['document_id']
).versions.all() ).versions.all()
def perform_create(self, serializer): def perform_create(self, serializer):
document = get_object_or_404( document = get_object_or_404(
klass=Document, pk=self.kwargs['document_pk'] klass=Document, pk=self.kwargs['document_id']
) )
AccessControlList.objects.check_access( AccessControlList.objects.check_access(
permissions=(permission_document_new_version,), permission=permission_document_new_version,),
user=self.request.user, obj=document user=self.request.user, obj=document
) )
serializer.save(document=document, _user=self.request.user) serializer.save(document=document, _user=self.request.user)
@@ -536,7 +697,7 @@ class APIDocumentVersionView(generics.RetrieveUpdateDestroyAPIView):
patch: Edit the selected document version. patch: Edit the selected document version.
put: Edit the selected document version. put: Edit the selected document version.
""" """
lookup_url_kwarg = 'document_version_pk' lookup_url_kwarg = 'document_version_id'
def get_document(self): def get_document(self):
if self.request.method == 'GET': if self.request.method == 'GET':
@@ -547,7 +708,7 @@ class APIDocumentVersionView(generics.RetrieveUpdateDestroyAPIView):
permission_required = permission_document_edit permission_required = permission_document_edit
document = get_object_or_404( document = get_object_or_404(
klass=Document, pk=self.kwargs['document_pk'] klass=Document, pk=self.kwargs['document_id']
) )
AccessControlList.objects.check_access( AccessControlList.objects.check_access(
@@ -569,3 +730,4 @@ class APIDocumentVersionView(generics.RetrieveUpdateDestroyAPIView):
return DocumentVersionSerializer return DocumentVersionSerializer
else: else:
return WritableDocumentVersionSerializer return WritableDocumentVersionSerializer
'''
+44 -38
View File
@@ -53,17 +53,17 @@ from .handlers import (
) )
from .links import ( from .links import (
link_clear_image_cache, link_document_clear_transformations, link_clear_image_cache, link_document_clear_transformations,
link_document_clone_transformations, link_document_delete, link_document_clone_transformations, link_trashed_document_delete,
link_document_document_type_edit, link_document_download, link_document_change_type, link_document_download,
link_document_duplicates_list, link_document_edit, link_document_duplicates_list, link_document_edit,
link_document_favorites_add, link_document_favorites_remove, link_document_favorites_add, link_document_favorites_remove,
link_document_list, link_document_list_deleted, link_document_list, link_trashed_document_list,
link_document_list_favorites, link_document_list_recent_access, link_document_list_favorites, link_document_list_recent_access,
link_document_list_recent_added, link_document_list_recent_added,
link_document_multiple_clear_transformations, link_document_multiple_clear_transformations,
link_document_multiple_delete, link_document_multiple_document_type_edit, link_trashed_document_multiple_delete, link_document_multiple_change_type,
link_document_multiple_download, link_document_multiple_favorites_add, link_document_multiple_download, link_document_multiple_favorites_add,
link_document_multiple_favorites_remove, link_document_multiple_restore, link_document_multiple_favorites_remove, link_trashed_document_multiple_restore,
link_document_multiple_trash, link_document_multiple_update_page_count, link_document_multiple_trash, link_document_multiple_update_page_count,
link_document_page_navigation_first, link_document_page_navigation_last, link_document_page_navigation_first, link_document_page_navigation_last,
link_document_page_navigation_next, link_document_page_navigation_previous, link_document_page_navigation_next, link_document_page_navigation_previous,
@@ -72,7 +72,7 @@ from .links import (
link_document_page_view_reset, link_document_page_zoom_in, link_document_page_view_reset, link_document_page_zoom_in,
link_document_page_zoom_out, link_document_pages, link_document_preview, link_document_page_zoom_out, link_document_pages, link_document_preview,
link_document_print, link_document_properties, link_document_print, link_document_properties,
link_document_quick_download, link_document_restore, link_document_trash, link_document_quick_download, link_trashed_document_restore, link_document_trash,
link_document_type_create, link_document_type_delete, link_document_type_create, link_document_type_delete,
link_document_type_edit, link_document_type_filename_create, link_document_type_edit, link_document_type_filename_create,
link_document_type_filename_delete, link_document_type_filename_edit, link_document_type_filename_delete, link_document_type_filename_edit,
@@ -90,14 +90,14 @@ from .literals import (
) )
from .menus import menu_documents from .menus import menu_documents
from .permissions import ( from .permissions import (
permission_document_create, permission_document_delete, permission_document_create,
permission_document_download, permission_document_edit, permission_document_download, permission_document_edit,
permission_document_new_version, permission_document_print, permission_document_new_version, permission_document_print,
permission_document_properties_edit, permission_document_restore, permission_document_properties_edit, permission_document_trash,
permission_document_trash, permission_document_type_delete, permission_document_type_delete, permission_document_type_edit,
permission_document_type_edit, permission_document_type_view, permission_document_type_view, permission_document_version_revert,
permission_document_version_revert, permission_document_version_view, permission_document_version_view, permission_document_view,
permission_document_view permission_trashed_document_delete, permission_trashed_document_restore
) )
from .queues import * # NOQA from .queues import * # NOQA
# Just import to initialize the search models # Just import to initialize the search models
@@ -119,14 +119,18 @@ class DocumentsApp(MayanAppConfig):
super(DocumentsApp, self).ready() super(DocumentsApp, self).ready()
from actstream import registry from actstream import registry
DeletedDocument = self.get_model('DeletedDocument') Document = self.get_model(model_name='Document')
Document = self.get_model('Document') DocumentPage = self.get_model(model_name='DocumentPage')
DocumentPage = self.get_model('DocumentPage') DocumentPageSearchResult = self.get_model(
DocumentPageSearchResult = self.get_model('DocumentPageSearchResult') model_name='DocumentPageSearchResult'
DocumentType = self.get_model('DocumentType') )
DocumentTypeFilename = self.get_model('DocumentTypeFilename') DocumentType = self.get_model(model_name='DocumentType')
DocumentVersion = self.get_model('DocumentVersion') DocumentTypeFilename = self.get_model(model_name='DocumentTypeFilename')
DuplicatedDocumentProxy = self.get_model('DuplicatedDocumentProxy') DocumentVersion = self.get_model(model_name='DocumentVersion')
DuplicatedDocumentProxy = self.get_model(
model_name='DuplicatedDocumentProxy'
)
TrashedDocument = self.get_model(model_name='TrashedDocument')
DynamicSerializerField.add_serializer( DynamicSerializerField.add_serializer(
klass=Document, klass=Document,
@@ -185,15 +189,16 @@ class DocumentsApp(MayanAppConfig):
ModelPermission.register( ModelPermission.register(
model=Document, permissions=( model=Document, permissions=(
permission_acl_edit, permission_acl_view, permission_acl_edit, permission_acl_view,
permission_document_delete, permission_document_download, permission_document_download, permission_document_edit,
permission_document_edit, permission_document_new_version, permission_document_new_version, permission_document_print,
permission_document_print, permission_document_properties_edit, permission_document_properties_edit, permission_document_trash,
permission_document_restore, permission_document_trash,
permission_document_version_revert, permission_document_version_revert,
permission_document_version_view, permission_document_view, permission_document_version_view, permission_document_view,
permission_events_view, permission_transformation_create, permission_events_view, permission_transformation_create,
permission_transformation_delete, permission_transformation_delete,
permission_transformation_edit, permission_transformation_view, permission_transformation_edit, permission_transformation_view,
permission_trashed_document_delete,
permission_trashed_document_restore
) )
) )
@@ -297,22 +302,22 @@ class DocumentsApp(MayanAppConfig):
widget=TwoStateWidget widget=TwoStateWidget
) )
# DeletedDocument # TrashedDocument
SourceColumn( SourceColumn(
attribute='label', is_identifier=True, is_sortable=True, attribute='label', is_identifier=True, is_sortable=True,
source=DeletedDocument source=TrashedDocument
) )
SourceColumn( SourceColumn(
func=lambda context: document_page_thumbnail_widget.render( func=lambda context: document_page_thumbnail_widget.render(
instance=context['object'] instance=context['object']
), label=_('Thumbnail'), source=DeletedDocument ), label=_('Thumbnail'), source=TrashedDocument
) )
SourceColumn( SourceColumn(
attribute='document_type', is_sortable=True, source=DeletedDocument attribute='document_type', is_sortable=True, source=TrashedDocument
) )
SourceColumn( SourceColumn(
attribute='get_rendered_deleted_date_time', source=DeletedDocument attribute='get_rendered_deleted_date_time', source=TrashedDocument
) )
# DocumentVersion # DocumentVersion
@@ -445,7 +450,7 @@ class DocumentsApp(MayanAppConfig):
links=( links=(
link_document_list_recent_access, link_document_list_recent_access,
link_document_list_recent_added, link_document_list_favorites, link_document_list_recent_added, link_document_list_favorites,
link_document_list, link_document_list_deleted, link_document_list, link_trashed_document_list,
link_duplicated_document_list, link_duplicated_document_list,
) )
) )
@@ -493,7 +498,7 @@ class DocumentsApp(MayanAppConfig):
menu_sidebar.bind_links( menu_sidebar.bind_links(
links=(link_trash_can_empty,), links=(link_trash_can_empty,),
sources=( sources=(
'documents:document_list_deleted', 'documents:trash_can_empty' 'documents:trashed_document_list', 'documents:trash_can_empty'
) )
) )
@@ -501,7 +506,7 @@ class DocumentsApp(MayanAppConfig):
menu_object.bind_links( menu_object.bind_links(
links=( links=(
link_document_favorites_add, link_document_favorites_remove, link_document_favorites_add, link_document_favorites_remove,
link_document_edit, link_document_document_type_edit, link_document_edit, link_document_change_type,
link_document_print, link_document_trash, link_document_print, link_document_trash,
link_document_quick_download, link_document_download, link_document_quick_download, link_document_download,
link_document_clear_transformations, link_document_clear_transformations,
@@ -510,8 +515,8 @@ class DocumentsApp(MayanAppConfig):
), sources=(Document,) ), sources=(Document,)
) )
menu_object.bind_links( menu_object.bind_links(
links=(link_document_restore, link_document_delete), links=(link_trashed_document_restore, link_trashed_document_delete),
sources=(DeletedDocument,) sources=(TrashedDocument,)
) )
# Document facet links # Document facet links
@@ -548,13 +553,14 @@ class DocumentsApp(MayanAppConfig):
link_document_multiple_clear_transformations, link_document_multiple_clear_transformations,
link_document_multiple_trash, link_document_multiple_download, link_document_multiple_trash, link_document_multiple_download,
link_document_multiple_update_page_count, link_document_multiple_update_page_count,
link_document_multiple_document_type_edit, link_document_multiple_change_type,
), sources=(Document,) ), sources=(Document,)
) )
menu_multi_item.bind_links( menu_multi_item.bind_links(
links=( links=(
link_document_multiple_restore, link_document_multiple_delete link_trashed_document_multiple_restore,
), sources=(DeletedDocument,) link_trashed_document_multiple_delete
), sources=(TrashedDocument,)
) )
# Document pages # Document pages
@@ -614,7 +620,7 @@ class DocumentsApp(MayanAppConfig):
receiver=handler_scan_duplicates_for, receiver=handler_scan_duplicates_for,
) )
registry.register(DeletedDocument) registry.register(TrashedDocument)
registry.register(Document) registry.register(Document)
registry.register(DocumentType) registry.register(DocumentType)
registry.register(DocumentVersion) registry.register(DocumentVersion)
+35 -23
View File
@@ -32,17 +32,19 @@ class DashboardWidgetDocumentPagesTotal(DashboardWidgetNumeric):
DocumentPage = apps.get_model( DocumentPage = apps.get_model(
app_label='documents', model_name='DocumentPage' app_label='documents', model_name='DocumentPage'
) )
self.count = AccessControlList.objects.filter_by_access( self.count = AccessControlList.objects.restrict_queryset(
permission=permission_document_view, user=request.user, permission=permission_document_view,
queryset=DocumentPage.objects.all() queryset=DocumentPage.objects.all(), user=request.user
).count() ).count()
return super(DashboardWidgetDocumentPagesTotal, self).render(request) return super(DashboardWidgetDocumentPagesTotal, self).render(
request=request
)
class DashboardWidgetDocumentsTotal(DashboardWidgetNumeric): class DashboardWidgetDocumentsTotal(DashboardWidgetNumeric):
icon_class = icon_dashboard_total_document icon_class = icon_dashboard_total_document
label = _('Total documents') label = _('Total documents')
link = reverse_lazy('documents:document_list') link = reverse_lazy(viewname='documents:document_list')
def render(self, request): def render(self, request):
AccessControlList = apps.get_model( AccessControlList = apps.get_model(
@@ -51,36 +53,40 @@ class DashboardWidgetDocumentsTotal(DashboardWidgetNumeric):
Document = apps.get_model( Document = apps.get_model(
app_label='documents', model_name='Document' app_label='documents', model_name='Document'
) )
self.count = AccessControlList.objects.filter_by_access( self.count = AccessControlList.objects.restrict_queryset(
permission=permission_document_view, user=request.user, permission=permission_document_view,
queryset=Document.objects.all() queryset=Document.objects.all(), user=request.user
).count() ).count()
return super(DashboardWidgetDocumentsTotal, self).render(request) return super(DashboardWidgetDocumentsTotal, self).render(
request=request
)
class DashboardWidgetDocumentsInTrash(DashboardWidgetNumeric): class DashboardWidgetDocumentsInTrash(DashboardWidgetNumeric):
icon_class = icon_dashboard_documents_in_trash icon_class = icon_dashboard_documents_in_trash
label = _('Documents in trash') label = _('Documents in trash')
link = reverse_lazy('documents:document_list_deleted') link = reverse_lazy(viewname='documents:trashed_document_list')
def render(self, request): def render(self, request):
AccessControlList = apps.get_model( AccessControlList = apps.get_model(
app_label='acls', model_name='AccessControlList' app_label='acls', model_name='AccessControlList'
) )
DeletedDocument = apps.get_model( TrashedDocument = apps.get_model(
app_label='documents', model_name='DeletedDocument' app_label='documents', model_name='TrashedDocument'
) )
self.count = AccessControlList.objects.filter_by_access( self.count = AccessControlList.objects.restrict_queryset(
permission=permission_document_view, user=request.user, permission=permission_document_view,
queryset=DeletedDocument.objects.all() queryset=TrashedDocument.objects.all(), user=request.user
).count() ).count()
return super(DashboardWidgetDocumentsInTrash, self).render(request) return super(DashboardWidgetDocumentsInTrash, self).render(
request=request
)
class DashboardWidgetDocumentsTypesTotal(DashboardWidgetNumeric): class DashboardWidgetDocumentsTypesTotal(DashboardWidgetNumeric):
icon_class = icon_dashboard_document_types icon_class = icon_dashboard_document_types
label = _('Document types') label = _('Document types')
link = reverse_lazy('documents:document_type_list') link = reverse_lazy(viewname='documents:document_type_list')
def render(self, request): def render(self, request):
AccessControlList = apps.get_model( AccessControlList = apps.get_model(
@@ -89,11 +95,13 @@ class DashboardWidgetDocumentsTypesTotal(DashboardWidgetNumeric):
DocumentType = apps.get_model( DocumentType = apps.get_model(
app_label='documents', model_name='DocumentType' app_label='documents', model_name='DocumentType'
) )
self.count = AccessControlList.objects.filter_by_access( self.count = AccessControlList.objects.restrict_queryset(
permission=permission_document_type_view, user=request.user, permission=permission_document_type_view,
queryset=DocumentType.objects.all() queryset=DocumentType.objects.all(), user=request.user
).count() ).count()
return super(DashboardWidgetDocumentsTypesTotal, self).render(request) return super(DashboardWidgetDocumentsTypesTotal, self).render(
request=request
)
class DashboardWidgetDocumentsNewThisMonth(DashboardWidgetNumeric): class DashboardWidgetDocumentsNewThisMonth(DashboardWidgetNumeric):
@@ -106,7 +114,9 @@ class DashboardWidgetDocumentsNewThisMonth(DashboardWidgetNumeric):
def render(self, request): def render(self, request):
self.count = new_documents_this_month(user=request.user) self.count = new_documents_this_month(user=request.user)
return super(DashboardWidgetDocumentsNewThisMonth, self).render(request) return super(DashboardWidgetDocumentsNewThisMonth, self).render(
request=request
)
class DashboardWidgetDocumentsPagesNewThisMonth(DashboardWidgetNumeric): class DashboardWidgetDocumentsPagesNewThisMonth(DashboardWidgetNumeric):
@@ -119,4 +129,6 @@ class DashboardWidgetDocumentsPagesNewThisMonth(DashboardWidgetNumeric):
def render(self, request): def render(self, request):
self.count = new_document_pages_this_month(user=request.user) self.count = new_document_pages_this_month(user=request.user)
return super(DashboardWidgetDocumentsPagesNewThisMonth, self).render(request) return super(DashboardWidgetDocumentsPagesNewThisMonth, self).render(
request=request
)
+10 -10
View File
@@ -4,35 +4,35 @@ from django.utils.translation import ugettext_lazy as _
from mayan.apps.events import EventTypeNamespace from mayan.apps.events import EventTypeNamespace
namespace = EventTypeNamespace(name='documents', label=_('Documents')) namespace = EventTypeNamespace(label=_('Documents'), name='documents')
event_document_create = namespace.add_event_type( event_document_create = namespace.add_event_type(
name='document_create', label=_('Document created') label=_('Document created'), name='document_create'
) )
event_document_download = namespace.add_event_type( event_document_download = namespace.add_event_type(
name='document_download', label=_('Document downloaded') label=_('Document downloaded'), name='document_download'
) )
event_document_new_version = namespace.add_event_type( event_document_new_version = namespace.add_event_type(
name='document_new_version', label=_('New version uploaded') label=_('New version uploaded'), name='document_new_version'
) )
event_document_properties_edit = namespace.add_event_type( event_document_properties_edit = namespace.add_event_type(
name='document_edit', label=_('Document properties edited') label=_('Document properties edited'), name='document_edit'
) )
# The type of an existing document is changed to another type # The type of an existing document is changed to another type
event_document_type_change = namespace.add_event_type( event_document_type_change = namespace.add_event_type(
name='document_type_change', label=_('Document type changed') label=_('Document type changed'), name='document_type_change'
) )
# A document type is created # A document type is created
event_document_type_created = namespace.add_event_type( event_document_type_created = namespace.add_event_type(
name='document_type_created', label=_('Document type created') label=_('Document type created'), name='document_type_created'
) )
# An existing document type is modified # An existing document type is modified
event_document_type_edited = namespace.add_event_type( event_document_type_edited = namespace.add_event_type(
name='document_type_edit', label=_('Document type edited') label=_('Document type edited'), name='document_type_edit'
) )
event_document_version_revert = namespace.add_event_type( event_document_version_revert = namespace.add_event_type(
name='document_version_revert', label=_('Document version reverted') label=_('Document version reverted'), name='document_version_revert'
) )
event_document_view = namespace.add_event_type( event_document_view = namespace.add_event_type(
name='document_view', label=_('Document viewed') label=_('Document viewed'), name='document_view'
) )
@@ -45,7 +45,7 @@ class DocumentTypeFilteredSelectForm(forms.Form):
queryset = DocumentType.objects.all() queryset = DocumentType.objects.all()
if permission: if permission:
queryset = AccessControlList.objects.filter_by_access( queryset = AccessControlList.objects.restrict_queryset(
permission=permission, queryset=queryset, user=user permission=permission, queryset=queryset, user=user
) )
+15 -13
View File
@@ -18,9 +18,6 @@ icon_dashboard_new_documents_this_month = Icon(
icon_dashboard_total_document = Icon( icon_dashboard_total_document = Icon(
driver_name='fontawesome', symbol='file' driver_name='fontawesome', symbol='file'
) )
icon_document_delete = Icon(
driver_name='fontawesome', symbol='times'
)
icon_document_download = Icon( icon_document_download = Icon(
driver_name='fontawesome', symbol='download' driver_name='fontawesome', symbol='download'
) )
@@ -42,9 +39,6 @@ icon_document_image_loading = Icon(
driver_name='fontawesomecss', css_classes='far fa-clock fa-2x' driver_name='fontawesomecss', css_classes='far fa-clock fa-2x'
) )
icon_document_list = Icon(driver_name='fontawesome', symbol='book') icon_document_list = Icon(driver_name='fontawesome', symbol='book')
icon_document_list_deleted = Icon(
driver_name='fontawesome', symbol='trash-alt'
)
icon_document_list_favorites = Icon(driver_name='fontawesome', symbol='star') icon_document_list_favorites = Icon(driver_name='fontawesome', symbol='star')
icon_document_list_recent_access = Icon( icon_document_list_recent_access = Icon(
driver_name='fontawesome', symbol='clock' driver_name='fontawesome', symbol='clock'
@@ -52,12 +46,6 @@ icon_document_list_recent_access = Icon(
icon_document_list_recent_added = Icon( icon_document_list_recent_added = Icon(
driver_name='fontawesome', symbol='asterisk' driver_name='fontawesome', symbol='asterisk'
) )
icon_document_multiple_delete = Icon(
driver_name='fontawesome', symbol='trash-alt'
)
icon_document_multiepl_restore = Icon(
driver_name='fontawesome', symbol='recycle'
)
icon_document_page_navigation_first = Icon( icon_document_page_navigation_first = Icon(
driver_name='fontawesome', symbol='step-backward' driver_name='fontawesome', symbol='step-backward'
) )
@@ -95,7 +83,6 @@ icon_document_print = Icon(
driver_name='fontawesome', symbol='print' driver_name='fontawesome', symbol='print'
) )
icon_document_properties = Icon(driver_name='fontawesome', symbol='info') icon_document_properties = Icon(driver_name='fontawesome', symbol='info')
icon_document_restore = Icon(driver_name='fontawesome', symbol='recycle')
icon_document_trash = Icon( icon_document_trash = Icon(
driver_name='fontawesome', symbol='trash-alt' driver_name='fontawesome', symbol='trash-alt'
) )
@@ -141,3 +128,18 @@ icon_menu_documents = Icon(driver_name='fontawesome', symbol='book')
icon_trash_can_empty = Icon( icon_trash_can_empty = Icon(
driver_name='fontawesome', symbol='trash-alt' driver_name='fontawesome', symbol='trash-alt'
) )
icon_trashed_document_delete = Icon(
driver_name='fontawesome', symbol='times'
)
icon_trashed_document_list = Icon(
driver_name='fontawesome', symbol='trash-alt'
)
icon_trashed_document_multiple_delete = Icon(
driver_name='fontawesome', symbol='trash-alt'
)
icon_trashed_document_multiple_restore = Icon(
driver_name='fontawesome', symbol='recycle'
)
icon_trashed_document_restore = Icon(
driver_name='fontawesome', symbol='recycle'
)
+124 -89
View File
@@ -9,19 +9,18 @@ from mayan.apps.navigation import Link
from .icons import ( from .icons import (
icon_clear_image_cache, icon_document_duplicates_list, icon_document_list, icon_clear_image_cache, icon_document_duplicates_list, icon_document_list,
icon_document_list_deleted, icon_document_list_favorites, icon_document_list_favorites,
icon_document_list_recent_access, icon_document_list_recent_added, icon_document_list_recent_access, icon_document_list_recent_added,
icon_document_delete, icon_document_download, icon_document_edit, icon_trashed_document_delete, icon_document_download, icon_document_edit,
icon_document_favorites_add, icon_document_favorites_remove, icon_document_favorites_add, icon_document_favorites_remove,
icon_document_multiple_delete, icon_document_page_navigation_first,
icon_document_multiple_restore, icon_document_page_navigation_first,
icon_document_page_navigation_last, icon_document_page_navigation_last,
icon_document_page_navigation_next, icon_document_page_navigation_previous, icon_document_page_navigation_next, icon_document_page_navigation_previous,
icon_document_page_return, icon_document_page_rotate_left, icon_document_page_return, icon_document_page_rotate_left,
icon_document_page_rotate_right, icon_document_page_view, icon_document_page_rotate_right, icon_document_page_view,
icon_document_page_view_reset, icon_document_page_zoom_in, icon_document_page_view_reset, icon_document_page_zoom_in,
icon_document_page_zoom_out, icon_document_pages, icon_document_preview, icon_document_page_zoom_out, icon_document_pages, icon_document_preview,
icon_document_print, icon_document_properties, icon_document_restore, icon_document_print, icon_document_properties, icon_trashed_document_restore,
icon_document_trash, icon_document_type_create, icon_document_trash, icon_document_type_create,
icon_document_type_delete, icon_document_type_edit, icon_document_type_delete, icon_document_type_edit,
icon_document_type_filename, icon_document_type_filename_create, icon_document_type_filename, icon_document_type_filename_create,
@@ -30,17 +29,20 @@ from .icons import (
icon_document_version_list, icon_document_version_return_document, icon_document_version_list, icon_document_version_return_document,
icon_document_version_return_list, icon_document_version_view, icon_document_version_return_list, icon_document_version_view,
icon_duplicated_document_list, icon_duplicated_document_scan, icon_duplicated_document_list, icon_duplicated_document_scan,
icon_trash_can_empty icon_trash_can_empty,
icon_trashed_document_list,
icon_trashed_document_multiple_delete,
icon_trashed_document_multiple_restore,
) )
from .permissions import ( from .permissions import (
permission_document_delete, permission_document_download, permission_document_download, permission_document_print,
permission_document_print, permission_document_properties_edit, permission_document_properties_edit, permission_document_tools,
permission_document_restore, permission_document_tools,
permission_document_trash, permission_document_type_create, permission_document_trash, permission_document_type_create,
permission_document_type_delete, permission_document_type_edit, permission_document_type_delete, permission_document_type_edit,
permission_document_type_view, permission_document_version_revert, permission_document_type_view, permission_document_version_revert,
permission_document_version_view, permission_document_view, permission_document_version_view, permission_document_view,
permission_empty_trash permission_empty_trash, permission_trashed_document_delete,
permission_trashed_document_restore
) )
from .settings import setting_zoom_max_level, setting_zoom_min_level from .settings import setting_zoom_max_level, setting_zoom_min_level
@@ -74,22 +76,26 @@ def is_min_zoom(context):
# Facet # Facet
link_document_preview = Link( link_document_preview = Link(
args='resolved_object.id', icon_class=icon_document_preview, icon_class=icon_document_preview,
kwargs={'document_id': 'resolved_object.id'},
permission=permission_document_view, text=_('Preview'), permission=permission_document_view, text=_('Preview'),
view='documents:document_preview' view='documents:document_preview'
) )
link_document_properties = Link( link_document_properties = Link(
args='resolved_object.id', icon_class=icon_document_properties, icon_class=icon_document_properties,
kwargs={'document_id': 'resolved_object.id'},
permission=permission_document_view, text=_('Properties'), permission=permission_document_view, text=_('Properties'),
view='documents:document_properties' view='documents:document_properties'
) )
link_document_version_list = Link( link_document_version_list = Link(
args='resolved_object.pk', icon_class=icon_document_version_list, icon_class=icon_document_version_list,
kwargs={'document_id': 'resolved_object.id'},
permission=permission_document_version_view, text=_('Versions'), permission=permission_document_version_view, text=_('Versions'),
view='documents:document_version_list' view='documents:document_version_list'
) )
link_document_pages = Link( link_document_pages = Link(
args='resolved_object.pk', icon_class=icon_document_pages, icon_class=icon_document_pages,
kwargs={'document_id': 'resolved_object.id'},
permission=permission_document_view, text=_('Pages'), permission=permission_document_view, text=_('Pages'),
view='documents:document_pages' view='documents:document_pages'
) )
@@ -97,68 +103,68 @@ link_document_pages = Link(
# Actions # Actions
link_document_clear_transformations = Link( link_document_clear_transformations = Link(
args='resolved_object.id', permission=permission_transformation_delete, args='resolved_object.id', permission=permission_transformation_delete,
kwargs={'document_id': 'resolved_object.id'},
text=_('Clear transformations'), text=_('Clear transformations'),
view='documents:document_clear_transformations' view='documents:document_clear_transformations'
) )
link_document_clone_transformations = Link( link_document_clone_transformations = Link(
args='resolved_object.id', permission=permission_transformation_edit, permission=permission_transformation_edit,
kwargs={'document_id': 'resolved_object.id'},
text=_('Clone transformations'), text=_('Clone transformations'),
view='documents:document_clone_transformations' view='documents:document_clone_transformations'
) )
link_document_delete = Link(
args='resolved_object.id', icon_class=icon_document_delete,
permission=permission_document_delete, tags='dangerous',
text=_('Delete'), view='documents:document_delete'
)
link_document_favorites_add = Link( link_document_favorites_add = Link(
args='resolved_object.id', icon_class=icon_document_favorites_add, icon_class=icon_document_favorites_add,
kwargs={'document_id': 'resolved_object.id'},
permission=permission_document_view, text=_('Add to favorites'), permission=permission_document_view, text=_('Add to favorites'),
view='documents:document_add_to_favorites' view='documents:document_add_to_favorites'
) )
link_document_favorites_remove = Link( link_document_favorites_remove = Link(
args='resolved_object.id', icon_class=icon_document_favorites_remove, icon_class=icon_document_favorites_remove,
kwargs={'document_id': 'resolved_object.id'},
permission=permission_document_view, text=_('Remove from favorites'), permission=permission_document_view, text=_('Remove from favorites'),
view='documents:document_remove_from_favorites' view='documents:document_remove_from_favorites'
) )
link_document_trash = Link( link_document_trash = Link(
args='resolved_object.id', icon_class=icon_document_trash, icon_class=icon_document_trash,
kwargs={'document_id': 'resolved_object.id'},
permission=permission_document_trash, tags='dangerous', permission=permission_document_trash, tags='dangerous',
text=_('Move to trash'), view='documents:document_trash' text=_('Move to trash'), view='documents:document_trash'
) )
link_document_edit = Link( link_document_edit = Link(
args='resolved_object.id', icon_class=icon_document_edit, icon_class=icon_document_edit,
kwargs={'document_id': 'resolved_object.id'},
permission=permission_document_properties_edit, permission=permission_document_properties_edit,
text=_('Edit properties'), view='documents:document_edit' text=_('Edit properties'), view='documents:document_edit'
) )
link_document_document_type_edit = Link( link_document_change_type = Link(
args='resolved_object.id', kwargs={'document_id': 'resolved_object.id'},
permission=permission_document_properties_edit, text=_('Change type'), permission=permission_document_properties_edit, text=_('Change type'),
view='documents:document_document_type_edit' view='documents:document_change_type'
) )
link_document_download = Link( link_document_download = Link(
args='resolved_object.id', icon_class=icon_document_download, icon_class=icon_document_download,
kwargs={'document_id': 'resolved_object.id'},
permission=permission_document_download, text=_('Advanced download'), permission=permission_document_download, text=_('Advanced download'),
view='documents:document_download_form' view='documents:document_download_form'
) )
link_document_print = Link( link_document_print = Link(
args='resolved_object.id', icon_class=icon_document_print, icon_class=icon_document_print,
kwargs={'document_id': 'resolved_object.id'},
permission=permission_document_print, text=_('Print'), permission=permission_document_print, text=_('Print'),
view='documents:document_print' view='documents:document_print'
) )
link_document_quick_download = Link( link_document_quick_download = Link(
args='resolved_object.id', permission=permission_document_download, permission=permission_document_download,
kwargs={'document_id': 'resolved_object.id'},
text=_('Quick download'), view='documents:document_download' text=_('Quick download'), view='documents:document_download'
) )
link_document_update_page_count = Link( link_document_update_page_count = Link(
args='resolved_object.pk', permission=permission_document_tools, kwargs={'document_id': 'resolved_object.id'},
permission=permission_document_tools,
text=_('Recalculate page count'), text=_('Recalculate page count'),
view='documents:document_update_page_count' view='documents:document_update_page_count'
) )
link_document_restore = Link(
args='object.pk', icon_class=icon_document_restore,
permission=permission_document_restore, text=_('Restore'),
view='documents:document_restore'
)
link_document_multiple_clear_transformations = Link( link_document_multiple_clear_transformations = Link(
permission=permission_transformation_delete, permission=permission_transformation_delete,
text=_('Clear transformations'), text=_('Clear transformations'),
@@ -168,10 +174,6 @@ link_document_multiple_trash = Link(
tags='dangerous', text=_('Move to trash'), tags='dangerous', text=_('Move to trash'),
view='documents:document_multiple_trash' view='documents:document_multiple_trash'
) )
link_document_multiple_delete = Link(
icon_class=icon_document_multiple_delete, tags='dangerous',
text=_('Delete'), view='documents:document_multiple_delete'
)
link_document_multiple_favorites_add = Link( link_document_multiple_favorites_add = Link(
text=_('Add to favorites'), text=_('Add to favorites'),
view='documents:document_multiple_add_to_favorites' view='documents:document_multiple_add_to_favorites'
@@ -180,9 +182,9 @@ link_document_multiple_favorites_remove = Link(
text=_('Remove from favorites'), text=_('Remove from favorites'),
view='documents:document_multiple_remove_from_favorites' view='documents:document_multiple_remove_from_favorites'
) )
link_document_multiple_document_type_edit = Link( link_document_multiple_change_type = Link(
text=_('Change type'), text=_('Change type'),
view='documents:document_multiple_document_type_edit' view='documents:document_multiple_change_type'
) )
link_document_multiple_download = Link( link_document_multiple_download = Link(
text=_('Advanced download'), text=_('Advanced download'),
@@ -192,31 +194,54 @@ link_document_multiple_update_page_count = Link(
text=_('Recalculate page count'), text=_('Recalculate page count'),
view='documents:document_multiple_update_page_count' view='documents:document_multiple_update_page_count'
) )
link_document_multiple_restore = Link(
icon_class=icon_document_multiple_restore, text=_('Restore'), link_trashed_document_delete = Link(
view='documents:document_multiple_restore' icon_class=icon_trashed_document_delete,
kwargs={'trashed_document_id': 'resolved_object.id'},
permission=permission_trashed_document_delete, tags='dangerous',
text=_('Delete'), view='documents:trashed_document_delete'
)
link_trashed_document_list = Link(
icon_class=icon_trashed_document_list, text=_('Trash can'),
view='documents:trashed_document_list'
)
link_trashed_document_restore = Link(
icon_class=icon_trashed_document_restore,
kwargs={'trashed_document_id': 'resolved_object.id'},
permission=permission_trashed_document_restore, text=_('Restore'),
view='documents:trashed_document_restore'
)
link_trashed_document_multiple_delete = Link(
icon_class=icon_trashed_document_multiple_delete, tags='dangerous',
text=_('Delete'), view='documents:trashed_document_multiple_delete'
)
link_trashed_document_multiple_restore = Link(
icon_class=icon_trashed_document_multiple_restore, text=_('Restore'),
view='documents:trashed_document_multiple_restore'
) )
# Versions # Versions
link_document_version_download = Link( link_document_version_download = Link(
args='resolved_object.pk', icon_class=icon_document_version_download, icon_class=icon_document_version_download,
kwargs={'document_version_id': 'resolved_object.pk'},
permission=permission_document_download, text=_('Download version'), permission=permission_document_download, text=_('Download version'),
view='documents:document_version_download_form' view='documents:document_version_download_form'
) )
link_document_version_return_document = Link( link_document_version_return_document = Link(
args='resolved_object.document.pk',
icon_class=icon_document_version_return_document, icon_class=icon_document_version_return_document,
kwargs={'document_id': 'resolved_object.document.pk'},
permission=permission_document_view, text=_('Document'), permission=permission_document_view, text=_('Document'),
view='documents:document_preview' view='documents:document_preview'
) )
link_document_version_return_list = Link( link_document_version_return_list = Link(
args='resolved_object.document.pk',
icon_class=icon_document_version_return_list, icon_class=icon_document_version_return_list,
kwargs={'document_id': 'resolved_object.document.pk'},
permission=permission_document_version_view, text=_('Versions'), permission=permission_document_version_view, text=_('Versions'),
view='documents:document_version_list' view='documents:document_version_list'
) )
link_document_version_view = Link( link_document_version_view = Link(
args='resolved_object.pk', icon_class=icon_document_version_view, icon_class=icon_document_version_view,
kwargs={'document_version_id': 'resolved_object.pk'},
permission=permission_document_version_view, text=_('Preview'), permission=permission_document_version_view, text=_('Preview'),
view='documents:document_version_view' view='documents:document_version_view'
) )
@@ -238,10 +263,6 @@ link_document_list_recent_added = Link(
icon_class=icon_document_list_recent_added, text=_('Recently added'), icon_class=icon_document_list_recent_added, text=_('Recently added'),
view='documents:document_list_recent_added' view='documents:document_list_recent_added'
) )
link_document_list_deleted = Link(
icon_class=icon_document_list_deleted, text=_('Trash can'),
view='documents:document_list_deleted'
)
# Tools # Tools
link_clear_image_cache = Link( link_clear_image_cache = Link(
@@ -260,73 +281,80 @@ link_trash_can_empty = Link(
# Document pages # Document pages
link_document_page_navigation_first = Link( link_document_page_navigation_first = Link(
args='resolved_object.pk', conditional_disable=is_first_page, conditional_disable=is_first_page,
icon_class=icon_document_page_navigation_first, icon_class=icon_document_page_navigation_first, keep_query=True,
keep_query=True, permission=permission_document_view, kwargs={'document_page_id': 'resolved_object.pk'},
text=_('First page'), view='documents:document_page_navigation_first' permission=permission_document_view, text=_('First page'),
view='documents:document_page_navigation_first'
) )
link_document_page_navigation_last = Link( link_document_page_navigation_last = Link(
args='resolved_object.pk', conditional_disable=is_last_page, conditional_disable=is_last_page,
icon_class=icon_document_page_navigation_last, icon_class=icon_document_page_navigation_last, keep_query=True,
keep_query=True, text=_('Last page'), kwargs={'document_page_id': 'resolved_object.pk'},
permission=permission_document_view, permission=permission_document_view, text=_('Last page'),
view='documents:document_page_navigation_last' view='documents:document_page_navigation_last'
) )
link_document_page_navigation_previous = Link( link_document_page_navigation_previous = Link(
args='resolved_object.pk', conditional_disable=is_first_page, conditional_disable=is_first_page,
icon_class=icon_document_page_navigation_previous, icon_class=icon_document_page_navigation_previous, keep_query=True,
keep_query=True, permission=permission_document_view, kwargs={'document_page_id': 'resolved_object.pk'},
text=_('Previous page'), permission=permission_document_view, text=_('Previous page'),
view='documents:document_page_navigation_previous' view='documents:document_page_navigation_previous'
) )
link_document_page_navigation_next = Link( link_document_page_navigation_next = Link(
args='resolved_object.pk', conditional_disable=is_last_page, conditional_disable=is_last_page,
icon_class=icon_document_page_navigation_next, icon_class=icon_document_page_navigation_next, keep_query=True,
keep_query=True, text=_('Next page'), kwargs={'document_page_id': 'resolved_object.pk'}, text=_('Next page'),
permission=permission_document_view, permission=permission_document_view,
view='documents:document_page_navigation_next' view='documents:document_page_navigation_next'
) )
link_document_page_return = Link( link_document_page_return = Link(
args='resolved_object.document.pk', icon_class=icon_document_page_return, icon_class=icon_document_page_return,
kwargs={'document_id': 'resolved_object.document.pk'},
permission=permission_document_view, text=_('Document'), permission=permission_document_view, text=_('Document'),
view='documents:document_preview' view='documents:document_preview'
) )
link_document_page_rotate_left = Link( link_document_page_rotate_left = Link(
args='resolved_object.pk', icon_class=icon_document_page_rotate_left, icon_class=icon_document_page_rotate_left, keep_query=True,
keep_query=True, permission=permission_document_view, kwargs={'document_page_id': 'resolved_object.pk'},
text=_('Rotate left'), view='documents:document_page_rotate_left' permission=permission_document_view, text=_('Rotate left'),
view='documents:document_page_rotate_left'
) )
link_document_page_rotate_right = Link( link_document_page_rotate_right = Link(
args='resolved_object.pk', icon_class=icon_document_page_rotate_right, icon_class=icon_document_page_rotate_right, keep_query=True,
keep_query=True, permission=permission_document_view, kwargs={'document_page_id': 'resolved_object.pk'},
text=_('Rotate right'), view='documents:document_page_rotate_right' permission=permission_document_view, text=_('Rotate right'),
view='documents:document_page_rotate_right'
) )
link_document_page_view = Link( link_document_page_view = Link(
icon_class=icon_document_page_view, icon_class=icon_document_page_view,
kwargs={'document_page_id': 'resolved_object.pk'},
permission=permission_document_view, text=_('Page image'), permission=permission_document_view, text=_('Page image'),
view='documents:document_page_view', args='resolved_object.pk' view='documents:document_page_view'
) )
link_document_page_view_reset = Link( link_document_page_view_reset = Link(
icon_class=icon_document_page_view_reset, icon_class=icon_document_page_view_reset,
kwargs={'document_page_id': 'resolved_object.pk'},
permission=permission_document_view, text=_('Reset view'), permission=permission_document_view, text=_('Reset view'),
view='documents:document_page_view_reset', args='resolved_object.pk' view='documents:document_page_view_reset'
) )
link_document_page_zoom_in = Link( link_document_page_zoom_in = Link(
args='resolved_object.pk', conditional_disable=is_max_zoom, conditional_disable=is_max_zoom, icon_class=icon_document_page_zoom_in,
icon_class=icon_document_page_zoom_in, keep_query=True, keep_query=True, kwargs={'document_page_id': 'resolved_object.pk'},
permission=permission_document_view, text=_('Zoom in'), permission=permission_document_view, text=_('Zoom in'),
view='documents:document_page_zoom_in' view='documents:document_page_zoom_in'
) )
link_document_page_zoom_out = Link( link_document_page_zoom_out = Link(
args='resolved_object.pk', conditional_disable=is_min_zoom, conditional_disable=is_min_zoom, icon_class=icon_document_page_zoom_out,
icon_class=icon_document_page_zoom_out, keep_query=True, keep_query=True, kwargs={'document_page_id': 'resolved_object.pk'},
permission=permission_document_view, text=_('Zoom out'), permission=permission_document_view, text=_('Zoom out'),
view='documents:document_page_zoom_out' view='documents:document_page_zoom_out'
) )
# Document versions # Document versions
link_document_version_revert = Link( link_document_version_revert = Link(
args='object.pk', condition=is_not_current_version, condition=is_not_current_version,
kwargs={'document_version_id': 'object.pk'},
permission=permission_document_version_revert, tags='dangerous', permission=permission_document_version_revert, tags='dangerous',
text=_('Revert'), view='documents:document_version_revert' text=_('Revert'), view='documents:document_version_revert'
) )
@@ -338,32 +366,38 @@ link_document_type_create = Link(
text=_('Create document type'), view='documents:document_type_create' text=_('Create document type'), view='documents:document_type_create'
) )
link_document_type_delete = Link( link_document_type_delete = Link(
args='resolved_object.id', icon_class=icon_document_type_delete, icon_class=icon_document_type_delete,
kwargs={'document_type_id': 'resolved_object.pk'},
permission=permission_document_type_delete, tags='dangerous', permission=permission_document_type_delete, tags='dangerous',
text=_('Delete'), view='documents:document_type_delete' text=_('Delete'), view='documents:document_type_delete'
) )
link_document_type_edit = Link( link_document_type_edit = Link(
args='resolved_object.id', icon_class=icon_document_type_edit, icon_class=icon_document_type_edit,
kwargs={'document_type_id': 'resolved_object.pk'},
permission=permission_document_type_edit, text=_('Edit'), permission=permission_document_type_edit, text=_('Edit'),
view='documents:document_type_edit' view='documents:document_type_edit'
) )
link_document_type_filename_create = Link( link_document_type_filename_create = Link(
args='document_type.id', icon_class=icon_document_type_filename_create, icon_class=icon_document_type_filename_create,
kwargs={'document_type_id': 'resolved_object.pk'},
permission=permission_document_type_edit, permission=permission_document_type_edit,
text=_('Add quick label to document type'), text=_('Add quick label to document type'),
view='documents:document_type_filename_create' view='documents:document_type_filename_create'
) )
link_document_type_filename_delete = Link( link_document_type_filename_delete = Link(
args='resolved_object.id', permission=permission_document_type_edit, kwargs={'filename_id': 'resolved_object.pk'},
permission=permission_document_type_edit,
tags='dangerous', text=_('Delete'), tags='dangerous', text=_('Delete'),
view='documents:document_type_filename_delete' view='documents:document_type_filename_delete'
) )
link_document_type_filename_edit = Link( link_document_type_filename_edit = Link(
args='resolved_object.id', permission=permission_document_type_edit, kwargs={'filename_id': 'resolved_object.pk'},
permission=permission_document_type_edit,
text=_('Edit'), view='documents:document_type_filename_edit' text=_('Edit'), view='documents:document_type_filename_edit'
) )
link_document_type_filename_list = Link( link_document_type_filename_list = Link(
args='resolved_object.id', icon_class=icon_document_type_filename, icon_class=icon_document_type_filename,
kwargs={'document_type_id': 'resolved_object.pk'},
permission=permission_document_type_view, text=_('Quick labels'), permission=permission_document_type_view, text=_('Quick labels'),
view='documents:document_type_filename_list' view='documents:document_type_filename_list'
) )
@@ -382,7 +416,8 @@ link_duplicated_document_list = Link(
view='documents:duplicated_document_list' view='documents:duplicated_document_list'
) )
link_document_duplicates_list = Link( link_document_duplicates_list = Link(
args='resolved_object.id', icon_class=icon_document_duplicates_list, icon_class=icon_document_duplicates_list,
kwargs={'document_id': 'resolved_object.pk'},
permission=permission_document_view, text=_('Duplicates'), permission=permission_document_view, text=_('Duplicates'),
view='documents:document_duplicates_list' view='documents:document_duplicates_list'
) )
+10 -8
View File
@@ -40,7 +40,9 @@ class DocumentPageManager(models.Manager):
except DocumentVersion.DoesNotExist: except DocumentVersion.DoesNotExist:
raise self.model.DoesNotExist raise self.model.DoesNotExist
return self.get(document_version__pk=document_version.pk, page_number=page_number) return self.get(
document_version__id=document_version.pk, page_number=page_number
)
class DocumentTypeManager(models.Manager): class DocumentTypeManager(models.Manager):
@@ -61,13 +63,13 @@ class DocumentTypeManager(models.Manager):
'Document type: %s, has a deletion period delta of: %s', 'Document type: %s, has a deletion period delta of: %s',
document_type, delta document_type, delta
) )
for document in document_type.deleted_documents.filter(deleted_date_time__lt=now() - delta): for trashed_document in document_type.trashed_documents.filter(deleted_date_time__lt=now() - delta):
logger.info( logger.info(
'Document "%s" with id: %d, trashed on: %s, exceded ' 'Document "%s" with id: %d, trashed on: %s, exceded '
'delete period', document, document.pk, 'delete period', trashed_document, trashed_document.pk,
document.deleted_date_time trashed_document.deleted_date_time
) )
document.delete() trashed_document.delete()
else: else:
logger.info( logger.info(
'Document type: %s, has a no retention delta', document_type 'Document type: %s, has a no retention delta', document_type
@@ -120,7 +122,7 @@ class DocumentVersionManager(models.Manager):
except Document.DoesNotExist: except Document.DoesNotExist:
raise self.model.DoesNotExist raise self.model.DoesNotExist
return self.get(document__pk=document.pk, checksum=checksum) return self.get(document__id=document.pk, checksum=checksum)
class DuplicatedDocumentManager(models.Manager): class DuplicatedDocumentManager(models.Manager):
@@ -204,7 +206,7 @@ class FavoriteDocumentManager(models.Manager):
except User.DoesNotExist: except User.DoesNotExist:
raise self.model.DoesNotExist raise self.model.DoesNotExist
return self.get(document__pk=document.pk, user__pk=user.pk) return self.get(document__id=document.pk, user__id=user.pk)
def get_for_user(self, user): def get_for_user(self, user):
Document = apps.get_model( Document = apps.get_model(
@@ -254,7 +256,7 @@ class RecentDocumentManager(models.Manager):
raise self.model.DoesNotExist raise self.model.DoesNotExist
return self.get( return self.get(
document__pk=document.pk, user__pk=user.pk, document__id=document.pk, user__id=user.pk,
datetime_accessed=datetime_accessed datetime_accessed=datetime_accessed
) )
+13 -13
View File
@@ -31,8 +31,8 @@ from ..signals import post_document_type_change
from .document_type_models import DocumentType from .document_type_models import DocumentType
__all__ = ( __all__ = (
'Document', 'DeletedDocument', 'DuplicatedDocument', 'FavoriteDocument', 'Document', 'DuplicatedDocument', 'FavoriteDocument', 'RecentDocument',
'RecentDocument' 'TrashedDocument'
) )
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -137,7 +137,7 @@ class Document(models.Model):
def get_absolute_url(self): def get_absolute_url(self):
return reverse( return reverse(
viewname='documents:document_preview', viewname='documents:document_preview',
kwargs={'document_pk': self.pk} kwargs={'document_id': self.pk}
) )
def get_api_image_url(self, *args, **kwargs): def get_api_image_url(self, *args, **kwargs):
@@ -279,13 +279,6 @@ class Document(models.Model):
return DocumentPage.objects.none() return DocumentPage.objects.none()
class DeletedDocument(Document):
objects = TrashCanManager()
class Meta:
proxy = True
@python_2_unicode_compatible @python_2_unicode_compatible
class DuplicatedDocument(models.Model): class DuplicatedDocument(models.Model):
document = models.ForeignKey( document = models.ForeignKey(
@@ -316,9 +309,9 @@ class DuplicatedDocumentProxy(Document):
verbose_name_plural = _('Duplicated documents') verbose_name_plural = _('Duplicated documents')
def get_duplicate_count(self, user): def get_duplicate_count(self, user):
queryset = AccessControlList.objects.filter_by_access( queryset = AccessControlList.objects.restrict_queryset(
permission=permission_document_view, user=user, permission=permission_document_view, queryset=self.get_duplicates(),
queryset=self.get_duplicates() user=user
) )
return queryset.count() return queryset.count()
@@ -382,3 +375,10 @@ class RecentDocument(models.Model):
def natural_key(self): def natural_key(self):
return (self.datetime_accessed, self.document.natural_key(), self.user.natural_key()) return (self.datetime_accessed, self.document.natural_key(), self.user.natural_key())
natural_key.dependencies = ['documents.Document', settings.AUTH_USER_MODEL] natural_key.dependencies = ['documents.Document', settings.AUTH_USER_MODEL]
class TrashedDocument(Document):
objects = TrashCanManager()
class Meta:
proxy = True
@@ -103,7 +103,7 @@ class DocumentPage(models.Model):
def get_absolute_url(self): def get_absolute_url(self):
return reverse( return reverse(
viewname='documents:document_page_view', viewname='documents:document_page_view',
kwargs={'document_page_pk': self.pk} kwargs={'document_page_id': self.pk}
) )
def get_api_image_url(self, *args, **kwargs): def get_api_image_url(self, *args, **kwargs):
@@ -126,10 +126,10 @@ class DocumentPage(models.Model):
final_url = furl() final_url = furl()
final_url.args = kwargs final_url.args = kwargs
final_url.path = reverse( final_url.path = reverse(
viewname='rest_api:documentpage-image', kwargs={ viewname='rest_api:document_page-image', kwargs={
'document_pk': self.document.pk, 'document_id': self.document.pk,
'document_version_pk': self.document_version.pk, 'document_version_id': self.document_version.pk,
'document_page_pk': self.pk 'document_page_id': self.pk
} }
) )
final_url.args['_hash'] = transformations_hash final_url.args['_hash'] = transformations_hash
@@ -73,23 +73,16 @@ class DocumentType(models.Model):
return super(DocumentType, self).delete(*args, **kwargs) return super(DocumentType, self).delete(*args, **kwargs)
@property
def deleted_documents(self):
DeletedDocument = apps.get_model(
app_label='documents', model_name='DeletedDocument'
)
return DeletedDocument.objects.filter(document_type=self)
def get_absolute_url(self): def get_absolute_url(self):
return reverse( return reverse(
viewname='documents:document_type_document_list', viewname='documents:document_type_document_list',
kwargs={'document_type_pk': self.pk} kwargs={'document_type_id': self.pk}
) )
def get_document_count(self, user): def get_document_count(self, user):
queryset = AccessControlList.objects.filter_by_access( queryset = AccessControlList.objects.restrict_queryset(
permission=permission_document_view, user=user, permission=permission_document_view, queryset=self.documents,
queryset=self.documents user=user
) )
return queryset.count() return queryset.count()
get_document_count.short_description = _('Documents') get_document_count.short_description = _('Documents')
@@ -134,6 +127,13 @@ class DocumentType(models.Model):
return result return result
@property
def trashed_documents(self):
TrashedDocument = apps.get_model(
app_label='documents', model_name='TrashedDocument'
)
return TrashedDocument.objects.filter(document_type=self)
@python_2_unicode_compatible @python_2_unicode_compatible
class DocumentTypeFilename(models.Model): class DocumentTypeFilename(models.Model):
@@ -151,7 +151,7 @@ class DocumentVersion(models.Model):
def get_absolute_url(self): def get_absolute_url(self):
return reverse( return reverse(
viewname='documents:document_version_view', viewname='documents:document_version_view',
kwargs={'document_version_pk': self.pk} kwargs={'document_version_id': self.pk}
) )
def get_api_image_url(self, *args, **kwargs): def get_api_image_url(self, *args, **kwargs):
@@ -195,6 +195,7 @@ class DocumentVersion(models.Model):
filename, self.get_rendered_timestamp(), extension filename, self.get_rendered_timestamp(), extension
) )
else: else:
#TODO: use get_rendered_timestamp here
return Template( return Template(
'{{ instance.document }} - {{ instance.timestamp }}' '{{ instance.document }} - {{ instance.timestamp }}'
).render(context=Context({'instance': self})) ).render(context=Context({'instance': self}))
@@ -205,6 +206,10 @@ class DocumentVersion(models.Model):
) )
get_rendered_timestamp.short_description = _('Date and time') get_rendered_timestamp.short_description = _('Date and time')
@property
def label(self):
return self.get_rendered_string()
def natural_key(self): def natural_key(self):
return (self.checksum, self.document.natural_key()) return (self.checksum, self.document.natural_key())
natural_key.dependencies = ['documents.Document'] natural_key.dependencies = ['documents.Document']
@@ -250,9 +255,19 @@ class DocumentVersion(models.Model):
self.document, self self.document, self
) )
event_document_version_revert.commit(actor=_user, target=self.document) try:
for version in self.document.versions.filter(timestamp__gt=self.timestamp): with transaction.atomic():
version.delete() event_document_version_revert.commit(
actor=_user, target=self.document
)
for version in self.document.versions.filter(timestamp__gt=self.timestamp):
version.delete()
except Exception as exception:
logger.error(
'Error reverting document version for document "%s"; %s',
self.document, exception
)
raise
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
""" """
+24 -24
View File
@@ -7,62 +7,62 @@ from mayan.apps.permissions import PermissionNamespace
namespace = PermissionNamespace(label=_('Documents'), name='documents') namespace = PermissionNamespace(label=_('Documents'), name='documents')
permission_document_create = namespace.add_permission( permission_document_create = namespace.add_permission(
name='document_create', label=_('Create documents') label=_('Create documents'), name='document_create'
)
permission_document_delete = namespace.add_permission(
name='document_delete', label=_('Delete documents')
) )
permission_document_trash = namespace.add_permission( permission_document_trash = namespace.add_permission(
name='document_trash', label=_('Trash documents') label=_('Trash documents'), name='document_trash'
) )
permission_document_download = namespace.add_permission( permission_document_download = namespace.add_permission(
name='document_download', label=_('Download documents') label=_('Download documents'), name='document_download'
) )
permission_document_edit = namespace.add_permission( permission_document_edit = namespace.add_permission(
name='document_edit', label=_('Edit documents') label=_('Edit documents'), name='document_edit'
) )
permission_document_new_version = namespace.add_permission( permission_document_new_version = namespace.add_permission(
name='document_new_version', label=_('Create new document versions') label=_('Create new document versions'), name='document_new_version'
) )
permission_document_properties_edit = namespace.add_permission( permission_document_properties_edit = namespace.add_permission(
name='document_properties_edit', label=_('Edit document properties') label=_('Edit document properties'), name='document_properties_edit'
) )
permission_document_print = namespace.add_permission( permission_document_print = namespace.add_permission(
name='document_print', label=_('Print documents') label=_('Print documents'), name='document_print'
)
permission_document_restore = namespace.add_permission(
name='document_restore', label=_('Restore trashed document')
) )
permission_document_tools = namespace.add_permission( permission_document_tools = namespace.add_permission(
name='document_tools', label=_('Execute document modifying tools') label=_('Execute document modifying tools'), name='document_tools'
) )
permission_document_version_revert = namespace.add_permission( permission_document_version_revert = namespace.add_permission(
name='document_version_revert', label=_('Revert documents to a previous version'),
label=_('Revert documents to a previous version') name='document_version_revert'
) )
permission_document_version_view = namespace.add_permission( permission_document_version_view = namespace.add_permission(
name='document_version_view', label=_('View documents\' versions list'),
label=_('View documents\' versions list') name='document_version_view'
) )
permission_document_view = namespace.add_permission( permission_document_view = namespace.add_permission(
name='document_view', label=_('View documents') label=_('View documents'), name='document_view'
) )
permission_empty_trash = namespace.add_permission( permission_empty_trash = namespace.add_permission(
name='document_empty_trash', label=_('Empty trash') label=_('Empty trash'), name='document_empty_trash'
)
permission_trashed_document_delete = namespace.add_permission(
label=_('Delete trashed documents'), name='document_delete'
)
permission_trashed_document_restore = namespace.add_permission(
label=_('Restore trashed document'), name='document_restore'
) )
setup_namespace = PermissionNamespace( setup_namespace = PermissionNamespace(
label=_('Document types'), name='documents_types' label=_('Document types'), name='documents_types'
) )
permission_document_type_create = setup_namespace.add_permission( permission_document_type_create = setup_namespace.add_permission(
name='document_type_create', label=_('Create document types') label=_('Create document types'), name='document_type_create'
) )
permission_document_type_delete = setup_namespace.add_permission( permission_document_type_delete = setup_namespace.add_permission(
name='document_type_delete', label=_('Delete document types') label=_('Delete document types'), name='document_type_delete'
) )
permission_document_type_edit = setup_namespace.add_permission( permission_document_type_edit = setup_namespace.add_permission(
name='document_type_edit', label=_('Edit document types') label=_('Edit document types'), name='document_type_edit'
) )
permission_document_type_view = setup_namespace.add_permission( permission_document_type_view = setup_namespace.add_permission(
name='document_type_view', label=_('View document types') label=_('View document types'), name='document_type_view'
) )
+22 -22
View File
@@ -6,55 +6,55 @@ from mayan.apps.common.queues import queue_tools
from mayan.apps.task_manager.classes import CeleryQueue from mayan.apps.task_manager.classes import CeleryQueue
queue_converter = CeleryQueue( queue_converter = CeleryQueue(
name='converter', label=_('Converter'), transient=True label=_('Converter'), name='converter', transient=True
) )
queue_documents_periodic = CeleryQueue( queue_documents_periodic = CeleryQueue(
name='documents_periodic', label=_('Documents periodic'), transient=True label=_('Documents periodic'), name='documents_periodic', transient=True
) )
queue_uploads = CeleryQueue( queue_uploads = CeleryQueue(
name='uploads', label=_('Uploads') label=_('Uploads'), name='uploads'
) )
queue_documents = CeleryQueue( queue_documents = CeleryQueue(
name='documents', label=_('Documents') label=_('Documents'), name='documents'
) )
queue_converter.add_task_type( queue_converter.add_task_type(
name='mayan.apps.documents.tasks.task_generate_document_page_image', label=_('Generate document page image'),
label=_('Generate document page image') name='mayan.apps.documents.tasks.task_generate_document_page_image'
) )
queue_documents.add_task_type( queue_documents.add_task_type(
name='mayan.apps.documents.tasks.task_delete_document', label=_('Delete a document'),
label=_('Delete a document') name='mayan.apps.documents.tasks.task_delete_document'
) )
queue_documents.add_task_type( queue_documents.add_task_type(
name='mayan.apps.documents.tasks.task_clean_empty_duplicate_lists', label=_('Clean empty duplicate lists'),
label=_('Clean empty duplicate lists') name='mayan.apps.documents.tasks.task_clean_empty_duplicate_lists'
) )
queue_documents_periodic.add_task_type( queue_documents_periodic.add_task_type(
name='mayan.apps.documents.tasks.task_check_delete_periods', label=_('Check document type delete periods'),
label=_('Check document type delete periods') name='mayan.apps.documents.tasks.task_check_delete_periods'
) )
queue_documents_periodic.add_task_type( queue_documents_periodic.add_task_type(
name='mayan.apps.documents.tasks.task_check_trash_periods', label=_('Check document type trash periods'),
label=_('Check document type trash periods') name='mayan.apps.documents.tasks.task_check_trash_periods'
) )
queue_documents_periodic.add_task_type( queue_documents_periodic.add_task_type(
name='mayan.apps.documents.tasks.task_delete_stubs', label=_('Delete document stubs'),
label=_('Delete document stubs') name='mayan.apps.documents.tasks.task_delete_stubs'
) )
queue_tools.add_task_type( queue_tools.add_task_type(
name='mayan.apps.documents.tasks.task_clear_image_cache', label=_('Clear image cache'),
label=_('Clear image cache') name='mayan.apps.documents.tasks.task_clear_image_cache'
) )
queue_uploads.add_task_type( queue_uploads.add_task_type(
name='mayan.apps.documents.tasks.task_update_page_count', label=_('Update document page count'),
label=_('Update document page count') name='mayan.apps.documents.tasks.task_update_page_count'
) )
queue_uploads.add_task_type( queue_uploads.add_task_type(
name='mayan.apps.documents.tasks.task_upload_new_version', label=_('Upload new document version'),
label=_('Upload new document version') name='mayan.apps.documents.tasks.task_upload_new_version'
) )
+191 -73
View File
@@ -6,6 +6,7 @@ from rest_framework import serializers
from rest_framework.reverse import reverse from rest_framework.reverse import reverse
from mayan.apps.common.models import SharedUploadedFile from mayan.apps.common.models import SharedUploadedFile
from mayan.apps.rest_api.relations import MultiKwargHyperlinkedIdentityField
from .models import ( from .models import (
Document, DocumentPage, DocumentType, DocumentTypeFilename, Document, DocumentPage, DocumentType, DocumentTypeFilename,
@@ -16,40 +17,80 @@ from .tasks import task_upload_new_version
class DocumentPageSerializer(serializers.HyperlinkedModelSerializer): class DocumentPageSerializer(serializers.HyperlinkedModelSerializer):
document_version_url = serializers.SerializerMethodField() #document_versions_url = serializers.SerializerMethodField()
image_url = serializers.SerializerMethodField() image_url = MultiKwargHyperlinkedIdentityField(
url = serializers.SerializerMethodField() view_kwargs=(
{
'lookup_field': 'pk', 'lookup_url_kwarg': 'document_page_id',
},
{
'lookup_field': 'document.pk', 'lookup_url_kwarg': 'document_id',
},
{
'lookup_field': 'document_version_id', 'lookup_url_kwarg': 'document_version_id',
},
),
view_name='rest_api:document_page-image'
)
#url = serializers.SerializerMethodField()
document_version_url = MultiKwargHyperlinkedIdentityField(
view_kwargs=(
{
'lookup_field': 'document_version_id', 'lookup_url_kwarg': 'document_version_id',
},
{
'lookup_field': 'document.pk', 'lookup_url_kwarg': 'document_id',
}
),
view_name='rest_api:document_version-detail'
)
url = MultiKwargHyperlinkedIdentityField(
view_kwargs=(
{
'lookup_field': 'pk', 'lookup_url_kwarg': 'document_page_id',
},
{
'lookup_field': 'document.pk', 'lookup_url_kwarg': 'document_id',
},
{
'lookup_field': 'document_version_id', 'lookup_url_kwarg': 'document_version_id',
},
),
view_name='rest_api:document_page-detail'
)
class Meta: class Meta:
fields = ('document_version_url', 'image_url', 'page_number', 'url') fields = ('document_version_url', 'image_url', 'page_number', 'url')
#fields = ('document_version_url', 'page_number', 'url')
model = DocumentPage model = DocumentPage
def get_document_version_url(self, instance): """
def get_document_versions_url(self, instance):
return reverse( return reverse(
viewname='rest_api:documentversion-detail', kwargs={ viewname='rest_api:documentversion-detail', kwargs={
'document_pk': instance.document.pk, 'document_id': instance.document.pk,
'document_version_pk': instance.document_version.pk 'document_version_id': instance.document_version.pk
}, request=self.context['request'], format=self.context['format'] }, request=self.context['request'], format=self.context['format']
) )
def get_image_url(self, instance): def get_image_url(self, instance):
return reverse( return reverse(
viewname='rest_api:documentpage-image', kwargs={ viewname='rest_api:documentpage-image', kwargs={
'document_pk': instance.document.pk, 'document_id': instance.document.pk,
'document_version_pk': instance.document_version.pk, 'document_version_id': instance.document_version.pk,
'document_page_pk': instance.pk, 'document_page_id': instance.pk,
}, request=self.context['request'], format=self.context['format'] }, request=self.context['request'], format=self.context['format']
) )
def get_url(self, instance): def get_url(self, instance):
return reverse( return reverse(
viewname='rest_api:documentpage-detail', kwargs={ viewname='rest_api:documentpage-detail', kwargs={
'document_pk': instance.document.pk, 'document_id': instance.document.pk,
'document_version_pk': instance.document_version.pk, 'document_version_id': instance.document_version.pk,
'document_page_pk': instance.pk, 'document_page_id': instance.pk,
}, request=self.context['request'], format=self.context['format'] }, request=self.context['request'], format=self.context['format']
) )
"""
class DocumentTypeFilenameSerializer(serializers.ModelSerializer): class DocumentTypeFilenameSerializer(serializers.ModelSerializer):
class Meta: class Meta:
@@ -59,33 +100,35 @@ class DocumentTypeFilenameSerializer(serializers.ModelSerializer):
class DocumentTypeSerializer(serializers.HyperlinkedModelSerializer): class DocumentTypeSerializer(serializers.HyperlinkedModelSerializer):
documents_url = serializers.HyperlinkedIdentityField( documents_url = serializers.HyperlinkedIdentityField(
lookup_field='pk', lookup_url_kwarg='document_type_pk', lookup_url_kwarg='document_type_id',
view_name='rest_api:documenttype-document-list' view_name='rest_api:document_type-document-list'
) )
documents_count = serializers.SerializerMethodField() #documents_count = serializers.SerializerMethodField()
filenames = DocumentTypeFilenameSerializer(many=True, read_only=True) #filenames = DocumentTypeFilenameSerializer(many=True, read_only=True)
class Meta: class Meta:
extra_kwargs = { extra_kwargs = {
'url': { 'url': {
'lookup_field': 'pk', 'lookup_url_kwarg': 'document_type_pk', 'lookup_field': 'pk', 'lookup_url_kwarg': 'document_type_id',
'view_name': 'rest_api:documenttype-detail' 'view_name': 'rest_api:document_type-detail'
} }
} }
fields = ( fields = (
'delete_time_period', 'delete_time_unit', 'documents_url', 'delete_time_period', 'delete_time_unit', 'documents_url',
'documents_count', 'id', 'label', 'filenames', 'trash_time_period', #'delete_time_period', 'delete_time_unit',
#'documents_count', 'id', 'label', 'filenames', 'trash_time_period',
'id', 'label', 'trash_time_period',
'trash_time_unit', 'url' 'trash_time_unit', 'url'
) )
model = DocumentType model = DocumentType
def get_documents_count(self, obj): #def get_documents_count(self, obj):
return obj.documents.count() # return obj.documents.count()
"""
class WritableDocumentTypeSerializer(serializers.ModelSerializer): class WritableDocumentTypeSerializer(serializers.ModelSerializer):
documents_url = serializers.HyperlinkedIdentityField( documents_url = serializers.HyperlinkedIdentityField(
lookup_field='pk', lookup_url_kwarg='document_type_pk', lookup_field='pk', lookup_url_kwarg='document_type_id',
view_name='rest_api:documenttype-document-list' view_name='rest_api:documenttype-document-list'
) )
documents_count = serializers.SerializerMethodField() documents_count = serializers.SerializerMethodField()
@@ -93,7 +136,7 @@ class WritableDocumentTypeSerializer(serializers.ModelSerializer):
class Meta: class Meta:
extra_kwargs = { extra_kwargs = {
'url': { 'url': {
'lookup_field': 'pk', 'lookup_url_kwarg': 'document_type_pk', 'lookup_field': 'pk', 'lookup_url_kwarg': 'document_type_id',
'view_name': 'rest_api:documenttype-detail' 'view_name': 'rest_api:documenttype-detail'
} }
} }
@@ -106,26 +149,69 @@ class WritableDocumentTypeSerializer(serializers.ModelSerializer):
def get_documents_count(self, obj): def get_documents_count(self, obj):
return obj.documents.count() return obj.documents.count()
"""
class DocumentVersionSerializer(serializers.HyperlinkedModelSerializer): class DocumentVersionSerializer(serializers.HyperlinkedModelSerializer):
document_url = serializers.SerializerMethodField() #document_url = serializers.SerializerMethodField()
download_url = serializers.SerializerMethodField() #download_url = serializers.SerializerMethodField()
pages_url = serializers.SerializerMethodField() document_url = serializers.HyperlinkedIdentityField(
lookup_field='document_id', lookup_url_kwarg='document_id',
view_name='rest_api:document-detail'
)
#pages_url = serializers.SerializerMethodField()
pages_url = MultiKwargHyperlinkedIdentityField(
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_page-list'
)
size = serializers.SerializerMethodField() size = serializers.SerializerMethodField()
url = serializers.SerializerMethodField() #url = serializers.SerializerMethodField()
url = MultiKwargHyperlinkedIdentityField(
view_kwargs=(
{
'lookup_field': 'pk', 'lookup_url_kwarg': 'document_version_id',
},
{
'lookup_field': 'document_id', 'lookup_url_kwarg': 'document_id',
},
),
view_name='rest_api:document_version-detail'
)
class Meta: class Meta:
extra_kwargs = { extra_kwargs = {
'document': { #'document': {
'lookup_field': 'pk', 'lookup_url_kwarg': 'document_pk', # 'lookup_field': 'pk', 'lookup_url_kwarg': 'document_id',
'view_name': 'rest_api:document-detail' # 'view_name': 'rest_api:document-detail'
}, #},
'file': {'use_url': False}, 'file': {'use_url': False},
#'url': {
# 'view_kwargs': (
# {
# 'lookup_field': 'pk', 'lookup_url_kwarg': 'document_version_id',
# },
# {
# 'lookup_field': 'document__pk', 'lookup_url_kwarg': 'document_id',
# },
# ),
# #'lookup_field': 'pk', 'lookup_url_kwarg': 'document_version_id',
# 'view_name': 'rest_api:document_version-detail'
#},
} }
fields = ( fields = (
'checksum', 'comment', 'document_url', 'download_url', 'encoding', #'checksum', 'comment', 'document_url', 'download_url', 'encoding',
'checksum', 'comment', 'document_url', 'encoding',
#'checksum', 'comment', 'encoding',
'file', 'mimetype', 'pages_url', 'size', 'timestamp', 'url' 'file', 'mimetype', 'pages_url', 'size', 'timestamp', 'url'
#'file', 'mimetype', 'size', 'timestamp', 'url'
) )
model = DocumentVersion model = DocumentVersion
read_only_fields = ('document', 'file', 'size') read_only_fields = ('document', 'file', 'size')
@@ -133,38 +219,62 @@ class DocumentVersionSerializer(serializers.HyperlinkedModelSerializer):
def get_size(self, instance): def get_size(self, instance):
return instance.size return instance.size
def build_url_field(self, field_name, model_class):
"""
Create a field representing the object's own URL.
"""
field_class = self.serializer_url_field
field_kwargs = {'kwargs': 1}
return field_class, field_kwargs
"""
def get_document_url(self, instance): def get_document_url(self, instance):
return reverse( return reverse(
viewname='rest_api:document-detail', kwargs={ viewname='rest_api:document-detail', kwargs={
'document_pk': instance.document.pk 'document_id': instance.document.pk
}, request=self.context['request'], format=self.context['format'] }, request=self.context['request']#, format=self.context['format']
) )
def get_download_url(self, instance): def get_download_url(self, instance):
return reverse( return reverse(
viewname='rest_api:documentversion-download', kwargs={ viewname='rest_api:document_version-download', kwargs={
'document_pk': instance.document.pk, 'document_id': instance.document.pk,
'document_version_pk': instance.pk 'document_version_id': instance.pk
}, request=self.context['request'], format=self.context['format'] }, request=self.context['request']#, format=self.context['format']
) )
def get_pages_url(self, instance): def get_pages_url(self, instance):
return reverse( return reverse(
viewname='rest_api:documentversion-page-list', kwargs={ viewname='rest_api:document_version-page-list', kwargs={
'document_pk': instance.document.pk, 'document_id': instance.document.pk,
'document_version_pk': instance.pk 'document_version_id': instance.pk
}, request=self.context['request'], format=self.context['format'] }, request=self.context['request']#, format=self.context['format']
) )
def get_url(self, instance):
def get_url(self, obj, view_name, request, format):
print ' obj, view_name, request, format', obj, view_name, request, format
# Unsaved objects will not yet have a valid URL.
if hasattr(obj, 'pk') and obj.pk in (None, ''):
return None
lookup_value = getattr(obj, self.lookup_field)
kwargs = {self.lookup_url_kwarg: lookup_value}
return self.reverse(view_name, kwargs=kwargs, request=request, format=format)
"""
"""
def get_url(self, instance, *args, **kwargs):
print ', *args, **kwargs', args, kwargs
return reverse( return reverse(
viewname='rest_api:documentversion-detail', kwargs={ viewname='rest_api:document_version-detail', kwargs={
'document_pk': instance.document.pk, 'document_id': instance.document.pk,
'document_version_pk': instance.pk 'document_version_id': instance.pk
}, request=self.context['request'], format=self.context['format'] }, request=self.context['request']#, format=self.context['format']
) )
"""
"""
class WritableDocumentVersionSerializer(serializers.ModelSerializer): class WritableDocumentVersionSerializer(serializers.ModelSerializer):
document_url = serializers.SerializerMethodField() document_url = serializers.SerializerMethodField()
download_url = serializers.SerializerMethodField() download_url = serializers.SerializerMethodField()
@@ -185,31 +295,31 @@ class WritableDocumentVersionSerializer(serializers.ModelSerializer):
def get_document_url(self, instance): def get_document_url(self, instance):
return reverse( return reverse(
viewname='rest_api:document-detail', kwargs={ viewname='rest_api:document-detail', kwargs={
'document_pk': instance.document.pk 'document_id': instance.document.pk
}, request=self.context['request'], format=self.context['format'] }, request=self.context['request'], format=self.context['format']
) )
def get_download_url(self, instance): def get_download_url(self, instance):
return reverse( return reverse(
viewname='rest_api:documentversion-download', kwargs={ viewname='rest_api:documentversion-download', kwargs={
'document_pk': instance.document.pk, 'document_id': instance.document.pk,
'document_version_pk': instance.pk 'document_version_id': instance.pk
}, request=self.context['request'], format=self.context['format'] }, request=self.context['request'], format=self.context['format']
) )
def get_pages_url(self, instance): def get_pages_url(self, instance):
return reverse( return reverse(
viewname='rest_api:documentversion-page-list', kwargs={ viewname='rest_api:documentversion-page-list', kwargs={
'document_pk': instance.document.pk, 'document_id': instance.document.pk,
'document_version_pk': instance.pk 'document_version_id': instance.pk
}, request=self.context['request'], format=self.context['format'] }, request=self.context['request'], format=self.context['format']
) )
def get_url(self, instance): def get_url(self, instance):
return reverse( return reverse(
viewname='rest_api:documentversion-detail', kwargs={ viewname='rest_api:documentversion-detail', kwargs={
'document_pk': instance.document.pk, 'document_id': instance.document.pk,
'document_version_pk': instance.pk 'document_version_id': instance.pk
}, request=self.context['request'], format=self.context['format'] }, request=self.context['request'], format=self.context['format']
) )
@@ -228,23 +338,23 @@ class NewDocumentVersionSerializer(serializers.Serializer):
document_id=document.pk, document_id=document.pk,
shared_uploaded_file_id=shared_uploaded_file.pk, user_id=_user.pk shared_uploaded_file_id=shared_uploaded_file.pk, user_id=_user.pk
) )
"""
class DeletedDocumentSerializer(serializers.HyperlinkedModelSerializer): class DeletedDocumentSerializer(serializers.HyperlinkedModelSerializer):
document_type_label = serializers.SerializerMethodField() document_type_label = serializers.SerializerMethodField()
restore = serializers.HyperlinkedIdentityField( restore = serializers.HyperlinkedIdentityField(
lookup_field='pk', lookup_url_kwarg='document_pk', lookup_field='pk', lookup_url_kwarg='document_id',
view_name='rest_api:trasheddocument-restore' view_name='rest_api:trasheddocument-restore'
) )
class Meta: class Meta:
extra_kwargs = { extra_kwargs = {
'document_type': { 'document_type': {
'lookup_field': 'pk', 'lookup_url_kwarg': 'document_type_pk', 'lookup_field': 'pk', 'lookup_url_kwarg': 'document_type_id',
'view_name': 'rest_api:documenttype-detail' 'view_name': 'rest_api:documenttype-detail'
}, },
'url': { 'url': {
'lookup_field': 'pk', 'lookup_url_kwarg': 'document_pk', 'lookup_field': 'pk', 'lookup_url_kwarg': 'document_id',
'view_name': 'rest_api:trasheddocument-detail' 'view_name': 'rest_api:trasheddocument-detail'
} }
} }
@@ -264,41 +374,49 @@ class DeletedDocumentSerializer(serializers.HyperlinkedModelSerializer):
class DocumentSerializer(serializers.HyperlinkedModelSerializer): class DocumentSerializer(serializers.HyperlinkedModelSerializer):
document_type = DocumentTypeSerializer() document_type = DocumentTypeSerializer(read_only=True)
#document_type_url = serializers.HyperlinkedIdentityField(
# lookup_field='document_type_id', lookup_url_kwarg='document_type_id',
# view_name='rest_api:document_type-detail'
#)
latest_version = DocumentVersionSerializer(many=False, read_only=True) latest_version = DocumentVersionSerializer(many=False, read_only=True)
versions_url = serializers.HyperlinkedIdentityField( versions_url = serializers.HyperlinkedIdentityField(
lookup_field='pk', lookup_url_kwarg='document_pk', lookup_field='pk', lookup_url_kwarg='document_id',
view_name='rest_api:document-version-list' view_name='rest_api:document_version-list'
) )
#view_name='rest_api:document_type-document-list'
class Meta: class Meta:
extra_kwargs = { extra_kwargs = {
'document_type': { 'document_type': {
'lookup_field': 'pk', 'lookup_url_kwarg': 'document_type_pk', 'lookup_field': 'pk', 'lookup_url_kwarg': 'document_type_id',
'view_name': 'rest_api:documenttype-detail' 'view_name': 'rest_api:document_type-detail'
}, },
'url': { 'url': {
'lookup_field': 'pk', 'lookup_url_kwarg': 'document_pk', 'lookup_field': 'pk', 'lookup_url_kwarg': 'document_id',
'view_name': 'rest_api:document-detail' 'view_name': 'rest_api:document-detail'
} }
} }
fields = ( fields = (
'date_added', 'description', 'document_type', 'id', 'label', 'date_added', 'description', 'document_type', 'id', 'label',
#'date_added', 'description', 'document_type_url', 'id', 'label',
'language', 'latest_version', 'url', 'uuid', 'versions_url', 'language', 'latest_version', 'url', 'uuid', 'versions_url',
#'language', 'url', 'uuid', 'versions_url'
) )
model = Document model = Document
read_only_fields = ('document_type',) #read_only_fields = ('document_type', 'label')
"""
class WritableDocumentSerializer(serializers.ModelSerializer): class WritableDocumentSerializer(serializers.ModelSerializer):
document_type = DocumentTypeSerializer(read_only=True) document_type = DocumentTypeSerializer(read_only=True)
latest_version = DocumentVersionSerializer(many=False, read_only=True) latest_version = DocumentVersionSerializer(many=False, read_only=True)
versions = serializers.HyperlinkedIdentityField( versions = serializers.HyperlinkedIdentityField(
lookup_field='pk', lookup_url_kwarg='document_pk', lookup_field='pk', lookup_url_kwarg='document_id',
view_name='rest_api:document-version-list' view_name='rest_api:document-version-list'
) )
url = serializers.HyperlinkedIdentityField( url = serializers.HyperlinkedIdentityField(
lookup_field='pk', lookup_url_kwarg='document_pk', lookup_field='pk', lookup_url_kwarg='document_id',
view_name='rest_api:document-detail', view_name='rest_api:document-detail',
) )
@@ -344,7 +462,7 @@ class NewDocumentSerializer(serializers.ModelSerializer):
'description', 'document_type', 'id', 'file', 'label', 'language', 'description', 'document_type', 'id', 'file', 'label', 'language',
) )
model = Document model = Document
"""
class RecentDocumentSerializer(serializers.ModelSerializer): class RecentDocumentSerializer(serializers.ModelSerializer):
class Meta: class Meta:
+1 -1
View File
@@ -13,7 +13,7 @@ from .literals import (
) )
from .utils import callback_update_cache_size from .utils import callback_update_cache_size
namespace = Namespace(name='documents', label=_('Documents')) namespace = Namespace(label=_('Documents'), name='documents')
setting_document_cache_maximum_size = namespace.add_setting( setting_document_cache_maximum_size = namespace.add_setting(
global_name='DOCUMENTS_CACHE_MAXIMUM_SIZE', global_name='DOCUMENTS_CACHE_MAXIMUM_SIZE',
+2 -2
View File
@@ -2,11 +2,11 @@ from __future__ import unicode_literals
from django.dispatch import Signal from django.dispatch import Signal
post_version_upload = Signal(providing_args=('instance',), use_caching=True) post_document_created = Signal(providing_args=('instance',), use_caching=True)
post_document_type_change = Signal( post_document_type_change = Signal(
providing_args=('instance',), use_caching=True providing_args=('instance',), use_caching=True
) )
post_document_created = Signal(providing_args=('instance',), use_caching=True)
post_initial_document_type = Signal( post_initial_document_type = Signal(
providing_args=('instance',), use_caching=True providing_args=('instance',), use_caching=True
) )
post_version_upload = Signal(providing_args=('instance',), use_caching=True)
+29 -30
View File
@@ -68,9 +68,8 @@ def new_documents_this_month(user=None):
queryset = Document.objects.all() queryset = Document.objects.all()
if user: if user:
queryset = AccessControlList.objects.filter_by_access( queryset = AccessControlList.objects.restrict_queryset(
permission=permission_document_view, user=user, permission=permission_document_view, queryset=queryset, user=user
queryset=queryset
) )
qss = qsstats.QuerySetStats(queryset, 'date_added') qss = qsstats.QuerySetStats(queryset, 'date_added')
@@ -110,9 +109,9 @@ def new_document_pages_this_month(user=None):
queryset = DocumentPage.objects.all() queryset = DocumentPage.objects.all()
if user: if user:
queryset = AccessControlList.objects.filter_by_access( queryset = AccessControlList.objects.restrict_queryset(
permission=permission_document_view, user=user, permission=permission_document_view, queryset=queryset,
queryset=queryset user=user
) )
qss = qsstats.QuerySetStats( qss = qsstats.QuerySetStats(
@@ -230,44 +229,44 @@ def total_document_page_per_month():
namespace = StatisticNamespace(slug='documents', label=_('Documents')) namespace = StatisticNamespace(slug='documents', label=_('Documents'))
namespace.add_statistic( namespace.add_statistic(
klass=StatisticLineChart,
slug='new-documents-per-month',
label=_('New documents per month'),
func=new_documents_per_month, func=new_documents_per_month,
minute='0' klass=StatisticLineChart,
label=_('New documents per month'),
minute='0',
slug='new-documents-per-month'
) )
namespace.add_statistic( namespace.add_statistic(
klass=StatisticLineChart,
slug='new-document-versions-per-month',
label=_('New document versions per month'),
func=new_document_versions_per_month, func=new_document_versions_per_month,
minute='0' klass=StatisticLineChart,
label=_('New document versions per month'),
minute='0',
slug='new-document-versions-per-month'
) )
namespace.add_statistic( namespace.add_statistic(
klass=StatisticLineChart,
slug='new-document-pages-per-month',
label=_('New document pages per month'),
func=new_document_pages_per_month, func=new_document_pages_per_month,
minute='0' klass=StatisticLineChart,
label=_('New document pages per month'),
minute='0',
slug='new-document-pages-per-month'
) )
namespace.add_statistic( namespace.add_statistic(
klass=StatisticLineChart,
slug='total-documents-at-each-month',
label=_('Total documents at each month'),
func=total_document_per_month, func=total_document_per_month,
minute='0' klass=StatisticLineChart,
label=_('Total documents at each month'),
minute='0',
slug='total-documents-at-each-month'
) )
namespace.add_statistic( namespace.add_statistic(
klass=StatisticLineChart,
slug='total-document-versions-at-each-month',
label=_('Total document versions at each month'),
func=total_document_version_per_month, func=total_document_version_per_month,
minute='0' klass=StatisticLineChart,
label=_('Total document versions at each month'),
minute='0',
slug='total-document-versions-at-each-month'
) )
namespace.add_statistic( namespace.add_statistic(
klass=StatisticLineChart,
slug='total-document-pages-at-each-month',
label=_('Total document pages at each month'),
func=total_document_page_per_month, func=total_document_page_per_month,
minute='0' klass=StatisticLineChart,
label=_('Total document pages at each month'),
minute='0',
slug='total-document-pages-at-each-month'
) )
+5 -5
View File
@@ -58,14 +58,14 @@ def task_clear_image_cache():
@app.task(ignore_result=True) @app.task(ignore_result=True)
def task_delete_document(deleted_document_id): def task_delete_document(trashed_document_id):
DeletedDocument = apps.get_model( TrashedDocument = apps.get_model(
app_label='documents', model_name='DeletedDocument' app_label='documents', model_name='TrashedDocument'
) )
logger.debug('Executing') logger.debug('Executing')
deleted_document = DeletedDocument.objects.get(pk=deleted_document_id) trashed_document = TrashedDocument.objects.get(pk=trashed_document_id)
deleted_document.delete() trashed_document.delete()
logger.debug('Finshed') logger.debug('Finshed')
+23 -13
View File
@@ -18,27 +18,25 @@ class DocumentTestMixin(object):
auto_create_document_type = True auto_create_document_type = True
auto_upload_document = True auto_upload_document = True
test_document_filename = TEST_SMALL_DOCUMENT_FILENAME test_document_filename = TEST_SMALL_DOCUMENT_FILENAME
test_document_path = None
def _create_document_type(self): def _create_document_type(self):
self.document_type = DocumentType.objects.create( self.document_type = DocumentType.objects.create(
label=TEST_DOCUMENT_TYPE_LABEL label=TEST_DOCUMENT_TYPE_LABEL
) )
def upload_document(self, filename=None): def _create_document(self, *args, **kwargs):
self._calculate_test_document_path() """
Alias for upload_document()
with open(self.test_document_path, mode='rb') as file_object: """
document = self.document_type.new_document( self.test_document = self.upload_document(*args, **kwargs)
file_object=file_object,
label=filename or self.test_document_filename
)
return document
def _calculate_test_document_path(self): def _calculate_test_document_path(self):
self.test_document_path = os.path.join( if not self.test_document_path:
settings.BASE_DIR, 'apps', 'documents', 'tests', 'contrib', self.test_document_path = os.path.join(
'sample_documents', self.test_document_filename settings.BASE_DIR, 'apps', 'documents', 'tests', 'contrib',
) 'sample_documents', self.test_document_filename
)
def setUp(self): def setUp(self):
super(DocumentTestMixin, self).setUp() super(DocumentTestMixin, self).setUp()
@@ -54,6 +52,18 @@ class DocumentTestMixin(object):
document_type.delete() document_type.delete()
super(DocumentTestMixin, self).tearDown() super(DocumentTestMixin, self).tearDown()
def upload_document(self, document_type=None, filename=None):
self._calculate_test_document_path()
document_type = document_type or self.document_type
with open(self.test_document_path, mode='rb') as file_object:
document = document_type.new_document(
file_object=file_object,
label=filename or self.test_document_filename
)
return document
class DocumentTypeQuickLabelTestMixin(object): class DocumentTypeQuickLabelTestMixin(object):
def _create_quick_label(self): def _create_quick_label(self):
+30 -30
View File
@@ -11,10 +11,10 @@ from mayan.apps.rest_api.tests import BaseAPITestCase
from ..models import Document, DocumentType from ..models import Document, DocumentType
from ..permissions import ( from ..permissions import (
permission_document_create, permission_document_delete, permission_document_create, permission_document_download,
permission_document_download, permission_document_edit, permission_document_edit, permission_document_new_version,
permission_document_new_version, permission_document_properties_edit, permission_document_properties_edit, permission_document_trash,
permission_document_restore, permission_document_trash, permission_trashed_document_delete, permission_trashed_document_restore,
permission_document_type_create, permission_document_type_delete, permission_document_type_create, permission_document_type_delete,
permission_document_type_edit, permission_document_version_revert, permission_document_type_edit, permission_document_version_revert,
permission_document_version_view, permission_document_view permission_document_version_view, permission_document_view
@@ -61,7 +61,7 @@ class DocumentTypeAPITestCase(BaseAPITestCase):
def _request_document_type_patch(self): def _request_document_type_patch(self):
return self.patch( return self.patch(
viewname='rest_api:documenttype-detail', kwargs={ viewname='rest_api:documenttype-detail', kwargs={
'document_type_pk': self.document_type.pk 'document_type_id': self.document_type.pk
}, data={'label': TEST_DOCUMENT_TYPE_LABEL_EDITED} }, data={'label': TEST_DOCUMENT_TYPE_LABEL_EDITED}
) )
@@ -90,7 +90,7 @@ class DocumentTypeAPITestCase(BaseAPITestCase):
def _request_document_type_put(self): def _request_document_type_put(self):
return self.put( return self.put(
viewname='rest_api:documenttype-detail', kwargs={ viewname='rest_api:documenttype-detail', kwargs={
'document_type_pk': self.document_type.pk 'document_type_id': self.document_type.pk
}, data={'label': TEST_DOCUMENT_TYPE_LABEL_EDITED} }, data={'label': TEST_DOCUMENT_TYPE_LABEL_EDITED}
) )
@@ -119,7 +119,7 @@ class DocumentTypeAPITestCase(BaseAPITestCase):
def _request_document_type_delete(self): def _request_document_type_delete(self):
return self.delete( return self.delete(
viewname='rest_api:documenttype-detail', kwargs={ viewname='rest_api:documenttype-detail', kwargs={
'document_type_pk': self.document_type.pk 'document_type_id': self.document_type.pk
} }
) )
@@ -207,7 +207,7 @@ class DocumentAPITestCase(DocumentTestMixin, BaseAPITestCase):
with open(TEST_DOCUMENT_PATH, mode='rb') as file_descriptor: with open(TEST_DOCUMENT_PATH, mode='rb') as file_descriptor:
return self.post( return self.post(
viewname='rest_api:document-version-list', kwargs={ viewname='rest_api:document-version-list', kwargs={
'document_pk': self.document.pk 'document_id': self.document.pk
}, data={ }, data={
'comment': '', 'file': file_descriptor, 'comment': '', 'file': file_descriptor,
} }
@@ -247,8 +247,8 @@ class DocumentAPITestCase(DocumentTestMixin, BaseAPITestCase):
def _request_document_version_revert(self): def _request_document_version_revert(self):
return self.delete( return self.delete(
viewname='rest_api:documentversion-detail', kwargs={ viewname='rest_api:documentversion-detail', kwargs={
'document_pk': self.document.pk, 'document_id': self.document.pk,
'document_version_pk': self.document.latest_version.pk 'document_version_id': self.document.latest_version.pk
} }
) )
@@ -275,7 +275,7 @@ class DocumentAPITestCase(DocumentTestMixin, BaseAPITestCase):
def _request_document_version_list(self): def _request_document_version_list(self):
return self.get( return self.get(
viewname='rest_api:document-version-list', viewname='rest_api:document-version-list',
kwargs={'document_pk': self.document.pk} kwargs={'document_id': self.document.pk}
) )
def test_document_version_list_no_permission(self): def test_document_version_list_no_permission(self):
@@ -301,7 +301,7 @@ class DocumentAPITestCase(DocumentTestMixin, BaseAPITestCase):
def _request_document_download(self): def _request_document_download(self):
return self.get( return self.get(
viewname='rest_api:document-download', viewname='rest_api:document-download',
kwargs={'document_pk': self.document.pk} kwargs={'document_id': self.document.pk}
) )
def test_document_download_no_permission(self): def test_document_download_no_permission(self):
@@ -329,8 +329,8 @@ class DocumentAPITestCase(DocumentTestMixin, BaseAPITestCase):
def _request_document_version_download(self): def _request_document_version_download(self):
return self.get( return self.get(
viewname='rest_api:documentversion-download', kwargs={ viewname='rest_api:documentversion-download', kwargs={
'document_pk': self.document.pk, 'document_id': self.document.pk,
'document_version_pk': self.document.latest_version.pk, 'document_version_id': self.document.latest_version.pk,
} }
) )
@@ -362,8 +362,8 @@ class DocumentAPITestCase(DocumentTestMixin, BaseAPITestCase):
response = self.get( response = self.get(
viewname='rest_api:documentversion-download', kwargs={ viewname='rest_api:documentversion-download', kwargs={
'document_pk': self.document.pk, 'document_id': self.document.pk,
'document_version_pk': self.document.latest_version.pk, 'document_version_id': self.document.latest_version.pk,
}, data={'preserve_extension': True} }, data={'preserve_extension': True}
) )
@@ -380,8 +380,8 @@ class DocumentAPITestCase(DocumentTestMixin, BaseAPITestCase):
def _request_document_version_edit_via_patch(self): def _request_document_version_edit_via_patch(self):
return self.patch( return self.patch(
viewname='rest_api:documentversion-detail', kwargs={ viewname='rest_api:documentversion-detail', kwargs={
'document_pk': self.document.pk, 'document_id': self.document.pk,
'document_version_pk': self.document.latest_version.pk, 'document_version_id': self.document.latest_version.pk,
}, data={'comment': TEST_DOCUMENT_VERSION_COMMENT_EDITED} }, data={'comment': TEST_DOCUMENT_VERSION_COMMENT_EDITED}
) )
@@ -407,8 +407,8 @@ class DocumentAPITestCase(DocumentTestMixin, BaseAPITestCase):
def _request_document_version_edit_via_put(self): def _request_document_version_edit_via_put(self):
return self.put( return self.put(
viewname='rest_api:documentversion-detail', kwargs={ viewname='rest_api:documentversion-detail', kwargs={
'document_pk': self.document.pk, 'document_id': self.document.pk,
'document_version_pk': self.document.latest_version.pk, 'document_version_id': self.document.latest_version.pk,
}, data={'comment': TEST_DOCUMENT_VERSION_COMMENT_EDITED} }, data={'comment': TEST_DOCUMENT_VERSION_COMMENT_EDITED}
) )
@@ -434,7 +434,7 @@ class DocumentAPITestCase(DocumentTestMixin, BaseAPITestCase):
def _request_document_description_edit_via_patch(self): def _request_document_description_edit_via_patch(self):
return self.patch( return self.patch(
viewname='rest_api:document-detail', viewname='rest_api:document-detail',
kwargs={'document_pk': self.document.pk}, kwargs={'document_id': self.document.pk},
data={'description': TEST_DOCUMENT_DESCRIPTION_EDITED} data={'description': TEST_DOCUMENT_DESCRIPTION_EDITED}
) )
@@ -459,7 +459,7 @@ class DocumentAPITestCase(DocumentTestMixin, BaseAPITestCase):
def _request_document_description_edit_via_put(self): def _request_document_description_edit_via_put(self):
return self.put( return self.put(
viewname='rest_api:document-detail', viewname='rest_api:document-detail',
kwargs={'document_pk': self.document.pk}, kwargs={'document_id': self.document.pk},
data={'description': TEST_DOCUMENT_DESCRIPTION_EDITED} data={'description': TEST_DOCUMENT_DESCRIPTION_EDITED}
) )
@@ -491,8 +491,8 @@ class DocumentPageAPITestCase(DocumentTestMixin, BaseAPITestCase):
page = self.document.pages.first() page = self.document.pages.first()
return self.get( return self.get(
viewname='rest_api:documentpage-image', kwargs={ viewname='rest_api:documentpage-image', kwargs={
'document_pk': page.document.pk, 'document_id': page.document.pk,
'document_version_pk': page.document_version.pk, 'document_page_pk': page.pk 'document_version_id': page.document_version.pk, 'document_page_id': page.pk
} }
) )
@@ -518,7 +518,7 @@ class TrashedDocumentAPITestCase(DocumentTestMixin, BaseAPITestCase):
def _request_document_move_to_trash(self): def _request_document_move_to_trash(self):
return self.delete( return self.delete(
viewname='rest_api:document-detail', viewname='rest_api:document-detail',
kwargs={'document_pk': self.document.pk} kwargs={'document_id': self.document.pk}
) )
def test_document_move_to_trash_no_permission(self): def test_document_move_to_trash_no_permission(self):
@@ -540,7 +540,7 @@ class TrashedDocumentAPITestCase(DocumentTestMixin, BaseAPITestCase):
def _request_trashed_document_delete_view(self): def _request_trashed_document_delete_view(self):
return self.delete( return self.delete(
viewname='rest_api:trasheddocument-detail', viewname='rest_api:trasheddocument-detail',
kwargs={'document_pk': self.document.pk} kwargs={'document_id': self.document.pk}
) )
def test_trashed_document_delete_from_trash_no_access(self): def test_trashed_document_delete_from_trash_no_access(self):
@@ -554,7 +554,7 @@ class TrashedDocumentAPITestCase(DocumentTestMixin, BaseAPITestCase):
def test_trashed_document_delete_from_trash_with_access(self): def test_trashed_document_delete_from_trash_with_access(self):
self.document = self.upload_document() self.document = self.upload_document()
self.document.delete() self.document.delete()
self.grant_access(permission=permission_document_delete, obj=self.document) self.grant_access(permission=permission_trashed_document_delete, obj=self.document)
response = self._request_trashed_document_delete_view() response = self._request_trashed_document_delete_view()
self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)
self.assertEqual(Document.objects.count(), 0) self.assertEqual(Document.objects.count(), 0)
@@ -563,7 +563,7 @@ class TrashedDocumentAPITestCase(DocumentTestMixin, BaseAPITestCase):
def _request_trashed_document_detail_view(self): def _request_trashed_document_detail_view(self):
return self.get( return self.get(
viewname='rest_api:trasheddocument-detail', viewname='rest_api:trasheddocument-detail',
kwargs={'document_pk': self.document.pk} kwargs={'document_id': self.document.pk}
) )
def test_trashed_document_detail_view_no_access(self): def test_trashed_document_detail_view_no_access(self):
@@ -608,7 +608,7 @@ class TrashedDocumentAPITestCase(DocumentTestMixin, BaseAPITestCase):
def _request_trashed_document_restore_view(self): def _request_trashed_document_restore_view(self):
return self.post( return self.post(
viewname='rest_api:trasheddocument-restore', viewname='rest_api:trasheddocument-restore',
kwargs={'document_pk': self.document.pk} kwargs={'document_id': self.document.pk}
) )
def test_trashed_document_restore_no_access(self): def test_trashed_document_restore_no_access(self):
@@ -622,7 +622,7 @@ class TrashedDocumentAPITestCase(DocumentTestMixin, BaseAPITestCase):
def test_trashed_document_restore_with_access(self): def test_trashed_document_restore_with_access(self):
self.document = self.upload_document() self.document = self.upload_document()
self.document.delete() self.document.delete()
self.grant_access(permission=permission_document_restore, obj=self.document) self.grant_access(permission=permission_trashed_document_restore, obj=self.document)
response = self._request_trashed_document_restore_view() response = self._request_trashed_document_restore_view()
self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(Document.trash.count(), 0) self.assertEqual(Document.trash.count(), 0)
@@ -9,19 +9,15 @@ from .literals import TEST_MULTI_PAGE_TIFF
class DocumentPageViewTestCase(GenericDocumentViewTestCase): class DocumentPageViewTestCase(GenericDocumentViewTestCase):
def setUp(self):
super(DocumentPageViewTestCase, self).setUp()
self.login_user()
def _document_page_list_view(self): def _document_page_list_view(self):
return self.get( return self.get(
viewname='documents:document_pages', viewname='documents:document_pages',
kwargs={'document_pk': self.document.pk} kwargs={'document_id': self.document.pk}
) )
def test_document_page_list_view_no_permission(self): def test_document_page_list_view_no_permission(self):
response = self._document_page_list_view() response = self._document_page_list_view()
self.assertEqual(response.status_code, 403) self.assertEqual(response.status_code, 404)
def test_document_page_list_view_with_access(self): def test_document_page_list_view_with_access(self):
self.grant_access( self.grant_access(
@@ -32,18 +28,39 @@ class DocumentPageViewTestCase(GenericDocumentViewTestCase):
response=response, text=self.document.label, status_code=200 response=response, text=self.document.label, status_code=200
) )
def _request_document_page_view(self, document_page):
return self.get(
viewname='documents:document_page_view', kwargs={
'document_page_id': document_page.pk
}
)
def test_document_page_view_no_permissions(self):
response = self._request_document_page_view(
document_page=self.document.pages.first()
)
self.assertEqual(response.status_code, 404)
def test_document_page_view_with_access(self):
self.grant_access(
obj=self.document, permission=permission_document_view
)
response = self._request_document_page_view(
document_page=self.document.pages.first()
)
self.assertContains(
response=response, text=force_text(self.document.pages.first()),
status_code=200
)
class DocumentPageNavigationViewTestCase(GenericDocumentViewTestCase): class DocumentPageNavigationViewTestCase(GenericDocumentViewTestCase):
test_document_filename = TEST_MULTI_PAGE_TIFF test_document_filename = TEST_MULTI_PAGE_TIFF
def setUp(self):
super(DocumentPageNavigationViewTestCase, self).setUp()
self.login_user()
def _request_document_page_navigation_next_view(self): def _request_document_page_navigation_next_view(self):
return self.get( return self.get(
viewname='documents:document_page_navigation_next', viewname='documents:document_page_navigation_next',
kwargs={'document_page_pk': self.document.pages.first().pk}, kwargs={'document_page_id': self.document.pages.first().pk},
follow=True follow=True
) )
@@ -51,7 +68,6 @@ class DocumentPageNavigationViewTestCase(GenericDocumentViewTestCase):
self.grant_access( self.grant_access(
obj=self.document, permission=permission_document_view obj=self.document, permission=permission_document_view
) )
response = self._request_document_page_navigation_next_view() response = self._request_document_page_navigation_next_view()
self.assertContains( self.assertContains(
@@ -62,7 +78,7 @@ class DocumentPageNavigationViewTestCase(GenericDocumentViewTestCase):
def _request_document_page_navigation_last_view(self): def _request_document_page_navigation_last_view(self):
return self.get( return self.get(
viewname='documents:document_page_navigation_last', viewname='documents:document_page_navigation_last',
kwargs={'document_page_pk': self.document.pages.first().pk}, kwargs={'document_page_id': self.document.pages.first().pk},
follow=True follow=True
) )
@@ -70,7 +86,6 @@ class DocumentPageNavigationViewTestCase(GenericDocumentViewTestCase):
self.grant_access( self.grant_access(
obj=self.document, permission=permission_document_view obj=self.document, permission=permission_document_view
) )
response = self._request_document_page_navigation_last_view() response = self._request_document_page_navigation_last_view()
self.assertContains( self.assertContains(
@@ -81,7 +96,7 @@ class DocumentPageNavigationViewTestCase(GenericDocumentViewTestCase):
def _request_document_page_navigation_previous_view(self): def _request_document_page_navigation_previous_view(self):
return self.get( return self.get(
viewname='documents:document_page_navigation_previous', viewname='documents:document_page_navigation_previous',
kwargs={'document_page_pk': self.document.pages.last().pk}, kwargs={'document_page_id': self.document.pages.last().pk},
follow=True follow=True
) )
@@ -89,7 +104,6 @@ class DocumentPageNavigationViewTestCase(GenericDocumentViewTestCase):
self.grant_access( self.grant_access(
obj=self.document, permission=permission_document_view obj=self.document, permission=permission_document_view
) )
response = self._request_document_page_navigation_previous_view() response = self._request_document_page_navigation_previous_view()
self.assertContains( self.assertContains(
@@ -100,7 +114,7 @@ class DocumentPageNavigationViewTestCase(GenericDocumentViewTestCase):
def _request_document_page_navigation_first_view(self): def _request_document_page_navigation_first_view(self):
return self.get( return self.get(
viewname='documents:document_page_navigation_first', viewname='documents:document_page_navigation_first',
kwargs={'document_page_pk': self.document.pages.last().pk}, kwargs={'document_page_id': self.document.pages.last().pk},
follow=True follow=True
) )
@@ -108,7 +122,6 @@ class DocumentPageNavigationViewTestCase(GenericDocumentViewTestCase):
self.grant_access( self.grant_access(
obj=self.document, permission=permission_document_view obj=self.document, permission=permission_document_view
) )
response = self._request_document_page_navigation_first_view() response = self._request_document_page_navigation_first_view()
self.assertContains( self.assertContains(
@@ -16,10 +16,6 @@ from .mixins import DocumentTypeQuickLabelTestMixin
class DocumentTypeViewsTestCase(GenericDocumentViewTestCase): class DocumentTypeViewsTestCase(GenericDocumentViewTestCase):
def setUp(self):
super(DocumentTypeViewsTestCase, self).setUp()
self.login_user()
def _request_document_type_create(self): def _request_document_type_create(self):
return self.post( return self.post(
viewname='documents:document_type_create', viewname='documents:document_type_create',
@@ -50,12 +46,12 @@ class DocumentTypeViewsTestCase(GenericDocumentViewTestCase):
def _request_document_type_delete(self): def _request_document_type_delete(self):
return self.post( return self.post(
viewname='documents:document_type_delete', viewname='documents:document_type_delete',
kwargs={'document_type_pk': self.document_type.pk} kwargs={'document_type_id': self.document_type.pk}
) )
def test_document_type_delete_view_no_permission(self): def test_document_type_delete_view_no_permission(self):
response = self._request_document_type_delete() response = self._request_document_type_delete()
self.assertEqual(response.status_code, 403) self.assertEqual(response.status_code, 404)
self.assertEqual(DocumentType.objects.count(), 1) self.assertEqual(DocumentType.objects.count(), 1)
def test_document_type_delete_view_with_access(self): def test_document_type_delete_view_with_access(self):
@@ -69,7 +65,7 @@ class DocumentTypeViewsTestCase(GenericDocumentViewTestCase):
def _request_document_type_edit(self): def _request_document_type_edit(self):
return self.post( return self.post(
viewname='documents:document_type_edit', viewname='documents:document_type_edit',
kwargs={'document_type_pk': self.document_type.pk}, kwargs={'document_type_id': self.document_type.pk},
data={ data={
'label': TEST_DOCUMENT_TYPE_LABEL_EDITED, 'label': TEST_DOCUMENT_TYPE_LABEL_EDITED,
'delete_time_period': DEFAULT_DELETE_PERIOD, 'delete_time_period': DEFAULT_DELETE_PERIOD,
@@ -79,7 +75,7 @@ class DocumentTypeViewsTestCase(GenericDocumentViewTestCase):
def test_document_type_edit_view_no_permission(self): def test_document_type_edit_view_no_permission(self):
response = self._request_document_type_edit() response = self._request_document_type_edit()
self.assertEqual(response.status_code, 403) self.assertEqual(response.status_code, 404)
self.document_type.refresh_from_db() self.document_type.refresh_from_db()
self.assertEqual( self.assertEqual(
self.document_type.label, TEST_DOCUMENT_TYPE_LABEL self.document_type.label, TEST_DOCUMENT_TYPE_LABEL
@@ -98,14 +94,10 @@ class DocumentTypeViewsTestCase(GenericDocumentViewTestCase):
class DocumentTypeQuickLabelViewsTestCase(DocumentTypeQuickLabelTestMixin, GenericDocumentViewTestCase): class DocumentTypeQuickLabelViewsTestCase(DocumentTypeQuickLabelTestMixin, GenericDocumentViewTestCase):
def setUp(self):
super(DocumentTypeQuickLabelViewsTestCase, self).setUp()
self.login_user()
def _request_quick_label_create(self): def _request_quick_label_create(self):
return self.post( return self.post(
viewname='documents:document_type_filename_create', viewname='documents:document_type_filename_create',
kwargs={'document_type_pk': self.document_type.pk}, kwargs={'document_type_id': self.document_type.pk},
data={ data={
'filename': TEST_DOCUMENT_TYPE_QUICK_LABEL, 'filename': TEST_DOCUMENT_TYPE_QUICK_LABEL,
} }
@@ -117,7 +109,7 @@ class DocumentTypeQuickLabelViewsTestCase(DocumentTypeQuickLabelTestMixin, Gener
) )
response = self._request_quick_label_create() response = self._request_quick_label_create()
self.assertEqual(response.status_code, 403) self.assertEqual(response.status_code, 404)
self.assertEqual(self.document_type.filenames.count(), 0) self.assertEqual(self.document_type.filenames.count(), 0)
def test_document_type_quick_label_create_with_access(self): def test_document_type_quick_label_create_with_access(self):
@@ -132,7 +124,7 @@ class DocumentTypeQuickLabelViewsTestCase(DocumentTypeQuickLabelTestMixin, Gener
def _request_quick_label_delete(self): def _request_quick_label_delete(self):
return self.post( return self.post(
viewname='documents:document_type_filename_delete', viewname='documents:document_type_filename_delete',
kwargs={'filename_pk': self.document_type_filename.pk}, kwargs={'filename_id': self.document_type_filename.pk},
) )
def test_document_type_quick_label_delete_no_access(self): def test_document_type_quick_label_delete_no_access(self):
@@ -158,7 +150,7 @@ class DocumentTypeQuickLabelViewsTestCase(DocumentTypeQuickLabelTestMixin, Gener
def _request_quick_label_edit(self): def _request_quick_label_edit(self):
return self.post( return self.post(
viewname='documents:document_type_filename_edit', viewname='documents:document_type_filename_edit',
kwargs={'filename_pk': self.document_type_filename.pk}, kwargs={'filename_id': self.document_type_filename.pk},
data={ data={
'filename': TEST_DOCUMENT_TYPE_QUICK_LABEL_EDITED, 'filename': TEST_DOCUMENT_TYPE_QUICK_LABEL_EDITED,
} }
@@ -168,7 +160,7 @@ class DocumentTypeQuickLabelViewsTestCase(DocumentTypeQuickLabelTestMixin, Gener
self._create_quick_label() self._create_quick_label()
response = self._request_quick_label_edit() response = self._request_quick_label_edit()
self.assertEqual(response.status_code, 403) self.assertEqual(response.status_code, 404)
self.document_type_filename.refresh_from_db() self.document_type_filename.refresh_from_db()
self.assertEqual( self.assertEqual(
self.document_type_filename.filename, self.document_type_filename.filename,
@@ -193,13 +185,13 @@ class DocumentTypeQuickLabelViewsTestCase(DocumentTypeQuickLabelTestMixin, Gener
def _request_quick_label_list_view(self): def _request_quick_label_list_view(self):
return self.get( return self.get(
viewname='documents:document_type_filename_list', viewname='documents:document_type_filename_list',
kwargs={'document_type_pk': self.document_type.pk}, kwargs={'document_type_id': self.document_type.pk},
) )
def test_document_type_quick_label_list_no_access(self): def test_document_type_quick_label_list_no_access(self):
self._create_quick_label() self._create_quick_label()
response = self._request_quick_label_list_view() response = self._request_quick_label_list_view()
self.assertEqual(response.status_code, 403) self.assertEqual(response.status_code, 404)
def test_document_type_quick_label_list_with_access(self): def test_document_type_quick_label_list_with_access(self):
self._create_quick_label() self._create_quick_label()
@@ -1,7 +1,10 @@
from __future__ import unicode_literals from __future__ import unicode_literals
from django.utils.encoding import force_text
from ..permissions import ( from ..permissions import (
permission_document_version_revert, permission_document_version_view permission_document_download, permission_document_version_revert,
permission_document_version_view
) )
from .base import GenericDocumentViewTestCase from .base import GenericDocumentViewTestCase
@@ -9,26 +12,101 @@ from .literals import TEST_SMALL_DOCUMENT_PATH, TEST_VERSION_COMMENT
class DocumentVersionTestCase(GenericDocumentViewTestCase): class DocumentVersionTestCase(GenericDocumentViewTestCase):
def setUp(self):
super(DocumentVersionTestCase, self).setUp()
self.login_user()
def _upload_new_version(self): def _upload_new_version(self):
with open(TEST_SMALL_DOCUMENT_PATH, mode='rb') as file_object: with open(TEST_SMALL_DOCUMENT_PATH, mode='rb') as file_object:
self.document.new_version( self.test_document_version = self.document.new_version(
comment=TEST_VERSION_COMMENT, file_object=file_object comment=TEST_VERSION_COMMENT, file_object=file_object
) )
def _request_document_version_detail_view(self):
return self.get(
viewname='documents:document_version_view',
kwargs={'document_version_id': self.test_document_version.pk}
)
def test_document_version_detail_no_permission(self):
self._upload_new_version()
response = self._request_document_version_detail_view()
self.assertEqual(response.status_code, 404)
def test_document_version_detail_with_access(self):
self._upload_new_version()
self.grant_access(
obj=self.document, permission=permission_document_version_view
)
response = self._request_document_version_detail_view()
self.assertEqual(response.status_code, 200)
def _request_document_version_download(self, data=None):
data = data or {}
return self.get(
viewname='documents:document_version_download', kwargs={
'document_version_id': self.document.latest_version.pk,
}, data=data
)
def test_document_version_download_view_no_permission(self):
response = self._request_document_version_download()
self.assertEqual(response.status_code, 404)
def test_document_version_download_view_with_permission(self):
# Set the expected_content_type for
# common.tests.mixins.ContentTypeCheckMixin
self.expected_content_type = '{}; charset=utf-8'.format(
self.document.latest_version.mimetype
)
self.grant_access(
obj=self.document, permission=permission_document_download
)
response = self._request_document_version_download()
self.assertEqual(response.status_code, 200)
with self.document.open() as file_object:
self.assert_download_response(
response=response, content=file_object.read(),
basename=force_text(self.document.latest_version),
mime_type='{}; charset=utf-8'.format(
self.document.latest_version.mimetype
)
)
def test_document_version_download_preserve_extension_view_with_permission(self):
# Set the expected_content_type for
# common.tests.mixins.ContentTypeCheckMixin
self.expected_content_type = '{}; charset=utf-8'.format(
self.document.latest_version.mimetype
)
self.grant_access(
obj=self.document, permission=permission_document_download
)
response = self._request_document_version_download(
data={'preserve_extension': True}
)
self.assertEqual(response.status_code, 200)
with self.document.open() as file_object:
self.assert_download_response(
response=response, content=file_object.read(),
basename=self.document.latest_version.get_rendered_string(
preserve_extension=True
), mime_type='{}; charset=utf-8'.format(
self.document.latest_version.mimetype
)
)
def _request_document_version_list_view(self): def _request_document_version_list_view(self):
return self.get( return self.get(
viewname='documents:document_version_list', viewname='documents:document_version_list',
kwargs={'document_pk': self.document.pk} kwargs={'document_id': self.document.pk}
) )
def test_document_version_list_no_permission(self): def test_document_version_list_no_permission(self):
self._upload_new_version() self._upload_new_version()
response = self._request_document_version_list_view() response = self._request_document_version_list_view()
self.assertEqual(response.status_code, 403) self.assertEqual(response.status_code, 404)
def test_document_version_list_with_access(self): def test_document_version_list_with_access(self):
self._upload_new_version() self._upload_new_version()
@@ -40,32 +118,28 @@ class DocumentVersionTestCase(GenericDocumentViewTestCase):
response=response, text=TEST_VERSION_COMMENT, status_code=200 response=response, text=TEST_VERSION_COMMENT, status_code=200
) )
def _request_document_version_revert_view(self, document_version): def _request_document_version_revert_view(self):
return self.post( return self.post(
viewname='documents:document_version_revert', viewname='documents:document_version_revert',
kwargs={'document_version_pk': document_version.pk} kwargs={'document_version_id': self.test_document_version_first.pk}
) )
def test_document_version_revert_no_permission(self): def test_document_version_revert_no_permission(self):
first_version = self.document.latest_version self.test_document_version_first = self.document.latest_version
self._upload_new_version() self._upload_new_version()
response = self._request_document_version_revert_view( response = self._request_document_version_revert_view()
document_version=first_version self.assertEqual(response.status_code, 302)
)
self.assertEqual(response.status_code, 403)
self.assertEqual(self.document.versions.count(), 2) self.assertEqual(self.document.versions.count(), 2)
def test_document_version_revert_with_access(self): def test_document_version_revert_with_access(self):
first_version = self.document.latest_version self.test_document_version_first = self.document.latest_version
self._upload_new_version() self._upload_new_version()
self.grant_access( self.grant_access(
obj=self.document, permission=permission_document_version_revert obj=self.document, permission=permission_document_version_revert
) )
response = self._request_document_version_revert_view( response = self._request_document_version_revert_view()
document_version=first_version
)
self.assertEqual(response.status_code, 302) self.assertEqual(response.status_code, 302)
self.assertEqual(self.document.versions.count(), 1) self.assertEqual(self.document.versions.count(), 1)
+109 -146
View File
@@ -3,18 +3,16 @@ from __future__ import unicode_literals
import os import os
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.utils.encoding import force_text
from mayan.apps.converter.models import Transformation from mayan.apps.converter.models import Transformation
from mayan.apps.converter.permissions import permission_transformation_delete from mayan.apps.converter.permissions import permission_transformation_delete
from ..literals import PAGE_RANGE_ALL from ..literals import PAGE_RANGE_ALL
from ..models import DeletedDocument, Document, DocumentType from ..models import Document, DocumentType, FavoriteDocument
from ..permissions import ( from ..permissions import (
permission_document_create, permission_document_download, permission_document_create, permission_document_download,
permission_document_print, permission_document_properties_edit, permission_document_print, permission_document_properties_edit,
permission_document_tools, permission_document_view, permission_document_tools, permission_document_view
permission_empty_trash
) )
from .base import GenericDocumentViewTestCase from .base import GenericDocumentViewTestCase
@@ -26,19 +24,15 @@ from .mixins import DocumentTypeQuickLabelTestMixin
class DocumentsViewsTestCase(GenericDocumentViewTestCase): class DocumentsViewsTestCase(GenericDocumentViewTestCase):
def setUp(self):
super(DocumentsViewsTestCase, self).setUp()
self.login_user()
def _request_document_properties_view(self): def _request_document_properties_view(self):
return self.get( return self.get(
viewname='documents:document_properties', viewname='documents:document_properties',
kwargs={'document_pk': self.document.pk} kwargs={'document_id': self.document.pk}
) )
def test_document_view_no_permissions(self): def test_document_view_no_permissions(self):
response = self._request_document_properties_view() response = self._request_document_properties_view()
self.assertEqual(response.status_code, 403) self.assertEqual(response.status_code, 404)
def test_document_view_with_permissions(self): def test_document_view_with_permissions(self):
self.grant_access( self.grant_access(
@@ -68,8 +62,8 @@ class DocumentsViewsTestCase(GenericDocumentViewTestCase):
def _request_document_type_edit(self, document_type): def _request_document_type_edit(self, document_type):
return self.post( return self.post(
viewname='documents:document_document_type_edit', viewname='documents:document_change_type',
kwargs={'document_pk': self.document.pk}, kwargs={'document_id': self.document.pk},
data={'document_type': document_type.pk} data={'document_type': document_type.pk}
) )
@@ -122,7 +116,7 @@ class DocumentsViewsTestCase(GenericDocumentViewTestCase):
def _request_multiple_document_type_edit(self, document_type): def _request_multiple_document_type_edit(self, document_type):
return self.post( return self.post(
viewname='documents:document_multiple_document_type_edit', viewname='documents:document_multiple_change_type',
data={ data={
'id_list': self.document.pk, 'id_list': self.document.pk,
'document_type': document_type.pk 'document_type': document_type.pk
@@ -174,40 +168,51 @@ class DocumentsViewsTestCase(GenericDocumentViewTestCase):
Document.objects.first().document_type, document_type_2 Document.objects.first().document_type, document_type_2
) )
def _request_document_download_form_view(self): def _request_document_download_form_get_view(self):
return self.get( return self.get(
viewname='documents:document_download_form', viewname='documents:document_download_form',
kwargs={'document_pk': self.document.pk} kwargs={'document_id': self.document.pk}
) )
def test_document_download_form_view_no_permission(self): def test_document_download_form_view_get_no_permission(self):
response = self._request_document_download_form_view() response = self._request_document_download_form_get_view()
self.assertEqual(response.status_code, 404)
self.assertNotContains( def test_document_download_form_get_view_with_access(self):
response=response, text=self.document.label, status_code=200
)
def test_document_download_form_view_with_access(self):
self.grant_access( self.grant_access(
obj=self.document, permission=permission_document_download obj=self.document, permission=permission_document_download
) )
response = self._request_document_download_form_view() response = self._request_document_download_form_get_view()
self.assertEqual(response.status_code, 200)
self.assertContains( def _request_document_download_form_post_view(self):
response=response, text=self.document.label, status_code=200 return self.post(
viewname='documents:document_download_form',
kwargs={'document_id': self.document.pk}
) )
def test_document_download_form_post_view_no_permission(self):
response = self._request_document_download_form_post_view()
self.assertEqual(response.status_code, 404)
def test_document_download_form_post_view_with_access(self):
self.grant_access(
obj=self.document, permission=permission_document_download
)
response = self._request_document_download_form_post_view()
self.assertEqual(response.status_code, 302)
def _request_document_download_view(self): def _request_document_download_view(self):
return self.get( return self.get(
viewname='documents:document_download', viewname='documents:document_download',
kwargs={'document_pk': self.document.pk} kwargs={'document_id': self.document.pk}
) )
def test_document_download_view_no_permission(self): def test_document_download_view_no_permission(self):
response = self._request_document_download_view() response = self._request_document_download_view()
self.assertEqual(response.status_code, 403) self.assertEqual(response.status_code, 404)
def test_document_download_view_with_permission(self): def test_document_download_view_with_access(self):
# Set the expected_content_type for # Set the expected_content_type for
# common.tests.mixins.ContentTypeCheckMixin # common.tests.mixins.ContentTypeCheckMixin
self.expected_content_type = '{}; charset=utf-8'.format( self.expected_content_type = '{}; charset=utf-8'.format(
@@ -235,7 +240,7 @@ class DocumentsViewsTestCase(GenericDocumentViewTestCase):
def test_document_multiple_download_view_no_permission(self): def test_document_multiple_download_view_no_permission(self):
response = self._request_document_multiple_download_view() response = self._request_document_multiple_download_view()
self.assertEqual(response.status_code, 403) self.assertEqual(response.status_code, 404)
def test_document_multiple_download_view_with_permission(self): def test_document_multiple_download_view_with_permission(self):
# Set the expected_content_type for # Set the expected_content_type for
@@ -257,70 +262,10 @@ class DocumentsViewsTestCase(GenericDocumentViewTestCase):
mime_type=self.document.file_mimetype mime_type=self.document.file_mimetype
) )
def _request_document_version_download(self, data=None):
data = data or {}
return self.get(
viewname='documents:document_version_download', kwargs={
'document_version_pk': self.document.latest_version.pk,
}, data=data
)
def test_document_version_download_view_no_permission(self):
response = self._request_document_version_download()
self.assertEqual(response.status_code, 403)
def test_document_version_download_view_with_permission(self):
# Set the expected_content_type for
# common.tests.mixins.ContentTypeCheckMixin
self.expected_content_type = '{}; charset=utf-8'.format(
self.document.latest_version.mimetype
)
self.grant_access(
obj=self.document, permission=permission_document_download
)
response = self._request_document_version_download()
self.assertEqual(response.status_code, 200)
with self.document.open() as file_object:
self.assert_download_response(
response=response, content=file_object.read(),
basename=force_text(self.document.latest_version),
mime_type='{}; charset=utf-8'.format(
self.document.latest_version.mimetype
)
)
def test_document_version_download_preserve_extension_view_with_permission(self):
# Set the expected_content_type for
# common.tests.mixins.ContentTypeCheckMixin
self.expected_content_type = '{}; charset=utf-8'.format(
self.document.latest_version.mimetype
)
self.grant_access(
obj=self.document, permission=permission_document_download
)
response = self._request_document_version_download(
data={'preserve_extension': True}
)
self.assertEqual(response.status_code, 200)
with self.document.open() as file_object:
self.assert_download_response(
response=response, content=file_object.read(),
basename=self.document.latest_version.get_rendered_string(
preserve_extension=True
), mime_type='{}; charset=utf-8'.format(
self.document.latest_version.mimetype
)
)
def _request_document_update_page_count_view(self): def _request_document_update_page_count_view(self):
return self.post( return self.post(
viewname='documents:document_update_page_count', viewname='documents:document_update_page_count',
kwargs={'document_pk': self.document.pk} kwargs={'document_id': self.document.pk}
) )
def test_document_update_page_count_view_no_permission(self): def test_document_update_page_count_view_no_permission(self):
@@ -372,7 +317,7 @@ class DocumentsViewsTestCase(GenericDocumentViewTestCase):
def _request_document_clear_transformations_view(self): def _request_document_clear_transformations_view(self):
return self.post( return self.post(
viewname='documents:document_clear_transformations', viewname='documents:document_clear_transformations',
kwargs={'document_pk': self.document.pk} kwargs={'document_id': self.document.pk}
) )
def test_document_clear_transformations_view_no_permission(self): def test_document_clear_transformations_view_no_permission(self):
@@ -482,57 +427,10 @@ class DocumentsViewsTestCase(GenericDocumentViewTestCase):
Transformation.objects.get_for_model(document_page).count(), 0 Transformation.objects.get_for_model(document_page).count(), 0
) )
def _request_empty_trash_view(self):
return self.post(viewname='documents:trash_can_empty')
def test_trash_can_empty_view_no_permission(self):
self.document.delete()
self.assertEqual(DeletedDocument.objects.count(), 1)
response = self._request_empty_trash_view()
self.assertEqual(response.status_code, 403)
self.assertEqual(DeletedDocument.objects.count(), 1)
def test_trash_can_empty_view_with_permission(self):
self.document.delete()
self.assertEqual(DeletedDocument.objects.count(), 1)
self.grant_permission(permission=permission_empty_trash)
response = self._request_empty_trash_view()
self.assertEqual(response.status_code, 302)
self.assertEqual(DeletedDocument.objects.count(), 0)
self.assertEqual(Document.objects.count(), 0)
def _request_document_page_view(self, document_page):
return self.get(
viewname='documents:document_page_view', kwargs={
'document_page_pk': document_page.pk
}
)
def test_document_page_view_no_permissions(self):
response = self._request_document_page_view(
document_page=self.document.pages.first()
)
self.assertEqual(response.status_code, 403)
def test_document_page_view_with_access(self):
self.grant_access(
obj=self.document, permission=permission_document_view
)
response = self._request_document_page_view(
document_page=self.document.pages.first()
)
self.assertContains(
response=response, text=force_text(self.document.pages.first()),
status_code=200
)
def _request_document_print_view(self): def _request_document_print_view(self):
return self.get( return self.get(
viewname='documents:document_print', kwargs={ viewname='documents:document_print', kwargs={
'document_pk': self.document.pk 'document_id': self.document.pk
}, data={ }, data={
'page_group': PAGE_RANGE_ALL 'page_group': PAGE_RANGE_ALL
} }
@@ -540,7 +438,7 @@ class DocumentsViewsTestCase(GenericDocumentViewTestCase):
def test_document_print_view_no_access(self): def test_document_print_view_no_access(self):
response = self._request_document_print_view() response = self._request_document_print_view()
self.assertEqual(response.status_code, 403) self.assertEqual(response.status_code, 404)
def test_document_print_view_with_access(self): def test_document_print_view_with_access(self):
self.grant_access( self.grant_access(
@@ -551,10 +449,6 @@ class DocumentsViewsTestCase(GenericDocumentViewTestCase):
class DocumentsQuickLabelViewsTestCase(DocumentTypeQuickLabelTestMixin, GenericDocumentViewTestCase): class DocumentsQuickLabelViewsTestCase(DocumentTypeQuickLabelTestMixin, GenericDocumentViewTestCase):
def setUp(self):
super(DocumentsQuickLabelViewsTestCase, self).setUp()
self.login_user()
def _request_document_quick_label_edit_view(self, extra_data=None): def _request_document_quick_label_edit_view(self, extra_data=None):
data = { data = {
'document_type_available_filenames': self.document_type_filename.pk, 'document_type_available_filenames': self.document_type_filename.pk,
@@ -566,14 +460,14 @@ class DocumentsQuickLabelViewsTestCase(DocumentTypeQuickLabelTestMixin, GenericD
return self.post( return self.post(
viewname='documents:document_edit', viewname='documents:document_edit',
kwargs={'document_pk': self.document.pk}, kwargs={'document_id': self.document.pk},
data=data data=data
) )
def test_document_quick_label_no_permission(self): def test_document_quick_label_no_permission(self):
self._create_quick_label() self._create_quick_label()
response = self._request_document_quick_label_edit_view() response = self._request_document_quick_label_edit_view()
self.assertEqual(response.status_code, 403) self.assertEqual(response.status_code, 404)
self.document.refresh_from_db() self.document.refresh_from_db()
def test_document_quick_label_with_access(self): def test_document_quick_label_with_access(self):
@@ -621,3 +515,72 @@ class DocumentsQuickLabelViewsTestCase(DocumentTypeQuickLabelTestMixin, GenericD
self.assertEqual( self.assertEqual(
self.document.label, self.document_type_filename.filename self.document.label, self.document_type_filename.filename
) )
class FavoriteDocumentsTestCase(GenericDocumentViewTestCase):
def _request_document_add_to_favorites_view(self):
return self.post(
viewname='documents:document_add_to_favorites',
kwargs={'document_id': self.document.pk}
)
def test_document_add_to_favorites_view_no_permission(self):
response = self._request_document_add_to_favorites_view()
self.assertEqual(response.status_code, 302)
self.assertEqual(FavoriteDocument.objects.count(), 0)
def test_document_add_to_favorites_view_with_access(self):
self.grant_access(
obj=self.document, permission=permission_document_view
)
response = self._request_document_add_to_favorites_view()
self.assertEqual(response.status_code, 302)
self.assertEqual(FavoriteDocument.objects.count(), 1)
def _document_add_to_favorites(self):
FavoriteDocument.objects.add_for_user(
document=self.document, user=self._test_case_user
)
def _request_document_list_favorites(self):
return self.get(
viewname='documents:document_list_favorites',
)
def test_document_list_favorites_view_no_permission(self):
self._document_add_to_favorites()
response = self._request_document_list_favorites()
self.assertNotContains(
response=response, text=self.document.label, status_code=200
)
def test_document_list_favorites_view_with_access(self):
self._document_add_to_favorites()
self.grant_access(
obj=self.document, permission=permission_document_view
)
response = self._request_document_list_favorites()
self.assertContains(
response=response, text=self.document.label, status_code=200
)
def _request_document_remove_from_favorites(self):
return self.post(
viewname='documents:document_remove_from_favorites',
kwargs={'document_id': self.document.pk}
)
def test_document_remove_from_favorites_view_no_permission(self):
self._document_add_to_favorites()
response = self._request_document_remove_from_favorites()
self.assertEqual(response.status_code, 302)
self.assertEqual(FavoriteDocument.objects.count(), 1)
def test_document_remove_from_favorites_view_with_access(self):
self._document_add_to_favorites()
self.grant_access(
obj=self.document, permission=permission_document_view
)
response = self._request_document_remove_from_favorites()
self.assertEqual(response.status_code, 302)
self.assertEqual(FavoriteDocument.objects.count(), 0)
@@ -7,10 +7,6 @@ from .literals import TEST_SMALL_DOCUMENT_FILENAME, TEST_SMALL_DOCUMENT_PATH
class DuplicatedDocumentsViewsTestCase(GenericDocumentViewTestCase): class DuplicatedDocumentsViewsTestCase(GenericDocumentViewTestCase):
def setUp(self):
super(DuplicatedDocumentsViewsTestCase, self).setUp()
self.login_user()
def _upload_duplicate_document(self): def _upload_duplicate_document(self):
with open(TEST_SMALL_DOCUMENT_PATH, mode='rb') as file_object: with open(TEST_SMALL_DOCUMENT_PATH, mode='rb') as file_object:
self.document_duplicate = self.document_type.new_document( self.document_duplicate = self.document_type.new_document(
@@ -23,7 +19,7 @@ class DuplicatedDocumentsViewsTestCase(GenericDocumentViewTestCase):
def _request_document_duplicates_list_view(self): def _request_document_duplicates_list_view(self):
return self.get( return self.get(
viewname='documents:document_duplicates_list', viewname='documents:document_duplicates_list',
kwargs={'document_pk': self.document.pk} kwargs={'document_id': self.document.pk}
) )
def test_duplicated_document_list_no_permissions(self): def test_duplicated_document_list_no_permissions(self):
@@ -53,7 +49,7 @@ class DuplicatedDocumentsViewsTestCase(GenericDocumentViewTestCase):
self._upload_duplicate_document() self._upload_duplicate_document()
response = self._request_document_duplicates_list_view() response = self._request_document_duplicates_list_view()
self.assertEqual(response.status_code, 403) self.assertEqual(response.status_code, 404)
def test_document_duplicates_list_with_access(self): def test_document_duplicates_list_with_access(self):
self._upload_duplicate_document() self._upload_duplicate_document()
+24 -45
View File
@@ -3,10 +3,6 @@ from __future__ import unicode_literals
from actstream.models import Action from actstream.models import Action
from django_downloadview import assert_download_response from django_downloadview import assert_download_response
from mayan.apps.user_management.tests.literals import (
TEST_USER_PASSWORD, TEST_USER_USERNAME
)
from ..events import event_document_download, event_document_view from ..events import event_document_download, event_document_view
from ..permissions import ( from ..permissions import (
permission_document_download, permission_document_view permission_document_download, permission_document_view
@@ -21,38 +17,30 @@ TEST_TRANSFORMATION_ARGUMENT = 'degrees: 180'
class DocumentEventsTestCase(GenericDocumentViewTestCase): class DocumentEventsTestCase(GenericDocumentViewTestCase):
def test_document_download_event_no_permissions(self): def _request_document_download_view(self):
self.login( return self.get(
username=TEST_USER_USERNAME, password=TEST_USER_PASSWORD viewname='documents:document_download',
kwargs={'document_id': self.document.pk}
) )
def test_document_download_event_no_permissions(self):
Action.objects.all().delete() Action.objects.all().delete()
response = self.get( response = self._request_document_download_view()
viewname='documents:document_download',
kwargs={'document_pk': self.document.pk}
)
self.assertEqual(response.status_code, 403) self.assertEqual(response.status_code, 404)
self.assertEqual(list(Action.objects.any(obj=self.document)), []) self.assertEqual(list(Action.objects.any(obj=self.document)), [])
def test_document_download_event_with_permissions(self): def test_document_download_event_with_permissions(self):
self.login(
username=TEST_USER_USERNAME, password=TEST_USER_PASSWORD
)
Action.objects.all().delete() Action.objects.all().delete()
self.role.permissions.add( self.grant_access(
permission_document_download.stored_permission obj=self.document, permission=permission_document_download
) )
self.expected_content_type = 'image/png; charset=utf-8' self.expected_content_type = 'image/png; charset=utf-8'
response = self.get( response = self._request_document_download_view()
viewname='documents:document_download',
kwargs={'document_pk': self.document.pk}
)
# Download the file to close the file descriptor # Download the file to close the file descriptor
with self.document.open() as file_object: with self.document.open() as file_object:
@@ -65,40 +53,31 @@ class DocumentEventsTestCase(GenericDocumentViewTestCase):
self.assertEqual(event.verb, event_document_download.id) self.assertEqual(event.verb, event_document_download.id)
self.assertEqual(event.target, self.document) self.assertEqual(event.target, self.document)
self.assertEqual(event.actor, self.user) self.assertEqual(event.actor, self._test_case_user)
def _request_document_preview_view(self):
return self.get(
viewname='documents:document_preview',
kwargs={'document_id': self.document.pk}
)
def test_document_view_event_no_permissions(self): def test_document_view_event_no_permissions(self):
self.login(
username=TEST_USER_USERNAME, password=TEST_USER_PASSWORD
)
Action.objects.all().delete() Action.objects.all().delete()
response = self.get( response = self._request_document_preview_view()
viewname='documents:document_preview',
kwargs={'document_pk': self.document.pk}
)
self.assertEqual(response.status_code, 403) self.assertEqual(response.status_code, 404)
self.assertEqual(list(Action.objects.any(obj=self.document)), []) self.assertEqual(list(Action.objects.any(obj=self.document)), [])
def test_document_view_event_with_permissions(self): def test_document_view_event_with_access(self):
self.login(
username=TEST_USER_USERNAME, password=TEST_USER_PASSWORD
)
Action.objects.all().delete() Action.objects.all().delete()
self.role.permissions.add( self.grant_access(obj=self.document, permission=permission_document_view)
permission_document_view.stored_permission response = self._request_document_preview_view()
) self.assertEqual(response.status_code, 200)
self.get(
viewname='documents:document_preview',
kwargs={'document_pk': self.document.pk}
)
event = Action.objects.any(obj=self.document).first() event = Action.objects.any(obj=self.document).first()
self.assertEqual(event.verb, event_document_view.id) self.assertEqual(event.verb, event_document_view.id)
self.assertEqual(event.target, self.document) self.assertEqual(event.target, self.document)
self.assertEqual(event.actor, self.user) self.assertEqual(event.actor, self._test_case_user)
+27 -44
View File
@@ -4,14 +4,13 @@ import time
from django.urls import reverse from django.urls import reverse
from mayan.apps.acls.models import AccessControlList
from ..links import ( from ..links import (
link_document_restore, link_document_version_download, link_trashed_document_restore, link_document_version_download,
link_document_version_revert link_document_version_revert
) )
from ..models import TrashedDocument
from ..permissions import ( from ..permissions import (
permission_document_download, permission_document_restore, permission_document_download, permission_trashed_document_restore,
permission_document_version_revert permission_document_version_revert
) )
@@ -26,15 +25,13 @@ class DocumentsLinksTestCase(GenericDocumentViewTestCase):
self.assertTrue(self.document.versions.count(), 2) self.assertTrue(self.document.versions.count(), 2)
self.login_user()
self.add_test_view(test_object=self.document.versions.first()) self.add_test_view(test_object=self.document.versions.first())
context = self.get_test_view() context = self.get_test_view()
resolved_link = link_document_version_revert.resolve(context=context) resolved_link = link_document_version_revert.resolve(context=context)
self.assertEqual(resolved_link, None) self.assertEqual(resolved_link, None)
def test_document_version_revert_link_with_permission(self): def test_document_version_revert_link_with_access(self):
# Needed by MySQL as milliseconds value is not store in timestamp # Needed by MySQL as milliseconds value is not store in timestamp
# field # field
time.sleep(1.01) time.sleep(1.01)
@@ -44,13 +41,8 @@ class DocumentsLinksTestCase(GenericDocumentViewTestCase):
self.assertTrue(self.document.versions.count(), 2) self.assertTrue(self.document.versions.count(), 2)
self.login_user() self.grant_access(
obj=self.document, permission=permission_document_version_revert
acl = AccessControlList.objects.create(
content_object=self.document, role=self.role
)
acl.permissions.add(
permission_document_version_revert.stored_permission
) )
self.add_test_view(test_object=self.document.versions.first()) self.add_test_view(test_object=self.document.versions.first())
@@ -61,27 +53,22 @@ class DocumentsLinksTestCase(GenericDocumentViewTestCase):
self.assertEqual( self.assertEqual(
resolved_link.url, resolved_link.url,
reverse( reverse(
'documents:document_version_revert', viewname='documents:document_version_revert',
args=(self.document.versions.first().pk,) kwargs={'document_version_id': self.document.versions.first().pk}
) )
) )
def test_document_version_download_link_no_permission(self): def test_document_version_download_link_no_permission(self):
self.login_user()
self.add_test_view(test_object=self.document.latest_version) self.add_test_view(test_object=self.document.latest_version)
context = self.get_test_view() context = self.get_test_view()
resolved_link = link_document_version_download.resolve(context=context) resolved_link = link_document_version_download.resolve(context=context)
self.assertEqual(resolved_link, None) self.assertEqual(resolved_link, None)
def test_document_version_download_link_with_permission(self): def test_document_version_download_link_with_access(self):
self.login_user() self.grant_access(
obj=self.document, permission=permission_document_download
acl = AccessControlList.objects.create(
content_object=self.document, role=self.role
) )
acl.permissions.add(permission_document_download.stored_permission)
self.add_test_view(test_object=self.document.latest_version) self.add_test_view(test_object=self.document.latest_version)
context = self.get_test_view() context = self.get_test_view()
@@ -91,45 +78,41 @@ class DocumentsLinksTestCase(GenericDocumentViewTestCase):
self.assertEqual( self.assertEqual(
resolved_link.url, resolved_link.url,
reverse( reverse(
'documents:document_version_download_form', viewname='documents:document_version_download_form',
args=(self.document.latest_version.pk,) kwargs={'document_version_id': self.document.latest_version.pk}
) )
) )
class DeletedDocumentsLinksTestCase(GenericDocumentViewTestCase): class DeletedDocumentsLinksTestCase(GenericDocumentViewTestCase):
def _request_trashed_document_restore_link(self):
self.add_test_view(
test_object=TrashedDocument.objects.get(pk=self.document.pk)
)
context = self.get_test_view()
return link_trashed_document_restore.resolve(context=context)
def test_deleted_document_restore_link_no_permission(self): def test_deleted_document_restore_link_no_permission(self):
self.document.delete() self.document.delete()
self.login_user() resolved_link = self._request_trashed_document_restore_link()
self.add_test_view(test_object=self.document)
context = self.get_test_view()
resolved_link = link_document_restore.resolve(context=context)
self.assertEqual(resolved_link, None) self.assertEqual(resolved_link, None)
def test_deleted_document_restore_link_with_permission(self): def test_deleted_document_restore_link_with_access(self):
self.document.delete() self.document.delete()
self.login_user() self.grant_access(
obj=self.document, permission=permission_trashed_document_restore
acl = AccessControlList.objects.create(
content_object=self.document, role=self.role
)
acl.permissions.add(
permission_document_restore.stored_permission
) )
self.add_test_view(test_object=self.document) resolved_link = self._request_trashed_document_restore_link()
context = self.get_test_view()
resolved_link = link_document_restore.resolve(context=context)
self.assertNotEqual(resolved_link, None) self.assertNotEqual(resolved_link, None)
self.assertEqual( self.assertEqual(
resolved_link.url, resolved_link.url,
reverse( reverse(
'documents:document_restore', viewname='documents:trashed_document_restore',
args=(self.document.pk,) kwargs={'trashed_document_id': self.document.pk}
) )
) )
+10 -10
View File
@@ -7,7 +7,7 @@ from mayan.apps.common.tests import BaseTestCase
from ..literals import STUB_EXPIRATION_INTERVAL from ..literals import STUB_EXPIRATION_INTERVAL
from ..models import ( from ..models import (
DeletedDocument, Document, DocumentType, DuplicatedDocument Document, DocumentType, DuplicatedDocument, TrashedDocument
) )
from .base import GenericDocumentTestCase from .base import GenericDocumentTestCase
@@ -58,12 +58,12 @@ class DocumentTestCase(DocumentTestMixin, BaseTestCase):
# Trash the document # Trash the document
self.document.delete() self.document.delete()
self.assertEqual(DeletedDocument.objects.count(), 1) self.assertEqual(TrashedDocument.objects.count(), 1)
self.assertEqual(Document.objects.count(), 0) self.assertEqual(Document.objects.count(), 0)
# Restore the document # Restore the document
self.document.restore() self.document.restore()
self.assertEqual(DeletedDocument.objects.count(), 0) self.assertEqual(TrashedDocument.objects.count(), 0)
self.assertEqual(Document.objects.count(), 1) self.assertEqual(Document.objects.count(), 1)
def test_trashing_documents(self): def test_trashing_documents(self):
@@ -71,12 +71,12 @@ class DocumentTestCase(DocumentTestMixin, BaseTestCase):
# Trash the document # Trash the document
self.document.delete() self.document.delete()
self.assertEqual(DeletedDocument.objects.count(), 1) self.assertEqual(TrashedDocument.objects.count(), 1)
self.assertEqual(Document.objects.count(), 0) self.assertEqual(Document.objects.count(), 0)
# Delete the document # Delete the document
self.document.delete() self.document.delete()
self.assertEqual(DeletedDocument.objects.count(), 0) self.assertEqual(TrashedDocument.objects.count(), 0)
self.assertEqual(Document.objects.count(), 0) self.assertEqual(Document.objects.count(), 0)
def test_auto_trashing(self): def test_auto_trashing(self):
@@ -94,12 +94,12 @@ class DocumentTestCase(DocumentTestMixin, BaseTestCase):
time.sleep(1.01) time.sleep(1.01)
self.assertEqual(Document.objects.count(), 1) self.assertEqual(Document.objects.count(), 1)
self.assertEqual(DeletedDocument.objects.count(), 0) self.assertEqual(TrashedDocument.objects.count(), 0)
DocumentType.objects.check_trash_periods() DocumentType.objects.check_trash_periods()
self.assertEqual(Document.objects.count(), 0) self.assertEqual(Document.objects.count(), 0)
self.assertEqual(DeletedDocument.objects.count(), 1) self.assertEqual(TrashedDocument.objects.count(), 1)
def test_auto_delete(self): def test_auto_delete(self):
""" """
@@ -112,12 +112,12 @@ class DocumentTestCase(DocumentTestMixin, BaseTestCase):
self.document_type.save() self.document_type.save()
self.assertEqual(Document.objects.count(), 1) self.assertEqual(Document.objects.count(), 1)
self.assertEqual(DeletedDocument.objects.count(), 0) self.assertEqual(TrashedDocument.objects.count(), 0)
self.document.delete() self.document.delete()
self.assertEqual(Document.objects.count(), 0) self.assertEqual(Document.objects.count(), 0)
self.assertEqual(DeletedDocument.objects.count(), 1) self.assertEqual(TrashedDocument.objects.count(), 1)
# Needed by MySQL as milliseconds value is not stored in timestamp # Needed by MySQL as milliseconds value is not stored in timestamp
# field # field
@@ -126,7 +126,7 @@ class DocumentTestCase(DocumentTestMixin, BaseTestCase):
DocumentType.objects.check_delete_periods() DocumentType.objects.check_delete_periods()
self.assertEqual(Document.objects.count(), 0) self.assertEqual(Document.objects.count(), 0)
self.assertEqual(DeletedDocument.objects.count(), 0) self.assertEqual(TrashedDocument.objects.count(), 0)
class PDFCompatibilityTestCase(BaseTestCase): class PDFCompatibilityTestCase(BaseTestCase):
+2 -2
View File
@@ -9,12 +9,12 @@ from mayan.apps.documents.tests import DocumentTestMixin
class DocumentSearchTestCase(DocumentTestMixin, BaseTestCase): class DocumentSearchTestCase(DocumentTestMixin, BaseTestCase):
def _perform_document_page_search(self): def _perform_document_page_search(self):
return document_page_search.search( return document_page_search.search(
query_string={'q': self.document.label}, user=self.user query_string={'q': self.document.label}, user=self._test_case_user
) )
def _perform_document_search(self): def _perform_document_search(self):
return document_search.search( return document_search.search(
query_string={'q': self.document.label}, user=self.user query_string={'q': self.document.label}, user=self._test_case_user
) )
def test_document_page_search_no_access(self): def test_document_page_search_no_access(self):
@@ -1,56 +1,26 @@
from __future__ import unicode_literals from __future__ import unicode_literals
from ..models import DeletedDocument, Document from ..models import Document, TrashedDocument
from ..permissions import ( from ..permissions import (
permission_document_delete, permission_document_restore, permission_document_trash, permission_document_view,
permission_document_trash, permission_document_view permission_empty_trash, permission_trashed_document_delete,
permission_trashed_document_restore
) )
from .base import GenericDocumentViewTestCase from .base import GenericDocumentViewTestCase
class DeletedDocumentTestCase(GenericDocumentViewTestCase): class TrashedDocumentTestCase(GenericDocumentViewTestCase):
def setUp(self):
super(DeletedDocumentTestCase, self).setUp()
self.login_user()
def _request_document_restore_view(self):
return self.post(
viewname='documents:document_restore',
kwargs={'document_pk': self.document.pk}
)
def test_document_restore_view_no_permission(self):
self.document.delete()
self.assertEqual(Document.objects.count(), 0)
response = self._request_document_restore_view()
self.assertEqual(response.status_code, 403)
self.assertEqual(DeletedDocument.objects.count(), 1)
self.assertEqual(Document.objects.count(), 0)
def test_document_restore_view_with_access(self):
self.document.delete()
self.assertEqual(Document.objects.count(), 0)
self.grant_access(
obj=self.document, permission=permission_document_restore
)
response = self._request_document_restore_view()
self.assertEqual(response.status_code, 302)
self.assertEqual(DeletedDocument.objects.count(), 0)
self.assertEqual(Document.objects.count(), 1)
def _request_document_trash_view(self): def _request_document_trash_view(self):
return self.post( return self.post(
viewname='documents:document_trash', viewname='documents:document_trash',
kwargs={'document_pk': self.document.pk} kwargs={'document_id': self.document.pk}
) )
def test_document_trash_no_permissions(self): def test_document_trash_no_permissions(self):
response = self._request_document_trash_view() response = self._request_document_trash_view()
self.assertEqual(response.status_code, 403) self.assertEqual(response.status_code, 302)
self.assertEqual(DeletedDocument.objects.count(), 0) self.assertEqual(TrashedDocument.objects.count(), 0)
self.assertEqual(Document.objects.count(), 1) self.assertEqual(Document.objects.count(), 1)
def test_document_trash_with_access(self): def test_document_trash_with_access(self):
@@ -60,58 +30,107 @@ class DeletedDocumentTestCase(GenericDocumentViewTestCase):
response = self._request_document_trash_view() response = self._request_document_trash_view()
self.assertEqual(response.status_code, 302) self.assertEqual(response.status_code, 302)
self.assertEqual(DeletedDocument.objects.count(), 1) self.assertEqual(TrashedDocument.objects.count(), 1)
self.assertEqual(Document.objects.count(), 0) self.assertEqual(Document.objects.count(), 0)
def _request_document_delete_view(self): def _request_trashed_document_restore_view(self):
return self.post( return self.post(
viewname='documents:document_delete', viewname='documents:trashed_document_restore',
kwargs={'document_pk': self.document.pk} kwargs={'trashed_document_id': self.document.pk}
) )
def test_document_delete_no_permissions(self): def test_trashed_document_restore_view_no_permission(self):
self.document.delete() self.document.delete()
self.assertEqual(Document.objects.count(), 0) self.assertEqual(Document.objects.count(), 0)
self.assertEqual(DeletedDocument.objects.count(), 1)
response = self._request_document_delete_view() response = self._request_trashed_document_restore_view()
self.assertEqual(response.status_code, 403) self.assertEqual(response.status_code, 302)
self.assertEqual(TrashedDocument.objects.count(), 1)
self.assertEqual(Document.objects.count(), 0) self.assertEqual(Document.objects.count(), 0)
self.assertEqual(DeletedDocument.objects.count(), 1)
def test_document_delete_with_access(self): def test_trashed_document_restore_view_with_access(self):
self.document.delete() self.document.delete()
self.assertEqual(Document.objects.count(), 0) self.assertEqual(Document.objects.count(), 0)
self.assertEqual(DeletedDocument.objects.count(), 1)
self.grant_access( self.grant_access(
obj=self.document, permission=permission_document_delete obj=self.document, permission=permission_trashed_document_restore
)
response = self._request_trashed_document_restore_view()
self.assertEqual(response.status_code, 302)
self.assertEqual(TrashedDocument.objects.count(), 0)
self.assertEqual(Document.objects.count(), 1)
def _request_trashed_document_delete_view(self):
return self.post(
viewname='documents:trashed_document_delete',
kwargs={'trashed_document_id': self.document.pk}
) )
response = self._request_document_delete_view() def test_trashed_document_delete_no_permissions(self):
self.document.delete()
self.assertEqual(Document.objects.count(), 0)
self.assertEqual(TrashedDocument.objects.count(), 1)
response = self._request_trashed_document_delete_view()
self.assertEqual(response.status_code, 302) self.assertEqual(response.status_code, 302)
self.assertEqual(DeletedDocument.objects.count(), 0) self.assertEqual(Document.objects.count(), 0)
self.assertEqual(TrashedDocument.objects.count(), 1)
def test_trashed_document_delete_with_access(self):
self.document.delete()
self.assertEqual(Document.objects.count(), 0)
self.assertEqual(TrashedDocument.objects.count(), 1)
self.grant_access(
obj=self.document, permission=permission_trashed_document_delete
)
response = self._request_trashed_document_delete_view()
self.assertEqual(response.status_code, 302)
self.assertEqual(TrashedDocument.objects.count(), 0)
self.assertEqual(Document.objects.count(), 0) self.assertEqual(Document.objects.count(), 0)
def _request_document_list_deleted_view(self): def _request_trashed_document_list_view(self):
return self.get(viewname='documents:document_list_deleted') return self.get(viewname='documents:trashed_document_list')
def test_deleted_document_list_view_no_permissions(self): def test_trashed_document_list_view_no_permissions(self):
self.document.delete() self.document.delete()
response = self._request_document_list_deleted_view() response = self._request_trashed_document_list_view()
self.assertNotContains( self.assertNotContains(
response=response, text=self.document.label, status_code=200 response=response, text=self.document.label, status_code=200
) )
def test_deleted_document_list_view_with_access(self): def test_trashed_document_list_view_with_access(self):
self.document.delete() self.document.delete()
self.grant_access( self.grant_access(
obj=self.document, permission=permission_document_view obj=self.document, permission=permission_document_view
) )
response = self._request_document_list_deleted_view() response = self._request_trashed_document_list_view()
self.assertContains( self.assertContains(
response=response, text=self.document.label, status_code=200 response=response, text=self.document.label, status_code=200
) )
def _request_empty_trash_view(self):
return self.post(viewname='documents:trash_can_empty')
def test_trash_can_empty_view_no_permission(self):
self.document.delete()
self.assertEqual(TrashedDocument.objects.count(), 1)
response = self._request_empty_trash_view()
self.assertEqual(response.status_code, 403)
self.assertEqual(TrashedDocument.objects.count(), 1)
def test_trash_can_empty_view_with_permission(self):
self.document.delete()
self.assertEqual(TrashedDocument.objects.count(), 1)
self.grant_permission(permission=permission_empty_trash)
response = self._request_empty_trash_view()
self.assertEqual(response.status_code, 302)
self.assertEqual(TrashedDocument.objects.count(), 0)
self.assertEqual(Document.objects.count(), 0)
+147 -110
View File
@@ -2,29 +2,34 @@ from __future__ import unicode_literals
from django.conf.urls import url from django.conf.urls import url
"""
from .api_views import ( from .api_views import (
APIDeletedDocumentListView, APIDeletedDocumentRestoreView, APITrashedDocumentListView, APITrashedDocumentRestoreView,
APIDeletedDocumentView, APIDocumentDownloadView, APIDocumentListView, APITrashedDocumentView, APIDocumentDownloadView, APIDocumentListView,
APIDocumentPageImageView, APIDocumentPageView, APIDocumentPageImageView, APIDocumentPageView,
APIDocumentTypeDocumentListView, APIDocumentTypeListView, APIDocumentTypeDocumentListView, APIDocumentTypeListView,
APIDocumentTypeView, APIDocumentVersionDownloadView, APIDocumentTypeView, APIDocumentVersionDownloadView,
APIDocumentVersionPageListView, APIDocumentVersionsListView, APIDocumentVersionPageListView, APIDocumentVersionsListView,
APIDocumentVersionView, APIDocumentView, APIRecentDocumentListView APIDocumentVersionView, APIDocumentView, APIRecentDocumentListView
) )
"""
from .api_views import (
DocumentPageViewSet, DocumentTypeViewSet, DocumentVersionViewSet,
DocumentViewSet
)
from .views import ( from .views import (
ClearImageCacheView, DeletedDocumentDeleteManyView, ClearImageCacheView, DocumentChangeTypeView, DocumentDownloadFormView,
DeletedDocumentDeleteView, DeletedDocumentListView,
DocumentDocumentTypeEditView, DocumentDownloadFormView,
DocumentDownloadView, DocumentDuplicatesListView, DocumentEditView, DocumentDownloadView, DocumentDuplicatesListView, DocumentEditView,
DocumentListView, DocumentPageListView, DocumentPageNavigationFirst, DocumentListView, DocumentPageListView, DocumentPageNavigationFirst,
DocumentPageNavigationLast, DocumentPageNavigationNext, DocumentPageNavigationLast, DocumentPageNavigationNext,
DocumentPageNavigationPrevious, DocumentPageRotateLeftView, DocumentPageNavigationPrevious, DocumentPageRotateLeftView,
DocumentPageRotateRightView, DocumentPageView, DocumentPageViewResetView, DocumentPageRotateRightView, DocumentPageView, DocumentPageViewResetView,
DocumentPageZoomInView, DocumentPageZoomOutView, DocumentPreviewView, DocumentPageZoomInView, DocumentPageZoomOutView, DocumentPreviewView,
DocumentPrint, DocumentRestoreManyView, DocumentRestoreView, DocumentPrintView, DocumentTransformationsClearView,
DocumentTransformationsClearView, DocumentTransformationsCloneView, DocumentTransformationsCloneView, DocumentTrashView,
DocumentTrashManyView, DocumentTrashView, DocumentTypeCreateView, DocumentTypeCreateView, DocumentTypeDeleteView,
DocumentTypeDeleteView, DocumentTypeDocumentListView, DocumentTypeEditView, DocumentTypeDocumentListView, DocumentTypeEditView,
DocumentTypeFilenameCreateView, DocumentTypeFilenameDeleteView, DocumentTypeFilenameCreateView, DocumentTypeFilenameDeleteView,
DocumentTypeFilenameEditView, DocumentTypeFilenameListView, DocumentTypeFilenameEditView, DocumentTypeFilenameListView,
DocumentTypeListView, DocumentUpdatePageCountView, DocumentTypeListView, DocumentUpdatePageCountView,
@@ -33,12 +38,51 @@ from .views import (
DocumentView, DuplicatedDocumentListView, EmptyTrashCanView, DocumentView, DuplicatedDocumentListView, EmptyTrashCanView,
FavoriteAddView, FavoriteDocumentListView, FavoriteRemoveView, FavoriteAddView, FavoriteDocumentListView, FavoriteRemoveView,
RecentAccessDocumentListView, RecentAddedDocumentListView, RecentAccessDocumentListView, RecentAddedDocumentListView,
ScanDuplicatedDocuments ScanDuplicatedDocuments, TrashedDocumentDeleteView, TrashedDocumentListView,
TrashedDocumentRestoreView
)
urlpatterns_trashed_documents = (
url(
regex=r'^documents/(?P<document_id>\d+)/trash/$',
name='document_trash', view=DocumentTrashView.as_view()
),
url(
regex=r'^documents/multiple/trash/$', name='document_multiple_trash',
view=DocumentTrashView.as_view()
),
url(
regex=r'^trashed_documents/$', name='trashed_document_list',
view=TrashedDocumentListView.as_view()
),
url(
regex=r'^trashed_documents/(?P<trashed_document_id>\d+)/restore/$',
name='trashed_document_restore',
view=TrashedDocumentRestoreView.as_view()
),
url(
regex=r'^trashed_documents/multiple/restore/$',
name='trashed_document_multiple_restore',
view=TrashedDocumentRestoreView.as_view()
),
url(
regex=r'^trashed_documents/(?P<trashed_document_id>\d+)/delete/$',
name='trashed_document_delete', view=TrashedDocumentDeleteView.as_view()
),
url(
regex=r'^trashed_documents/multiple/delete/$',
name='trashed_document_multiple_delete',
view=TrashedDocumentDeleteView.as_view()
),
url(
regex=r'^trash/empty/$', name='trash_can_empty',
view=EmptyTrashCanView.as_view()
)
) )
urlpatterns = [ urlpatterns = [
url( url(
regex=r'^documents/all/$', name='document_list', regex=r'^documents/$', name='document_list',
view=DocumentListView.as_view() view=DocumentListView.as_view()
), ),
url( url(
@@ -50,10 +94,8 @@ urlpatterns = [
regex=r'^documents/recent_added/$', name='document_list_recent_added', regex=r'^documents/recent_added/$', name='document_list_recent_added',
view=RecentAddedDocumentListView.as_view() view=RecentAddedDocumentListView.as_view()
), ),
url(
regex=r'^documents/deleted/$', name='document_list_deleted',
view=DeletedDocumentListView.as_view()
),
url( url(
regex=r'^documents/duplicated/$', name='duplicated_document_list', regex=r'^documents/duplicated/$', name='duplicated_document_list',
view=DuplicatedDocumentListView.as_view() view=DuplicatedDocumentListView.as_view()
@@ -63,20 +105,20 @@ urlpatterns = [
view=FavoriteDocumentListView.as_view() view=FavoriteDocumentListView.as_view()
), ),
url( url(
regex=r'^documents/(?P<document_pk>\d+)/preview/$', regex=r'^documents/(?P<document_id>\d+)/preview/$',
name='document_preview', view=DocumentPreviewView.as_view() name='document_preview', view=DocumentPreviewView.as_view()
), ),
url( url(
regex=r'^documents/(?P<document_pk>\d+)/properties/$', regex=r'^documents/(?P<document_id>\d+)/properties/$',
name='document_properties', view=DocumentView.as_view() name='document_properties', view=DocumentView.as_view()
), ),
url( url(
regex=r'^documents/(?P<document_pk>\d+)/duplicates/$', regex=r'^documents/(?P<document_id>\d+)/duplicates/$',
name='document_duplicates_list', name='document_duplicates_list',
view=DocumentDuplicatesListView.as_view() view=DocumentDuplicatesListView.as_view()
), ),
url( url(
regex=r'^documents/(?P<document_pk>\d+)/add_to_favorites/$', regex=r'^documents/(?P<document_id>\d+)/add_to_favorites/$',
name='document_add_to_favorites', view=FavoriteAddView.as_view() name='document_add_to_favorites', view=FavoriteAddView.as_view()
), ),
url( url(
@@ -85,7 +127,7 @@ urlpatterns = [
view=FavoriteAddView.as_view() view=FavoriteAddView.as_view()
), ),
url( url(
regex=r'^documents/(?P<document_pk>\d+)/remove_from_favorites/$', regex=r'^documents/(?P<document_id>\d+)/remove_from_favorites/$',
name='document_remove_from_favorites', name='document_remove_from_favorites',
view=FavoriteRemoveView.as_view() view=FavoriteRemoveView.as_view()
), ),
@@ -95,50 +137,25 @@ urlpatterns = [
view=FavoriteRemoveView.as_view() view=FavoriteRemoveView.as_view()
), ),
url( url(
regex=r'^documents/(?P<document_pk>\d+)/restore/$', regex=r'^documents/(?P<document_id>\d+)/type/$',
name='document_restore', view=DocumentRestoreView.as_view() name='document_change_type',
), view=DocumentChangeTypeView.as_view()
url(
regex=r'^documents/multiple/restore/$',
name='document_multiple_restore',
view=DocumentRestoreManyView.as_view()
),
url(
regex=r'^documents/(?P<document_pk>\d+)/delete/$',
name='document_delete', view=DeletedDocumentDeleteView.as_view()
),
url(
regex=r'^documents/multiple/delete/$', name='document_multiple_delete',
view=DeletedDocumentDeleteManyView.as_view()
),
url(
regex=r'^documents/(?P<document_pk>\d+)/type/$',
name='document_document_type_edit',
view=DocumentDocumentTypeEditView.as_view()
), ),
url( url(
regex=r'^documents/multiple/type/$', regex=r'^documents/multiple/type/$',
name='document_multiple_document_type_edit', name='document_multiple_change_type',
view=DocumentDocumentTypeEditView.as_view() view=DocumentChangeTypeView.as_view()
), ),
url( url(
regex=r'^documents/(?P<document_pk>\d+)/trash/$', regex=r'^documents/(?P<document_id>\d+)/edit/$', name='document_edit',
name='document_trash', view=DocumentTrashView.as_view()
),
url(
regex=r'^documents/multiple/trash/$', name='document_multiple_trash',
view=DocumentTrashManyView.as_view()
),
url(
regex=r'^documents/(?P<document_pk>\d+)/edit/$', name='document_edit',
view=DocumentEditView.as_view() view=DocumentEditView.as_view()
), ),
url( url(
regex=r'^documents/(?P<document_pk>\d+)/print/$', regex=r'^documents/(?P<document_id>\d+)/print/$',
name='document_print', view=DocumentPrint.as_view() name='document_print', view=DocumentPrintView.as_view()
), ),
url( url(
regex=r'^documents/(?P<document_pk>\d+)/reset_page_count/$', regex=r'^documents/(?P<document_id>\d+)/reset_page_count/$',
name='document_update_page_count', name='document_update_page_count',
view=DocumentUpdatePageCountView.as_view() view=DocumentUpdatePageCountView.as_view()
), ),
@@ -148,11 +165,11 @@ urlpatterns = [
view=DocumentUpdatePageCountView.as_view() view=DocumentUpdatePageCountView.as_view()
), ),
url( url(
regex=r'^documents/(?P<document_pk>\d+)/download/form/$', regex=r'^documents/(?P<document_id>\d+)/download/form/$',
name='document_download_form', view=DocumentDownloadFormView.as_view() name='document_download_form', view=DocumentDownloadFormView.as_view()
), ),
url( url(
regex=r'^documents/(?P<document_pk>\d+)/download/$', regex=r'^documents/(?P<document_id>\d+)/download/$',
name='document_download', view=DocumentDownloadView.as_view() name='document_download', view=DocumentDownloadView.as_view()
), ),
url( url(
@@ -165,46 +182,46 @@ urlpatterns = [
name='document_multiple_download', view=DocumentDownloadView.as_view() name='document_multiple_download', view=DocumentDownloadView.as_view()
), ),
url( url(
regex=r'^documents/(?P<document_pk>\d+)/clear_transformations/$', regex=r'^documents/(?P<document_id>\d+)/transformations/clear/$',
name='document_clear_transformations', name='document_clear_transformations',
view=DocumentTransformationsClearView.as_view() view=DocumentTransformationsClearView.as_view()
), ),
url( url(
regex=r'^documents/(?P<document_pk>\d+)/clone_transformations/$', regex=r'^documents/(?P<document_id>\d+)/transformations/clone/$',
name='document_clone_transformations', name='document_clone_transformations',
view=DocumentTransformationsCloneView.as_view() view=DocumentTransformationsCloneView.as_view()
), ),
url( url(
regex=r'^documents/(?P<document_pk>\d+)/version/all/$', regex=r'^documents/(?P<document_id>\d+)/versions/$',
name='document_version_list', name='document_version_list',
view=DocumentVersionListView.as_view() view=DocumentVersionListView.as_view()
), ),
url( url(
regex=r'^documents/versions/(?P<document_version_pk>\d+)/download/form/$', regex=r'^documents/versions/(?P<document_version_id>\d+)/download/form/$',
name='document_version_download_form', name='document_version_download_form',
view=DocumentVersionDownloadFormView.as_view() view=DocumentVersionDownloadFormView.as_view()
), ),
url( url(
regex=r'^documents/versions/(?P<document_version_pk>\d+)/$', regex=r'^documents/versions/(?P<document_version_id>\d+)/$',
name='document_version_view', view=DocumentVersionView.as_view() name='document_version_view', view=DocumentVersionView.as_view()
), ),
url( url(
regex=r'^documents/versions/(?P<document_version_pk>\d+)/download/$', regex=r'^documents/versions/(?P<document_version_id>\d+)/download/$',
name='document_version_download', name='document_version_download',
view=DocumentVersionDownloadView.as_view() view=DocumentVersionDownloadView.as_view()
), ),
url( url(
regex=r'^documents/versions/(?P<document_version_pk>\d+)/revert/$', regex=r'^documents/versions/(?P<document_version_id>\d+)/revert/$',
name='document_version_revert', name='document_version_revert',
view=DocumentVersionRevertView.as_view() view=DocumentVersionRevertView.as_view()
), ),
url( url(
regex=r'^documents/(?P<document_pk>\d+)/pages/$', regex=r'^documents/(?P<document_id>\d+)/pages/$',
name='document_pages', name='document_pages',
view=DocumentPageListView.as_view() view=DocumentPageListView.as_view()
), ),
url( url(
regex=r'^documents/multiple/clear_transformations/$', regex=r'^documents/multiple/transformations/clear/$',
name='document_multiple_clear_transformations', name='document_multiple_clear_transformations',
view=DocumentTransformationsClearView.as_view() view=DocumentTransformationsClearView.as_view()
), ),
@@ -213,96 +230,92 @@ urlpatterns = [
view=ClearImageCacheView.as_view() view=ClearImageCacheView.as_view()
), ),
url( url(
regex=r'^trash_can/empty/$', name='trash_can_empty', regex=r'^documents/pages/(?P<document_page_id>\d+)/$',
view=EmptyTrashCanView.as_view()
),
url(
regex=r'^pages/(?P<document_page_pk>\d+)/$',
name='document_page_view', view=DocumentPageView.as_view() name='document_page_view', view=DocumentPageView.as_view()
), ),
url( url(
regex=r'^pages/(?P<document_page_pk>\d+)/navigation/next/$', regex=r'^documents/pages/(?P<document_page_id>\d+)/navigation/next/$',
name='document_page_navigation_next', name='document_page_navigation_next',
view=DocumentPageNavigationNext.as_view() view=DocumentPageNavigationNext.as_view()
), ),
url( url(
regex=r'^pages/(?P<document_page_pk>\d+)/navigation/previous/$', regex=r'^documents/pages/(?P<document_page_id>\d+)/navigation/previous/$',
name='document_page_navigation_previous', name='document_page_navigation_previous',
view=DocumentPageNavigationPrevious.as_view() view=DocumentPageNavigationPrevious.as_view()
), ),
url( url(
regex=r'^pages/(?P<document_page_pk>\d+)/navigation/first/$', regex=r'^documents/pages/(?P<document_page_id>\d+)/navigation/first/$',
name='document_page_navigation_first', name='document_page_navigation_first',
view=DocumentPageNavigationFirst.as_view() view=DocumentPageNavigationFirst.as_view()
), ),
url( url(
regex=r'^pages/(?P<document_page_pk>\d+)/navigation/last/$', regex=r'^documents/pages/(?P<document_page_id>\d+)/navigation/last/$',
name='document_page_navigation_last', name='document_page_navigation_last',
view=DocumentPageNavigationLast.as_view() view=DocumentPageNavigationLast.as_view()
), ),
url( url(
regex=r'^pages/(?P<document_page_pk>\d+)/zoom/in/$', regex=r'^documents/pages/(?P<document_page_id>\d+)/zoom/in/$',
name='document_page_zoom_in', view=DocumentPageZoomInView.as_view() name='document_page_zoom_in', view=DocumentPageZoomInView.as_view()
), ),
url( url(
regex=r'^pages/(?P<document_page_pk>\d+)/zoom/out/$', regex=r'^documents/pages/(?P<document_page_id>\d+)/zoom/out/$',
name='document_page_zoom_out', view=DocumentPageZoomOutView.as_view() name='document_page_zoom_out', view=DocumentPageZoomOutView.as_view()
), ),
url( url(
regex=r'^pages/(?P<document_page_pk>\d+)/rotate/left/$', regex=r'^documents/pages/(?P<document_page_id>\d+)/rotate/left/$',
name='document_page_rotate_left', name='document_page_rotate_left',
view=DocumentPageRotateLeftView.as_view() view=DocumentPageRotateLeftView.as_view()
), ),
url( url(
regex=r'^pages/(?P<document_page_pk>\d+)/rotate/right/$', regex=r'^documents/pages/(?P<document_page_id>\d+)/rotate/right/$',
name='document_page_rotate_right', name='document_page_rotate_right',
view=DocumentPageRotateRightView.as_view() view=DocumentPageRotateRightView.as_view()
), ),
url( url(
regex=r'^pages/(?P<document_page_pk>\d+)/reset/$', regex=r'^documents/pages/(?P<document_page_id>\d+)/reset/$',
name='document_page_view_reset', name='document_page_view_reset',
view=DocumentPageViewResetView.as_view() view=DocumentPageViewResetView.as_view()
), ),
# Admin views # Admin views
url( url(
regex=r'^types/$', name='document_type_list', regex=r'^documents_types/$', name='document_type_list',
view=DocumentTypeListView.as_view() view=DocumentTypeListView.as_view()
), ),
url( url(
regex=r'^types/create/$', name='document_type_create', regex=r'^documents_types/create/$', name='document_type_create',
view=DocumentTypeCreateView.as_view() view=DocumentTypeCreateView.as_view()
), ),
url( url(
regex=r'^types/(?P<document_type_pk>\d+)/edit/$', name='document_type_edit', regex=r'^documents_types/(?P<document_type_id>\d+)/edit/$',
view=DocumentTypeEditView.as_view() name='document_type_edit', view=DocumentTypeEditView.as_view()
), ),
url( url(
regex=r'^types/(?P<document_type_pk>\d+)/delete/$', name='document_type_delete', regex=r'^documents_types/(?P<document_type_id>\d+)/delete/$',
view=DocumentTypeDeleteView.as_view() name='document_type_delete', view=DocumentTypeDeleteView.as_view()
), ),
url( url(
regex=r'^types/(?P<document_type_pk>\d+)/documents/$', regex=r'^documents_types/(?P<document_type_id>\d+)/documents/$',
name='document_type_document_list', name='document_type_document_list',
view=DocumentTypeDocumentListView.as_view() view=DocumentTypeDocumentListView.as_view()
), ),
url( url(
regex=r'^types/(?P<document_type_pk>\d+)/filenames/create/$', regex=r'^documents_types/(?P<document_type_id>\d+)/filenames/$',
name='document_type_filename_create',
view=DocumentTypeFilenameCreateView.as_view()
),
url(
regex=r'^types/(?P<document_type_pk>\d+)/filenames/$',
name='document_type_filename_list', name='document_type_filename_list',
view=DocumentTypeFilenameListView.as_view() view=DocumentTypeFilenameListView.as_view()
), ),
url( url(
regex=r'^types/filenames/(?P<filename_pk>\d+)/edit/$', regex=r'^documents_types/(?P<document_type_id>\d+)/filenames/create/$',
name='document_type_filename_create',
view=DocumentTypeFilenameCreateView.as_view()
),
url(
regex=r'^documents_types/filenames/(?P<filename_id>\d+)/edit/$',
name='document_type_filename_edit', name='document_type_filename_edit',
view=DocumentTypeFilenameEditView.as_view() view=DocumentTypeFilenameEditView.as_view()
), ),
url( url(
regex=r'^types/filenames/(?P<filename_pk>\d+)/delete/$', regex=r'^documents_types/filenames/(?P<filename_id>\d+)/delete/$',
name='document_type_filename_delete', name='document_type_filename_delete',
view=DocumentTypeFilenameDeleteView.as_view() view=DocumentTypeFilenameDeleteView.as_view()
), ),
@@ -316,17 +329,20 @@ urlpatterns = [
), ),
] ]
api_urls = [ urlpatterns.extend(urlpatterns_trashed_documents)
api_urls = []
"""
url( url(
regex=r'^document_types/$', name='documenttype-list', regex=r'^document_types/$', name='documenttype-list',
view=APIDocumentTypeListView.as_view() view=APIDocumentTypeListView.as_view()
), ),
url( url(
regex=r'^document_types/(?P<document_type_pk>\d+)/$', regex=r'^document_types/(?P<document_type_id>\d+)/$',
name='documenttype-detail', view=APIDocumentTypeView.as_view() name='documenttype-detail', view=APIDocumentTypeView.as_view()
), ),
url( url(
regex=r'^document_types/(?P<document_type_pk>\d+)/documents/$', regex=r'^document_types/(?P<document_type_id>\d+)/documents/$',
name='documenttype-document-list', name='documenttype-document-list',
view=APIDocumentTypeDocumentListView.as_view() view=APIDocumentTypeDocumentListView.as_view()
), ),
@@ -335,30 +351,30 @@ api_urls = [
view=APIDocumentListView.as_view() view=APIDocumentListView.as_view()
), ),
url( url(
regex=r'^documents/(?P<document_pk>\d+)/$', name='document-detail', regex=r'^documents/(?P<document_id>\d+)/$', name='document-detail',
view=APIDocumentView.as_view() view=APIDocumentView.as_view()
), ),
url( url(
regex=r'^documents/(?P<document_pk>\d+)/download/$', regex=r'^documents/(?P<document_id>\d+)/download/$',
name='document-download', view=APIDocumentDownloadView.as_view() name='document-download', view=APIDocumentDownloadView.as_view()
), ),
url( url(
regex=r'^documents/(?P<document_pk>\d+)/versions/$', regex=r'^documents/(?P<document_id>\d+)/versions/$',
name='document-version-list', name='document-version-list',
view=APIDocumentVersionsListView.as_view() view=APIDocumentVersionsListView.as_view()
), ),
url( url(
regex=r'^documents/(?P<document_pk>\d+)/versions/(?P<document_version_pk>\d+)/$', regex=r'^documents/(?P<document_id>\d+)/versions/(?P<document_version_id>\d+)/$',
name='documentversion-detail', name='documentversion-detail',
view=APIDocumentVersionView.as_view() view=APIDocumentVersionView.as_view()
), ),
url( url(
regex=r'^documents/(?P<document_pk>\d+)/versions/(?P<document_version_pk>\d+)/pages/$', regex=r'^documents/(?P<document_id>\d+)/versions/(?P<document_version_id>\d+)/pages/$',
name='documentversion-page-list', name='documentversion-page-list',
view=APIDocumentVersionPageListView.as_view() view=APIDocumentVersionPageListView.as_view()
), ),
url( url(
regex=r'^documents/(?P<document_pk>\d+)/versions/(?P<document_version_pk>\d+)/download/$', regex=r'^documents/(?P<document_id>\d+)/versions/(?P<document_version_id>\d+)/download/$',
name='documentversion-download', name='documentversion-download',
view=APIDocumentVersionDownloadView.as_view() view=APIDocumentVersionDownloadView.as_view()
), ),
@@ -367,24 +383,45 @@ api_urls = [
view=APIRecentDocumentListView.as_view() view=APIRecentDocumentListView.as_view()
), ),
url( url(
regex=r'^documents/(?P<document_pk>\d+)/versions/(?P<document_version_pk>\d+)/pages/(?P<document_page_pk>\d+)$', regex=r'^documents/(?P<document_id>\d+)/versions/(?P<document_version_id>\d+)/pages/(?P<document_page_id>\d+)$',
name='documentpage-detail', view=APIDocumentPageView.as_view() name='documentpage-detail', view=APIDocumentPageView.as_view()
), ),
url( url(
regex=r'^documents/(?P<document_pk>\d+)/versions/(?P<document_version_pk>\d+)/pages/(?P<document_page_pk>\d+)/image/$', regex=r'^documents/(?P<document_id>\d+)/versions/(?P<document_version_id>\d+)/pages/(?P<document_page_id>\d+)/image/$',
name='documentpage-image', view=APIDocumentPageImageView.as_view() name='documentpage-image', view=APIDocumentPageImageView.as_view()
), ),
url( url(
regex=r'^trashed_documents/$', name='trasheddocument-list', regex=r'^trashed_documents/$', name='trasheddocument-list',
view=APIDeletedDocumentListView.as_view() view=APITrashedDocumentListView.as_view()
), ),
url( url(
regex=r'^trashed_documents/(?P<document_pk>\d+)/$', regex=r'^trashed_documents/(?P<document_id>\d+)/$',
name='trasheddocument-detail', view=APIDeletedDocumentView.as_view() name='trasheddocument-detail', view=APITrashedDocumentView.as_view()
), ),
url( url(
regex=r'^trashed_documents/(?P<document_pk>\d+)/restore/$', regex=r'^trashed_documents/(?P<document_id>\d+)/restore/$',
name='trasheddocument-restore', name='trasheddocument-restore',
view=APIDeletedDocumentRestoreView.as_view() view=APITrashedDocumentRestoreView.as_view()
), ),
] ]
"""
api_router_entries = (
{
'prefix': r'documents', 'viewset': DocumentViewSet,
'basename': 'document'
},
{
'prefix': r'document_types', 'viewset': DocumentTypeViewSet,
'basename': 'document_type'
},
{
'prefix': r'documents/(?P<document_id>\d+)/versions',
'viewset': DocumentVersionViewSet, 'basename': 'document_version'
},
{
'prefix': r'documents/(?P<document_id>\d+)/versions/(?P<document_version_id>\d+)/pages',
'viewset': DocumentPageViewSet, 'basename': 'document_page'
},
)
+1
View File
@@ -3,3 +3,4 @@ from .document_type_views import * # NOQA
from .document_version_views import * # NOQA from .document_version_views import * # NOQA
from .document_views import * # NOQA from .document_views import * # NOQA
from .misc_views import * # NOQA from .misc_views import * # NOQA
from .trashed_document_views import * # NOQA
@@ -6,15 +6,14 @@ from furl import furl
from django.conf import settings from django.conf import settings
from django.contrib import messages from django.contrib import messages
from django.shortcuts import get_object_or_404, resolve_url from django.shortcuts import resolve_url
from django.urls import reverse from django.urls import reverse
from django.utils.encoding import force_text from django.utils.encoding import force_text
from django.utils.http import urlencode
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.views.generic import RedirectView from django.views.generic import RedirectView
from mayan.apps.acls.models import AccessControlList
from mayan.apps.common.generics import SimpleView, SingleObjectListView from mayan.apps.common.generics import SimpleView, SingleObjectListView
from mayan.apps.common.mixins import ExternalObjectMixin
from mayan.apps.common.utils import resolve from mayan.apps.common.utils import resolve
from mayan.apps.converter.literals import DEFAULT_ROTATION, DEFAULT_ZOOM_LEVEL from mayan.apps.converter.literals import DEFAULT_ROTATION, DEFAULT_ZOOM_LEVEL
@@ -37,53 +36,40 @@ __all__ = (
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class DocumentPageInteractiveTransformation(RedirectView): class DocumentPageInteractiveTransformation(ExternalObjectMixin, RedirectView):
def dispatch(self, request, *args, **kwargs): external_object_class = DocumentPage
obj = self.get_object() external_object_permission = permission_document_view
external_object_pk_url_kwarg = 'document_page_id'
AccessControlList.objects.check_access(
obj=obj, permissions=permission_document_view, user=request.user,
)
return super(DocumentPageInteractiveTransformation, self).dispatch(
request, *args, **kwargs
)
def get_object(self): def get_object(self):
return get_object_or_404( return self.get_external_object()
klass=DocumentPage, pk=self.kwargs['document_page_pk']
)
def get_redirect_url(self, *args, **kwargs): def get_redirect_url(self, *args, **kwargs):
url = reverse(
viewname='documents:document_page_view',
kwargs={'document_page_pk': self.kwargs['document_page_pk']}
)
query_dict = { query_dict = {
'rotation': int( 'rotation': self.request.GET.get('rotation', DEFAULT_ROTATION),
self.request.GET.get('rotation', DEFAULT_ROTATION) 'zoom': self.request.GET.get('zoom', DEFAULT_ZOOM_LEVEL)
), 'zoom': int(self.request.GET.get('zoom', DEFAULT_ZOOM_LEVEL))
} }
self.transformation_function(query_dict) url = furl(
args=query_dict, path=reverse(
viewname='documents:document_page_view',
kwargs={'document_page_id': self.kwargs['document_page_id']}
)
return '{}?{}'.format(url, urlencode(query_dict))
class DocumentPageListView(SingleObjectListView):
def dispatch(self, request, *args, **kwargs):
AccessControlList.objects.check_access(
obj=self.get_document(), permissions=permission_document_view,
user=self.request.user,
) )
return super( self.transformation_function(query_dict=query_dict)
DocumentPageListView, self
).dispatch(request, *args, **kwargs) return url.tostr()
class DocumentPageListView(ExternalObjectMixin, SingleObjectListView):
external_object_class = Document
external_object_permission = permission_document_view
external_object_pk_url_kwarg = 'document_id'
def get_document(self): def get_document(self):
return get_object_or_404(klass=Document, pk=self.kwargs['document_pk']) return self.get_external_object()
def get_extra_context(self): def get_extra_context(self):
return { return {
@@ -95,27 +81,17 @@ class DocumentPageListView(SingleObjectListView):
'title': _('Pages for document: %s') % self.get_document(), 'title': _('Pages for document: %s') % self.get_document(),
} }
def get_object_list(self): def get_source_queryset(self):
return self.get_document().pages.all() return self.get_document().pages.all()
class DocumentPageNavigationBase(RedirectView): class DocumentPageNavigationBase(ExternalObjectMixin, RedirectView):
def dispatch(self, request, *args, **kwargs): external_object_class = DocumentPage
document_page = self.get_object() external_object_permission = permission_document_view
external_object_pk_url_kwarg = 'document_page_id'
AccessControlList.objects.check_access(
permissions=permission_document_view, user=request.user,
obj=document_page.document
)
return super(DocumentPageNavigationBase, self).dispatch(
request, *args, **kwargs
)
def get_object(self): def get_object(self):
return get_object_or_404( return self.get_external_object()
klass=DocumentPage, pk=self.kwargs['document_page_pk']
)
def get_redirect_url(self, *args, **kwargs): def get_redirect_url(self, *args, **kwargs):
""" """
@@ -158,14 +134,14 @@ class DocumentPageNavigationFirst(DocumentPageNavigationBase):
def get_new_kwargs(self): def get_new_kwargs(self):
document_page = self.get_object() document_page = self.get_object()
return {'document_page_pk': document_page.siblings.first().pk} return {'document_page_id': document_page.siblings.first().pk}
class DocumentPageNavigationLast(DocumentPageNavigationBase): class DocumentPageNavigationLast(DocumentPageNavigationBase):
def get_new_kwargs(self): def get_new_kwargs(self):
document_page = self.get_object() document_page = self.get_object()
return {'document_page_pk': document_page.siblings.last().pk} return {'document_page_id': document_page.siblings.last().pk}
class DocumentPageNavigationNext(DocumentPageNavigationBase): class DocumentPageNavigationNext(DocumentPageNavigationBase):
@@ -178,12 +154,12 @@ class DocumentPageNavigationNext(DocumentPageNavigationBase):
) )
except DocumentPage.DoesNotExist: except DocumentPage.DoesNotExist:
messages.warning( messages.warning(
request=self.request, message=_( message=_(
'There are no more pages in this document' 'There are no more pages in this document'
) ), request=self.request
) )
finally: finally:
return {'document_page_pk': document_page.pk} return {'document_page_id': document_page.pk}
class DocumentPageNavigationPrevious(DocumentPageNavigationBase): class DocumentPageNavigationPrevious(DocumentPageNavigationBase):
@@ -196,47 +172,40 @@ class DocumentPageNavigationPrevious(DocumentPageNavigationBase):
) )
except DocumentPage.DoesNotExist: except DocumentPage.DoesNotExist:
messages.warning( messages.warning(
request=self.request, message=_( message=_(
'You are already at the first page of this document' 'You are already at the first page of this document'
) ), request=self.request
) )
finally: finally:
return {'document_page_pk': document_page.pk} return {'document_page_id': document_page.pk}
class DocumentPageRotateLeftView(DocumentPageInteractiveTransformation): class DocumentPageRotateLeftView(DocumentPageInteractiveTransformation):
def transformation_function(self, query_dict): def transformation_function(self, query_dict):
query_dict['rotation'] = ( query_dict['rotation'] = (
query_dict['rotation'] - setting_rotation_step.value int(query_dict['rotation']) - setting_rotation_step.value
) % 360 ) % 360
class DocumentPageRotateRightView(DocumentPageInteractiveTransformation): class DocumentPageRotateRightView(DocumentPageInteractiveTransformation):
def transformation_function(self, query_dict): def transformation_function(self, query_dict):
query_dict['rotation'] = ( query_dict['rotation'] = (
query_dict['rotation'] + setting_rotation_step.value int(query_dict['rotation']) + setting_rotation_step.value
) % 360 ) % 360
class DocumentPageView(SimpleView): class DocumentPageView(ExternalObjectMixin, SimpleView):
external_object_class = DocumentPage
external_object_permission = permission_document_view
external_object_pk_url_kwarg = 'document_page_id'
template_name = 'appearance/generic_form.html' template_name = 'appearance/generic_form.html'
def dispatch(self, request, *args, **kwargs):
AccessControlList.objects.check_access(
permissions=permission_document_view, user=request.user,
obj=self.get_object().document
)
return super(
DocumentPageView, self
).dispatch(request, *args, **kwargs)
def get_extra_context(self): def get_extra_context(self):
zoom = int(self.request.GET.get('zoom', DEFAULT_ZOOM_LEVEL)) zoom = int(self.request.GET.get('zoom', DEFAULT_ZOOM_LEVEL))
rotation = int(self.request.GET.get('rotation', DEFAULT_ROTATION)) rotation = int(self.request.GET.get('rotation', DEFAULT_ROTATION))
document_page_form = DocumentPageForm( document_page_form = DocumentPageForm(
instance=self.get_object(), zoom=zoom, rotation=rotation instance=self.get_object(), rotation=rotation, zoom=zoom
) )
base_title = _('Image of: %s') % self.get_object() base_title = _('Image of: %s') % self.get_object()
@@ -252,15 +221,13 @@ class DocumentPageView(SimpleView):
'navigation_object_list': ('page',), 'navigation_object_list': ('page',),
'page': self.get_object(), 'page': self.get_object(),
'rotation': rotation, 'rotation': rotation,
'title': ' '.join((base_title, zoom_text,)), 'title': ' '.join((base_title, zoom_text)),
'read_only': True, 'read_only': True,
'zoom': zoom, 'zoom': zoom,
} }
def get_object(self): def get_object(self):
return get_object_or_404( return self.get_external_object()
klass=DocumentPage, pk=self.kwargs['document_page_pk']
)
class DocumentPageViewResetView(RedirectView): class DocumentPageViewResetView(RedirectView):
@@ -269,7 +236,7 @@ class DocumentPageViewResetView(RedirectView):
class DocumentPageZoomInView(DocumentPageInteractiveTransformation): class DocumentPageZoomInView(DocumentPageInteractiveTransformation):
def transformation_function(self, query_dict): def transformation_function(self, query_dict):
zoom = query_dict['zoom'] + setting_zoom_percent_step.value zoom = int(query_dict['zoom']) + setting_zoom_percent_step.value
if zoom > setting_zoom_max_level.value: if zoom > setting_zoom_max_level.value:
zoom = setting_zoom_max_level.value zoom = setting_zoom_max_level.value
@@ -279,7 +246,7 @@ class DocumentPageZoomInView(DocumentPageInteractiveTransformation):
class DocumentPageZoomOutView(DocumentPageInteractiveTransformation): class DocumentPageZoomOutView(DocumentPageInteractiveTransformation):
def transformation_function(self, query_dict): def transformation_function(self, query_dict):
zoom = query_dict['zoom'] - setting_zoom_percent_step.value zoom = int(query_dict['zoom']) - setting_zoom_percent_step.value
if zoom < setting_zoom_min_level.value: if zoom < setting_zoom_min_level.value:
zoom = setting_zoom_min_level.value zoom = setting_zoom_min_level.value
@@ -2,16 +2,15 @@ from __future__ import absolute_import, unicode_literals
import logging import logging
from django.shortcuts import get_object_or_404
from django.template import RequestContext from django.template import RequestContext
from django.urls import reverse, reverse_lazy from django.urls import reverse, reverse_lazy
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from mayan.apps.acls.models import AccessControlList
from mayan.apps.common.generics import ( from mayan.apps.common.generics import (
SingleObjectCreateView, SingleObjectDeleteView, SingleObjectEditView, SingleObjectCreateView, SingleObjectDeleteView, SingleObjectEditView,
SingleObjectListView SingleObjectListView
) )
from mayan.apps.common.mixins import ExternalObjectMixin
from ..forms import DocumentTypeFilenameForm_create from ..forms import DocumentTypeFilenameForm_create
from ..icons import icon_document_type_filename, icon_document_type_setup from ..icons import icon_document_type_filename, icon_document_type_setup
@@ -60,7 +59,7 @@ class DocumentTypeDeleteView(SingleObjectDeleteView):
model = DocumentType model = DocumentType
object_permission = permission_document_type_delete object_permission = permission_document_type_delete
post_action_redirect = reverse_lazy(viewname='documents:document_type_list') post_action_redirect = reverse_lazy(viewname='documents:document_type_list')
pk_url_kwarg = 'document_type_pk' pk_url_kwarg = 'document_type_id'
def get_extra_context(self): def get_extra_context(self):
return { return {
@@ -70,13 +69,17 @@ class DocumentTypeDeleteView(SingleObjectDeleteView):
} }
class DocumentTypeDocumentListView(DocumentListView): class DocumentTypeDocumentListView(ExternalObjectMixin, DocumentListView):
def get_document_type(self): external_object_class = DocumentType
return get_object_or_404(klass=DocumentType, pk=self.kwargs['document_type_pk']) external_object_permission = permission_document_type_view
external_object_pk_url_kwarg = 'document_type_id'
def get_document_queryset(self): def get_document_queryset(self):
return self.get_document_type().documents.all() return self.get_document_type().documents.all()
def get_document_type(self):
return self.get_external_object()
def get_extra_context(self): def get_extra_context(self):
context = super(DocumentTypeDocumentListView, self).get_extra_context() context = super(DocumentTypeDocumentListView, self).get_extra_context()
context.update( context.update(
@@ -95,7 +98,7 @@ class DocumentTypeEditView(SingleObjectEditView):
) )
model = DocumentType model = DocumentType
object_permission = permission_document_type_edit object_permission = permission_document_type_edit
pk_url_kwarg = 'document_type_pk' pk_url_kwarg = 'document_type_id'
post_action_redirect = reverse_lazy( post_action_redirect = reverse_lazy(
viewname='documents:document_type_list' viewname='documents:document_type_list'
) )
@@ -136,21 +139,14 @@ class DocumentTypeListView(SingleObjectListView):
} }
class DocumentTypeFilenameCreateView(SingleObjectCreateView): class DocumentTypeFilenameCreateView(ExternalObjectMixin, SingleObjectCreateView):
external_object_class = DocumentType
external_object_permission = permission_document_type_edit
external_object_pk_url_kwarg = 'document_type_id'
form_class = DocumentTypeFilenameForm_create form_class = DocumentTypeFilenameForm_create
def dispatch(self, request, *args, **kwargs):
AccessControlList.objects.check_access(
permissions=permission_document_type_edit, user=request.user,
obj=self.get_document_type()
)
return super(DocumentTypeFilenameCreateView, self).dispatch(
request, *args, **kwargs
)
def get_document_type(self): def get_document_type(self):
return get_object_or_404(klass=DocumentType, pk=self.kwargs['document_type_pk']) return self.get_external_object()
def get_extra_context(self): def get_extra_context(self):
return { return {
@@ -168,7 +164,7 @@ class DocumentTypeFilenameCreateView(SingleObjectCreateView):
class DocumentTypeFilenameDeleteView(SingleObjectDeleteView): class DocumentTypeFilenameDeleteView(SingleObjectDeleteView):
model = DocumentTypeFilename model = DocumentTypeFilename
object_permission = permission_document_type_edit object_permission = permission_document_type_edit
pk_url_kwarg = 'filename_pk' pk_url_kwarg = 'filename_id'
def get_extra_context(self): def get_extra_context(self):
return { return {
@@ -187,7 +183,7 @@ class DocumentTypeFilenameDeleteView(SingleObjectDeleteView):
def get_post_action_redirect(self): def get_post_action_redirect(self):
return reverse( return reverse(
viewname='documents:document_type_filename_list', viewname='documents:document_type_filename_list',
kwargs={'document_type_pk': self.get_object().document_type.pk} kwargs={'document_type_id': self.get_object().document_type.pk}
) )
@@ -195,7 +191,7 @@ class DocumentTypeFilenameEditView(SingleObjectEditView):
fields = ('enabled', 'filename',) fields = ('enabled', 'filename',)
model = DocumentTypeFilename model = DocumentTypeFilename
object_permission = permission_document_type_edit object_permission = permission_document_type_edit
pk_url_kwarg = 'filename_pk' pk_url_kwarg = 'filename_id'
def get_extra_context(self): def get_extra_context(self):
document_type_filename = self.get_object() document_type_filename = self.get_object()
@@ -216,16 +212,17 @@ class DocumentTypeFilenameEditView(SingleObjectEditView):
def get_post_action_redirect(self): def get_post_action_redirect(self):
return reverse( return reverse(
viewname='documents:document_type_filename_list', viewname='documents:document_type_filename_list',
kwargs={'document_type_pk': self.get_object().document_type.pk} kwargs={'document_type_id': self.get_object().document_type.pk}
) )
class DocumentTypeFilenameListView(SingleObjectListView): class DocumentTypeFilenameListView(ExternalObjectMixin, SingleObjectListView):
access_object_retrieve_method = 'get_document_type' external_object_class = DocumentType
object_permission = permission_document_type_view external_object_permission = permission_document_type_view
external_object_pk_url_kwarg = 'document_type_id'
def get_document_type(self): def get_document_type(self):
return get_object_or_404(klass=DocumentType, pk=self.kwargs['document_type_pk']) return self.get_external_object()
def get_extra_context(self): def get_extra_context(self):
return { return {
@@ -255,5 +252,5 @@ class DocumentTypeFilenameListView(SingleObjectListView):
) % self.get_document_type(), ) % self.get_document_type(),
} }
def get_object_list(self): def get_source_queryset(self):
return self.get_document_type().filenames.all() return self.get_document_type().filenames.all()
@@ -3,15 +3,14 @@ from __future__ import absolute_import, unicode_literals
import logging import logging
from django.contrib import messages from django.contrib import messages
from django.shortcuts import get_object_or_404
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from mayan.apps.acls.models import AccessControlList
from mayan.apps.common.generics import ( from mayan.apps.common.generics import (
ConfirmView, SingleObjectDetailView, SingleObjectListView ConfirmView, SingleObjectDetailView, SingleObjectListView
) )
from mayan.apps.common.mixins import ExternalObjectMixin
from ..events import event_document_view from ..events import event_document_download, event_document_view
from ..forms import DocumentVersionDownloadForm, DocumentVersionPreviewForm from ..forms import DocumentVersionDownloadForm, DocumentVersionPreviewForm
from ..models import Document, DocumentVersion from ..models import Document, DocumentVersion
from ..permissions import ( from ..permissions import (
@@ -21,79 +20,22 @@ from ..permissions import (
from .document_views import DocumentDownloadFormView, DocumentDownloadView from .document_views import DocumentDownloadFormView, DocumentDownloadView
__all__ = (
'DocumentVersionDownloadFormView', 'DocumentVersionDownloadView',
'DocumentVersionListView', 'DocumentVersionRevertView',
'DocumentVersionView'
)
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class DocumentVersionListView(SingleObjectListView):
def dispatch(self, request, *args, **kwargs):
AccessControlList.objects.check_access(
obj=self.get_document(),
permissions=permission_document_version_view, user=request.user
)
self.get_document().add_as_recent_document_for_user(user=request.user)
return super(
DocumentVersionListView, self
).dispatch(request, *args, **kwargs)
def get_document(self):
return get_object_or_404(klass=Document, pk=self.kwargs['document_pk'])
def get_extra_context(self):
return {
'hide_object': True,
'list_as_items': True,
'object': self.get_document(),
'table_cell_container_classes': 'td-container-thumbnail',
'title': _('Versions of document: %s') % self.get_document(),
}
def get_object_list(self):
return self.get_document().versions.order_by('-timestamp')
class DocumentVersionRevertView(ConfirmView):
object_permission = permission_document_version_revert
def get_extra_context(self):
return {
'message': _(
'All later version after this one will be deleted too.'
),
'object': self.get_object().document,
'title': _('Revert to this version?'),
}
def get_object(self):
return get_object_or_404(
klass=DocumentVersion, pk=self.kwargs['document_version_pk']
)
def view_action(self):
try:
self.get_object().revert(_user=self.request.user)
messages.success(
request=self.request, message=_(
'Document version reverted successfully'
)
)
except Exception as exception:
messages.error(
request=self.request,
message=_('Error reverting document version; %s') % exception
)
class DocumentVersionDownloadFormView(DocumentDownloadFormView): class DocumentVersionDownloadFormView(DocumentDownloadFormView):
form_class = DocumentVersionDownloadForm form_class = DocumentVersionDownloadForm
model = DocumentVersion model = DocumentVersion
multiple_download_view = None pk_url_kwarg = 'document_version_id'
pk_url_kwarg = 'document_version_pk'
querystring_form_fields = ( querystring_form_fields = (
'compressed', 'zip_filename', 'preserve_extension' 'compressed', 'zip_filename', 'preserve_extension'
) )
single_download_view = 'documents:document_version_download' viewname = 'documents:document_version_download'
def get_extra_context(self): def get_extra_context(self):
result = super( result = super(
@@ -106,30 +48,26 @@ class DocumentVersionDownloadFormView(DocumentDownloadFormView):
return result return result
def get_document_queryset(self):
id_list = self.request.GET.get(
'id_list', self.request.POST.get('id_list', '')
)
if not id_list:
id_list = self.kwargs['document_version_pk']
return self.model.objects.filter(
pk__in=id_list.split(',')
)
class DocumentVersionDownloadView(DocumentDownloadView): class DocumentVersionDownloadView(DocumentDownloadView):
model = DocumentVersion model = DocumentVersion
object_permission = permission_document_download object_permission = permission_document_download
pk_url_kwarg = 'document_version_pk' pk_url_kwarg = 'document_version_id'
@staticmethod
def commit_event(item, request):
# TODO: Improve by adding a document version download event
event_document_download.commit(
actor=request.user,
target=item.document
)
@staticmethod @staticmethod
def get_item_file(item): def get_item_file(item):
return item.file return item.file
def get_encoding(self): def get_encoding(self):
return self.get_object().encoding return self.get_object_list().first().encoding
def get_item_label(self, item): def get_item_label(self, item):
preserve_extension = self.request.GET.get( preserve_extension = self.request.GET.get(
@@ -143,13 +81,69 @@ class DocumentVersionDownloadView(DocumentDownloadView):
return item.get_rendered_string(preserve_extension=preserve_extension) return item.get_rendered_string(preserve_extension=preserve_extension)
def get_mimetype(self): def get_mimetype(self):
return self.get_object().mimetype return self.get_object_list().first().mimetype
class DocumentVersionListView(ExternalObjectMixin, SingleObjectListView):
external_object_class = Document
external_object_permission = permission_document_version_view
external_object_pk_url_kwarg = 'document_id'
def get_document(self):
document = self.get_external_object()
document.add_as_recent_document_for_user(user=self.request.user)
return document
def get_extra_context(self):
return {
'hide_object': True,
'list_as_items': True,
'object': self.get_document(),
'table_cell_container_classes': 'td-container-thumbnail',
'title': _('Versions of document: %s') % self.get_document(),
}
def get_source_queryset(self):
return self.get_document().versions.order_by('-timestamp')
class DocumentVersionRevertView(ExternalObjectMixin, ConfirmView):
external_object_class = DocumentVersion
external_object_permission = permission_document_version_revert
external_object_pk_url_kwarg = 'document_version_id'
def get_extra_context(self):
return {
'message': _(
'All later version after this one will be deleted too.'
),
'object': self.get_object().document,
'title': _('Revert to this version?'),
}
def get_object(self):
return self.get_external_object()
def view_action(self):
try:
self.get_object().revert(_user=self.request.user)
messages.success(
message=_(
'Document version reverted successfully'
), request=self.request
)
except Exception as exception:
messages.error(
message=_('Error reverting document version; %s') % exception,
request=self.request
)
class DocumentVersionView(SingleObjectDetailView): class DocumentVersionView(SingleObjectDetailView):
form_class = DocumentVersionPreviewForm form_class = DocumentVersionPreviewForm
model = DocumentVersion model = DocumentVersion
object_permission = permission_document_version_view object_permission = permission_document_version_view
pk_url_kwarg = 'document_version_id'
def dispatch(self, request, *args, **kwargs): def dispatch(self, request, *args, **kwargs):
result = super( result = super(
File diff suppressed because it is too large Load Diff
+4 -2
View File
@@ -24,7 +24,8 @@ class ClearImageCacheView(ConfirmView):
def view_action(self): def view_action(self):
task_clear_image_cache.apply_async() task_clear_image_cache.apply_async()
messages.success( messages.success(
self.request, _('Document cache clearing queued successfully.') message=_('Document cache clearing queued successfully.'),
request=self.request
) )
@@ -37,5 +38,6 @@ class ScanDuplicatedDocuments(ConfirmView):
def view_action(self): def view_action(self):
task_scan_duplicates_all.apply_async() task_scan_duplicates_all.apply_async()
messages.success( messages.success(
self.request, _('Duplicated document scan queued successfully.') message=_('Duplicated document scan queued successfully.'),
request=self.request
) )
@@ -0,0 +1,162 @@
from __future__ import absolute_import, unicode_literals
import logging
from django.contrib import messages
from django.urls import reverse_lazy
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ungettext
from mayan.apps.acls.models import AccessControlList
from mayan.apps.common.generics import (
ConfirmView, MultipleObjectConfirmActionView
)
from ..icons import icon_trashed_document_list
from ..models import Document, TrashedDocument
from ..permissions import (
permission_document_trash, permission_document_view, permission_empty_trash,
permission_trashed_document_delete, permission_trashed_document_restore
)
from ..tasks import task_delete_document
from .document_views import DocumentListView
__all__ = (
'DocumentTrashView', 'EmptyTrashCanView', 'TrashedDocumentDeleteView',
'TrashedDocumentListView', 'TrashedDocumentRestoreView',
)
logger = logging.getLogger(__name__)
class DocumentTrashView(MultipleObjectConfirmActionView):
model = Document
object_permission = permission_document_trash
pk_url_kwarg = 'document_id'
success_message = _(
'%(count)d document moved to the trash.'
)
success_message_plural = _(
'%(count)d documents moved to the trash.'
)
def get_extra_context(self):
queryset = self.get_object_list()
result = {
'title': ungettext(
single='Move the selected document to the trash?',
plural='Move the selected documents to the trash?',
number=queryset.count()
)
}
return result
def object_action(self, form, instance):
instance.delete()
class EmptyTrashCanView(ConfirmView):
extra_context = {
'title': _('Empty trash?')
}
view_permission = permission_empty_trash
action_cancel_redirect = post_action_redirect = reverse_lazy(
viewname='documents:trashed_document_list'
)
def view_action(self):
for trashed_document in TrashedDocument.objects.all():
task_delete_document.apply_async(
kwargs={'trashed_document_id': trashed_document.pk}
)
messages.success(
request=self.request, message=_('Trash emptied successfully')
)
class TrashedDocumentDeleteView(MultipleObjectConfirmActionView):
model = TrashedDocument
object_permission = permission_trashed_document_delete
pk_url_kwarg = 'trashed_document_id'
success_message = _(
'%(count)d trashed document deleted.'
)
success_message_plural = _(
'%(count)d trashed documents deleted.'
)
def get_extra_context(self):
queryset = self.get_object_list()
result = {
'title': ungettext(
single='Delete the selected trashed document?',
plural='Delete the selected trashed documents?',
number=queryset.count()
)
}
return result
def object_action(self, form, instance):
instance.delete()
class TrashedDocumentListView(DocumentListView):
object_permission = None
def get_document_queryset(self):
return AccessControlList.objects.restrict_queryset(
permission=permission_document_view,
queryset=TrashedDocument.trash.all(), user=self.request.user
)
def get_extra_context(self):
context = super(TrashedDocumentListView, self).get_extra_context()
context.update(
{
'hide_link': True,
'no_results_icon': icon_trashed_document_list,
'no_results_text': _(
'To avoid loss of data, documents are not deleted '
'instantly. First, they are placed in the trash can. '
'From here they can be then finally deleted or restored.'
),
'no_results_title': _(
'There are no documents in the trash can'
),
'title': _('Documents in trash'),
}
)
return context
class TrashedDocumentRestoreView(MultipleObjectConfirmActionView):
model = TrashedDocument
object_permission = permission_trashed_document_restore
pk_url_kwarg = 'trashed_document_id'
success_message = _(
'%(count)d trashed document restored.'
)
success_message_plural = _(
'%(count)d trashed documents restored.'
)
def get_extra_context(self):
queryset = self.get_object_list()
result = {
'title': ungettext(
single='Restore the selected trashed document?',
plural='Restore the selected trashed documents?',
number=queryset.count()
)
}
return result
def object_action(self, form, instance):
instance.restore()