diff --git a/mayan/apps/documents/apps.py b/mayan/apps/documents/apps.py index 082cdb5e20..23d582aab1 100644 --- a/mayan/apps/documents/apps.py +++ b/mayan/apps/documents/apps.py @@ -32,7 +32,8 @@ from .links import ( link_document_events_view, link_document_multiple_document_type_edit, link_document_download, link_document_edit, link_document_list, link_document_list_deleted, link_document_list_recent, - link_document_multiple_delete, link_document_multiple_clear_transformations, + link_document_multiple_delete, link_document_multiple_trash, + link_document_multiple_clear_transformations, link_document_multiple_download, link_document_multiple_restore, link_document_multiple_update_page_count, link_document_page_navigation_first, link_document_page_navigation_last, @@ -42,7 +43,7 @@ from .links import ( link_document_page_view_reset, link_document_page_zoom_in, link_document_page_zoom_out, link_document_pages, link_document_preview, link_document_print, link_document_properties, link_document_restore, - link_document_type_create, link_document_type_delete, + link_document_trash, link_document_type_create, link_document_type_delete, link_document_type_edit, link_document_type_filename_create, link_document_type_filename_delete, link_document_type_filename_edit, link_document_type_filename_list, link_document_type_list, @@ -58,7 +59,8 @@ from .permissions import ( permission_document_delete, permission_document_download, permission_document_edit, permission_document_new_version, permission_document_print, permission_document_properties_edit, - permission_document_version_revert, permission_document_view + permission_document_trash, permission_document_version_revert, + permission_document_view ) from .settings import setting_thumbnail_size from .statistics import DocumentStatistics, DocumentUsageStatistics @@ -84,10 +86,11 @@ class DocumentsApp(MayanAppConfig): permission_document_delete, permission_document_download, permission_document_edit, permission_document_new_version, permission_document_print, permission_document_properties_edit, - permission_document_version_revert, permission_document_view, - permission_events_view, permission_transformation_create, - permission_transformation_delete, permission_transformation_edit, - permission_transformation_view, + permission_document_trash, permission_document_version_revert, + permission_document_view, permission_events_view, + permission_transformation_create, + permission_transformation_delete, + permission_transformation_edit, permission_transformation_view, ) ) @@ -102,8 +105,8 @@ class DocumentsApp(MayanAppConfig): menu_sidebar.bind_links(links=[link_document_type_filename_create], sources=[DocumentTypeFilename, 'documents:document_type_filename_list', 'documents:document_type_filename_create']) # Document object links - menu_object.bind_links(links=[link_document_edit, link_document_document_type_edit, link_document_print, link_document_delete, link_document_download, link_document_clear_transformations, link_document_update_page_count], sources=[Document]) - menu_object.bind_links(links=[link_document_restore], sources=[DeletedDocument]) + menu_object.bind_links(links=[link_document_edit, link_document_document_type_edit, link_document_print, link_document_trash, link_document_download, link_document_clear_transformations, link_document_update_page_count], sources=[Document]) + menu_object.bind_links(links=[link_document_restore, link_document_delete], sources=[DeletedDocument]) # Document facet links menu_facet.bind_links(links=[link_acl_list], sources=[Document]) @@ -114,8 +117,8 @@ class DocumentsApp(MayanAppConfig): # Document actions menu_object.bind_links(links=[link_document_version_revert, link_document_version_download], sources=[DocumentVersion]) - menu_multi_item.bind_links(links=[link_document_multiple_clear_transformations, link_document_multiple_delete, link_document_multiple_download, link_document_multiple_update_page_count, link_document_multiple_document_type_edit], sources=[Document]) - menu_multi_item.bind_links(links=[link_document_multiple_restore], sources=[DeletedDocument]) + menu_multi_item.bind_links(links=[link_document_multiple_clear_transformations, link_document_multiple_trash, link_document_multiple_download, link_document_multiple_update_page_count, link_document_multiple_document_type_edit], sources=[Document]) + menu_multi_item.bind_links(links=[link_document_multiple_restore, link_document_multiple_delete], sources=[DeletedDocument]) # Document pages menu_facet.bind_links(links=[link_document_page_rotate_left, link_document_page_rotate_right, link_document_page_zoom_in, link_document_page_zoom_out, link_document_page_view_reset], sources=['documents:document_page_view']) diff --git a/mayan/apps/documents/links.py b/mayan/apps/documents/links.py index 6756512e03..7df1a5eb8e 100644 --- a/mayan/apps/documents/links.py +++ b/mayan/apps/documents/links.py @@ -11,8 +11,9 @@ from .permissions import ( permission_document_properties_edit, permission_document_print, permission_document_restore, permission_document_tools, permission_document_version_revert, permission_document_view, - permission_document_type_create, permission_document_type_delete, - permission_document_type_edit, permission_document_type_view + permission_document_trash, permission_document_type_create, + permission_document_type_delete, permission_document_type_edit, + permission_document_type_view ) from .settings import setting_zoom_max_level, setting_zoom_min_level @@ -47,6 +48,7 @@ link_document_pages = Link(permissions=[permission_document_view], text=_('Pages # Actions link_document_clear_transformations = Link(permissions=[permission_transformation_delete], text=_('Clear transformations'), view='documents:document_clear_transformations', args='object.id') link_document_delete = Link(permissions=[permission_document_delete], tags='dangerous', text=_('Delete'), view='documents:document_delete', args='object.id') +link_document_trash = Link(permissions=[permission_document_trash], tags='dangerous', text=_('Move to trash'), view='documents:document_trash', args='object.id') link_document_edit = Link(permissions=[permission_document_properties_edit], text=_('Edit properties'), view='documents:document_edit', args='object.id') link_document_document_type_edit = Link(permissions=[permission_document_properties_edit], text=_('Change type'), view='documents:document_document_type_edit', args='object.id') link_document_download = Link(permissions=[permission_document_download], text=_('Download'), view='documents:document_download', args='object.id') @@ -54,6 +56,7 @@ link_document_print = Link(permissions=[permission_document_print], text=_('Prin link_document_update_page_count = Link(permissions=[permission_document_tools], text=_('Reset page count'), view='documents:document_update_page_count', args='object.pk') link_document_restore = Link(permissions=[permission_document_restore], text=_('Restore'), view='documents:document_restore', args='object.pk') link_document_multiple_clear_transformations = Link(permissions=[permission_transformation_delete], text=_('Clear transformations'), view='documents:document_multiple_clear_transformations') +link_document_multiple_trash = Link(permissions=[permission_document_trash], tags='dangerous', text=_('Move to trash'), view='documents:document_multiple_trash') link_document_multiple_delete = Link(permissions=[permission_document_delete], tags='dangerous', text=_('Delete'), view='documents:document_multiple_delete') link_document_multiple_document_type_edit = Link(permissions=[permission_document_properties_edit], text=_('Change type'), view='documents:document_multiple_document_type_edit') link_document_multiple_download = Link(permissions=[permission_document_download], text=_('Download'), view='documents:document_multiple_download') diff --git a/mayan/apps/documents/managers.py b/mayan/apps/documents/managers.py index f8a9861978..1fe3b7177b 100644 --- a/mayan/apps/documents/managers.py +++ b/mayan/apps/documents/managers.py @@ -78,6 +78,10 @@ class DocumentManager(models.Manager): return version +class PassthroughManager(models.Manager): + pass + + class TrashCanManager(models.Manager): def get_queryset(self): return super(TrashCanManager, self).get_queryset().filter(in_trash=True) @@ -87,9 +91,3 @@ class TrashCanQuerySet(models.QuerySet): def delete(self, to_trash=True): for instance in self: instance.delete(to_trash=to_trash) - - #if to_trash: - # for instance in self: - # instance.delete(to_trash=to_trash) - #else: - # super(TrashCanQuerySet, self).delete() diff --git a/mayan/apps/documents/models.py b/mayan/apps/documents/models.py index aa55ff0ed0..915c878440 100644 --- a/mayan/apps/documents/models.py +++ b/mayan/apps/documents/models.py @@ -28,7 +28,8 @@ from .events import ( event_document_version_revert ) from .managers import ( - DocumentManager, DocumentTypeManager, RecentDocumentManager, TrashCanManager + DocumentManager, DocumentTypeManager, PassthroughManager, + RecentDocumentManager, TrashCanManager ) from .runtime import storage_backend from .settings import ( @@ -82,6 +83,8 @@ class Document(models.Model): in_trash = models.BooleanField(default=False, editable=False, verbose_name=_('In trash?')) objects = DocumentManager() + passthrough = PassthroughManager() + trash = TrashCanManager() class Meta: verbose_name = _('Document') @@ -502,7 +505,7 @@ class DocumentPage(models.Model): return self.document_version.document def invalidate_cache(self): - fs_cleanup(self.get_cache_filename()) + fs_cleanup(self.cache_filename) @property def uuid(self): diff --git a/mayan/apps/documents/permissions.py b/mayan/apps/documents/permissions.py index 9597b10597..36bac57e46 100644 --- a/mayan/apps/documents/permissions.py +++ b/mayan/apps/documents/permissions.py @@ -8,6 +8,7 @@ namespace = PermissionNamespace('documents', _('Documents')) permission_document_create = namespace.add_permission(name='document_create', label=_('Create documents')) permission_document_delete = namespace.add_permission(name='document_delete', label=_('Delete documents')) +permission_document_trash = namespace.add_permission(name='document_trash', label=_('Trash documents')) permission_document_download = namespace.add_permission(name='document_download', label=_('Download documents')) permission_document_edit = namespace.add_permission(name='document_edit', label=_('Edit documents')) permission_document_new_version = namespace.add_permission(name='document_new_version', label=_('Create new document versions')) diff --git a/mayan/apps/documents/urls.py b/mayan/apps/documents/urls.py index cffb88b2e3..10e36df158 100644 --- a/mayan/apps/documents/urls.py +++ b/mayan/apps/documents/urls.py @@ -11,8 +11,9 @@ from .api_views import ( ) from .settings import setting_print_size, setting_display_size from .views import ( - DeletedDocumentListView, DocumentListView, DocumentManyRestoreView, - DocumentPageListView, DocumentRestoreView, RecentDocumentListView + DeletedDocumentDeleteView, DeletedDocumentListView, DocumentListView, + DocumentManyDeleteView, DocumentManyRestoreView, DocumentPageListView, + DocumentRestoreView, RecentDocumentListView ) urlpatterns = patterns( @@ -25,10 +26,12 @@ urlpatterns = patterns( url(r'^(?P\d+)/properties/$', 'document_properties', name='document_properties'), url(r'^(?P\d+)/restore/$', DocumentRestoreView.as_view(), name='document_restore'), url(r'^multiple/restore/$', DocumentManyRestoreView.as_view(), name='document_multiple_restore'), + url(r'^(?P\d+)/delete/$', DeletedDocumentDeleteView.as_view(), name='document_delete'), + url(r'^multiple/delete/$', DocumentManyDeleteView.as_view(), name='document_multiple_delete'), url(r'^(?P\d+)/type/$', 'document_document_type_edit', name='document_document_type_edit'), url(r'^multiple/type/$', 'document_multiple_document_type_edit', name='document_multiple_document_type_edit'), - url(r'^(?P\d+)/delete/$', 'document_delete', name='document_delete'), - url(r'^multiple/delete/$', 'document_multiple_delete', name='document_multiple_delete'), + url(r'^(?P\d+)/trash/$', 'document_trash', name='document_trash'), + url(r'^multiple/trash/$', 'document_multiple_trash', name='document_multiple_trash'), url(r'^(?P\d+)/edit/$', 'document_edit', name='document_edit'), url(r'^(?P\d+)/print/$', 'document_print', name='document_print'), url(r'^(?P\d+)/reset_page_count/$', 'document_update_page_count', name='document_update_page_count'), diff --git a/mayan/apps/documents/views.py b/mayan/apps/documents/views.py index 8e659d9082..0bd60ac2b8 100644 --- a/mayan/apps/documents/views.py +++ b/mayan/apps/documents/views.py @@ -45,9 +45,10 @@ from .permissions import ( permission_document_delete, permission_document_download, permission_document_print, permission_document_properties_edit, permission_document_restore, permission_document_tools, - permission_document_type_create, permission_document_type_delete, - permission_document_type_edit, permission_document_type_view, - permission_document_version_revert, permission_document_view, + permission_document_trash, permission_document_type_create, + permission_document_type_delete, permission_document_type_edit, + permission_document_type_view, permission_document_version_revert, + permission_document_view, ) from .settings import ( setting_preview_size, setting_recent_count, setting_rotation_step, @@ -67,6 +68,7 @@ class DocumentListView(SingleObjectListView): 'hide_links': True, 'title': _('All documents'), } + object_permission = permission_document_view def get_document_queryset(self): @@ -78,13 +80,22 @@ class DocumentListView(SingleObjectListView): class DeletedDocumentListView(DocumentListView): + object_permission = None + extra_context = { 'hide_link': True, 'title': _('Deleted documents'), } def get_document_queryset(self): - return DeletedDocument.objects.all() + queryset = Document.trash.all() + + try: + Permission.check_permissions(self.request.user, [permission_document_view]) + except PermissionDenied: + AccessControlList.objects.check_access(permission_document_view, self.request.user, queryset) + + return DeletedDocument.objects.filter(pk__in=queryset.values_list('pk', flat=True)) class DocumentPageListView(ParentChildListView): @@ -123,10 +134,12 @@ class DocumentRestoreView(ConfirmView): } def object_action(self, request, instance): + source_document = get_object_or_404(Document.passthrough, pk=instance.pk) + try: Permission.check_permissions(request.user, [permission_document_restore]) except PermissionDenied: - AccessControlList.objects.check_access(permission_document_restore, request.user, instance) + AccessControlList.objects.check_access(permission_document_restore, request.user, source_document) instance.restore() messages.success(request, _('Document: %(document)s restored.') % { @@ -147,6 +160,38 @@ class DocumentManyRestoreView(MultipleInstanceActionMixin, DocumentRestoreView): model = DeletedDocument +class DeletedDocumentDeleteView(ConfirmView): + extra_context = { + 'title': _('Delete the selected document?') + } + + def object_action(self, request, instance): + source_document = get_object_or_404(Document.passthrough, pk=instance.pk) + + try: + Permission.check_permissions(request.user, [permission_document_delete]) + except PermissionDenied: + AccessControlList.objects.check_access(permission_document_delete, request.user, source_document) + + instance.delete() + messages.success(request, _('Document: %(document)s deleted.') % { + 'document': instance} + ) + + def post(self, request, *args, **kwargs): + document = get_object_or_404(DeletedDocument, pk=self.kwargs['pk']) + self.object_action(request=request, instance=document) + + return HttpResponseRedirect(self.get_success_url()) + + +class DocumentManyDeleteView(MultipleInstanceActionMixin, DeletedDocumentDeleteView): + extra_context = { + 'title': _('Delete the selected documents?') + } + model = DeletedDocument + + def document_properties(request, document_id): document = get_object_or_404(Document, pk=document_id) @@ -206,7 +251,7 @@ def document_preview(request, document_id): }, context_instance=RequestContext(request)) -def document_delete(request, document_id=None, document_id_list=None): +def document_trash(request, document_id=None, document_id_list=None): post_action_redirect = None if document_id: @@ -219,9 +264,9 @@ def document_delete(request, document_id=None, document_id_list=None): return HttpResponseRedirect(request.META.get('HTTP_REFERER', reverse(settings.LOGIN_REDIRECT_URL))) try: - Permission.check_permissions(request.user, [permission_document_delete]) + Permission.check_permissions(request.user, [permission_document_trash]) except PermissionDenied: - documents = AccessControlList.objects.filter_by_access(permission_document_delete, request.user, documents, exception_on_empty=True) + documents = AccessControlList.objects.filter_by_access(permission_document_trash, request.user, documents, exception_on_empty=True) previous = request.POST.get('previous', request.GET.get('previous', request.META.get('HTTP_REFERER', reverse(settings.LOGIN_REDIRECT_URL)))) next = request.POST.get('next', request.GET.get('next', post_action_redirect if post_action_redirect else request.META.get('HTTP_REFERER', reverse(settings.LOGIN_REDIRECT_URL)))) @@ -230,9 +275,9 @@ def document_delete(request, document_id=None, document_id_list=None): for document in documents: try: document.delete() - messages.success(request, _('Document deleted successfully.')) + messages.success(request, _('Document moved to trash successfully.')) except Exception as exception: - messages.error(request, _('Document: %(document)s delete error: %(error)s') % { + messages.error(request, _('Document: %(document)s error moving to trash: %(error)s') % { 'document': document, 'error': exception }) @@ -243,8 +288,8 @@ def document_delete(request, document_id=None, document_id_list=None): 'previous': previous, 'next': next, 'title': ungettext( - 'Are you sure you wish to delete the selected document?', - 'Are you sure you wish to delete the selected documents?', + 'Move the selected document to the trash ?', + 'Move the selected documents to the trash ?', len(documents) ) } @@ -256,8 +301,8 @@ def document_delete(request, document_id=None, document_id_list=None): context_instance=RequestContext(request)) -def document_multiple_delete(request): - return document_delete( +def document_multiple_trash(request): + return document_trash( request, document_id_list=request.GET.get('id_list', []) )