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:
@@ -3,3 +3,4 @@ from .document_type_views import * # NOQA
|
||||
from .document_version_views import * # NOQA
|
||||
from .document_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.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.utils.encoding import force_text
|
||||
from django.utils.http import urlencode
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
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.mixins import ExternalObjectMixin
|
||||
from mayan.apps.common.utils import resolve
|
||||
from mayan.apps.converter.literals import DEFAULT_ROTATION, DEFAULT_ZOOM_LEVEL
|
||||
|
||||
@@ -37,53 +36,40 @@ __all__ = (
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class DocumentPageInteractiveTransformation(RedirectView):
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
obj = self.get_object()
|
||||
|
||||
AccessControlList.objects.check_access(
|
||||
obj=obj, permissions=permission_document_view, user=request.user,
|
||||
)
|
||||
|
||||
return super(DocumentPageInteractiveTransformation, self).dispatch(
|
||||
request, *args, **kwargs
|
||||
)
|
||||
class DocumentPageInteractiveTransformation(ExternalObjectMixin, RedirectView):
|
||||
external_object_class = DocumentPage
|
||||
external_object_permission = permission_document_view
|
||||
external_object_pk_url_kwarg = 'document_page_id'
|
||||
|
||||
def get_object(self):
|
||||
return get_object_or_404(
|
||||
klass=DocumentPage, pk=self.kwargs['document_page_pk']
|
||||
)
|
||||
return self.get_external_object()
|
||||
|
||||
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 = {
|
||||
'rotation': int(
|
||||
self.request.GET.get('rotation', DEFAULT_ROTATION)
|
||||
), 'zoom': int(self.request.GET.get('zoom', DEFAULT_ZOOM_LEVEL))
|
||||
'rotation': self.request.GET.get('rotation', DEFAULT_ROTATION),
|
||||
'zoom': 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(
|
||||
DocumentPageListView, self
|
||||
).dispatch(request, *args, **kwargs)
|
||||
self.transformation_function(query_dict=query_dict)
|
||||
|
||||
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):
|
||||
return get_object_or_404(klass=Document, pk=self.kwargs['document_pk'])
|
||||
return self.get_external_object()
|
||||
|
||||
def get_extra_context(self):
|
||||
return {
|
||||
@@ -95,27 +81,17 @@ class DocumentPageListView(SingleObjectListView):
|
||||
'title': _('Pages for document: %s') % self.get_document(),
|
||||
}
|
||||
|
||||
def get_object_list(self):
|
||||
def get_source_queryset(self):
|
||||
return self.get_document().pages.all()
|
||||
|
||||
|
||||
class DocumentPageNavigationBase(RedirectView):
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
document_page = self.get_object()
|
||||
|
||||
AccessControlList.objects.check_access(
|
||||
permissions=permission_document_view, user=request.user,
|
||||
obj=document_page.document
|
||||
)
|
||||
|
||||
return super(DocumentPageNavigationBase, self).dispatch(
|
||||
request, *args, **kwargs
|
||||
)
|
||||
class DocumentPageNavigationBase(ExternalObjectMixin, RedirectView):
|
||||
external_object_class = DocumentPage
|
||||
external_object_permission = permission_document_view
|
||||
external_object_pk_url_kwarg = 'document_page_id'
|
||||
|
||||
def get_object(self):
|
||||
return get_object_or_404(
|
||||
klass=DocumentPage, pk=self.kwargs['document_page_pk']
|
||||
)
|
||||
return self.get_external_object()
|
||||
|
||||
def get_redirect_url(self, *args, **kwargs):
|
||||
"""
|
||||
@@ -158,14 +134,14 @@ class DocumentPageNavigationFirst(DocumentPageNavigationBase):
|
||||
def get_new_kwargs(self):
|
||||
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):
|
||||
def get_new_kwargs(self):
|
||||
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):
|
||||
@@ -178,12 +154,12 @@ class DocumentPageNavigationNext(DocumentPageNavigationBase):
|
||||
)
|
||||
except DocumentPage.DoesNotExist:
|
||||
messages.warning(
|
||||
request=self.request, message=_(
|
||||
message=_(
|
||||
'There are no more pages in this document'
|
||||
)
|
||||
), request=self.request
|
||||
)
|
||||
finally:
|
||||
return {'document_page_pk': document_page.pk}
|
||||
return {'document_page_id': document_page.pk}
|
||||
|
||||
|
||||
class DocumentPageNavigationPrevious(DocumentPageNavigationBase):
|
||||
@@ -196,47 +172,40 @@ class DocumentPageNavigationPrevious(DocumentPageNavigationBase):
|
||||
)
|
||||
except DocumentPage.DoesNotExist:
|
||||
messages.warning(
|
||||
request=self.request, message=_(
|
||||
message=_(
|
||||
'You are already at the first page of this document'
|
||||
)
|
||||
), request=self.request
|
||||
)
|
||||
finally:
|
||||
return {'document_page_pk': document_page.pk}
|
||||
return {'document_page_id': document_page.pk}
|
||||
|
||||
|
||||
class DocumentPageRotateLeftView(DocumentPageInteractiveTransformation):
|
||||
def transformation_function(self, query_dict):
|
||||
query_dict['rotation'] = (
|
||||
query_dict['rotation'] - setting_rotation_step.value
|
||||
int(query_dict['rotation']) - setting_rotation_step.value
|
||||
) % 360
|
||||
|
||||
|
||||
class DocumentPageRotateRightView(DocumentPageInteractiveTransformation):
|
||||
def transformation_function(self, query_dict):
|
||||
query_dict['rotation'] = (
|
||||
query_dict['rotation'] + setting_rotation_step.value
|
||||
int(query_dict['rotation']) + setting_rotation_step.value
|
||||
) % 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'
|
||||
|
||||
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):
|
||||
zoom = int(self.request.GET.get('zoom', DEFAULT_ZOOM_LEVEL))
|
||||
rotation = int(self.request.GET.get('rotation', DEFAULT_ROTATION))
|
||||
|
||||
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()
|
||||
@@ -252,15 +221,13 @@ class DocumentPageView(SimpleView):
|
||||
'navigation_object_list': ('page',),
|
||||
'page': self.get_object(),
|
||||
'rotation': rotation,
|
||||
'title': ' '.join((base_title, zoom_text,)),
|
||||
'title': ' '.join((base_title, zoom_text)),
|
||||
'read_only': True,
|
||||
'zoom': zoom,
|
||||
}
|
||||
|
||||
def get_object(self):
|
||||
return get_object_or_404(
|
||||
klass=DocumentPage, pk=self.kwargs['document_page_pk']
|
||||
)
|
||||
return self.get_external_object()
|
||||
|
||||
|
||||
class DocumentPageViewResetView(RedirectView):
|
||||
@@ -269,7 +236,7 @@ class DocumentPageViewResetView(RedirectView):
|
||||
|
||||
class DocumentPageZoomInView(DocumentPageInteractiveTransformation):
|
||||
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:
|
||||
zoom = setting_zoom_max_level.value
|
||||
@@ -279,7 +246,7 @@ class DocumentPageZoomInView(DocumentPageInteractiveTransformation):
|
||||
|
||||
class DocumentPageZoomOutView(DocumentPageInteractiveTransformation):
|
||||
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:
|
||||
zoom = setting_zoom_min_level.value
|
||||
|
||||
@@ -2,16 +2,15 @@ from __future__ import absolute_import, unicode_literals
|
||||
|
||||
import logging
|
||||
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django.template import RequestContext
|
||||
from django.urls import reverse, reverse_lazy
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from mayan.apps.acls.models import AccessControlList
|
||||
from mayan.apps.common.generics import (
|
||||
SingleObjectCreateView, SingleObjectDeleteView, SingleObjectEditView,
|
||||
SingleObjectListView
|
||||
)
|
||||
from mayan.apps.common.mixins import ExternalObjectMixin
|
||||
|
||||
from ..forms import DocumentTypeFilenameForm_create
|
||||
from ..icons import icon_document_type_filename, icon_document_type_setup
|
||||
@@ -60,7 +59,7 @@ class DocumentTypeDeleteView(SingleObjectDeleteView):
|
||||
model = DocumentType
|
||||
object_permission = permission_document_type_delete
|
||||
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):
|
||||
return {
|
||||
@@ -70,13 +69,17 @@ class DocumentTypeDeleteView(SingleObjectDeleteView):
|
||||
}
|
||||
|
||||
|
||||
class DocumentTypeDocumentListView(DocumentListView):
|
||||
def get_document_type(self):
|
||||
return get_object_or_404(klass=DocumentType, pk=self.kwargs['document_type_pk'])
|
||||
class DocumentTypeDocumentListView(ExternalObjectMixin, DocumentListView):
|
||||
external_object_class = DocumentType
|
||||
external_object_permission = permission_document_type_view
|
||||
external_object_pk_url_kwarg = 'document_type_id'
|
||||
|
||||
def get_document_queryset(self):
|
||||
return self.get_document_type().documents.all()
|
||||
|
||||
def get_document_type(self):
|
||||
return self.get_external_object()
|
||||
|
||||
def get_extra_context(self):
|
||||
context = super(DocumentTypeDocumentListView, self).get_extra_context()
|
||||
context.update(
|
||||
@@ -95,7 +98,7 @@ class DocumentTypeEditView(SingleObjectEditView):
|
||||
)
|
||||
model = DocumentType
|
||||
object_permission = permission_document_type_edit
|
||||
pk_url_kwarg = 'document_type_pk'
|
||||
pk_url_kwarg = 'document_type_id'
|
||||
post_action_redirect = reverse_lazy(
|
||||
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
|
||||
|
||||
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):
|
||||
return get_object_or_404(klass=DocumentType, pk=self.kwargs['document_type_pk'])
|
||||
return self.get_external_object()
|
||||
|
||||
def get_extra_context(self):
|
||||
return {
|
||||
@@ -168,7 +164,7 @@ class DocumentTypeFilenameCreateView(SingleObjectCreateView):
|
||||
class DocumentTypeFilenameDeleteView(SingleObjectDeleteView):
|
||||
model = DocumentTypeFilename
|
||||
object_permission = permission_document_type_edit
|
||||
pk_url_kwarg = 'filename_pk'
|
||||
pk_url_kwarg = 'filename_id'
|
||||
|
||||
def get_extra_context(self):
|
||||
return {
|
||||
@@ -187,7 +183,7 @@ class DocumentTypeFilenameDeleteView(SingleObjectDeleteView):
|
||||
def get_post_action_redirect(self):
|
||||
return reverse(
|
||||
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',)
|
||||
model = DocumentTypeFilename
|
||||
object_permission = permission_document_type_edit
|
||||
pk_url_kwarg = 'filename_pk'
|
||||
pk_url_kwarg = 'filename_id'
|
||||
|
||||
def get_extra_context(self):
|
||||
document_type_filename = self.get_object()
|
||||
@@ -216,16 +212,17 @@ class DocumentTypeFilenameEditView(SingleObjectEditView):
|
||||
def get_post_action_redirect(self):
|
||||
return reverse(
|
||||
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):
|
||||
access_object_retrieve_method = 'get_document_type'
|
||||
object_permission = permission_document_type_view
|
||||
class DocumentTypeFilenameListView(ExternalObjectMixin, SingleObjectListView):
|
||||
external_object_class = DocumentType
|
||||
external_object_permission = permission_document_type_view
|
||||
external_object_pk_url_kwarg = 'document_type_id'
|
||||
|
||||
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):
|
||||
return {
|
||||
@@ -255,5 +252,5 @@ class DocumentTypeFilenameListView(SingleObjectListView):
|
||||
) % self.get_document_type(),
|
||||
}
|
||||
|
||||
def get_object_list(self):
|
||||
def get_source_queryset(self):
|
||||
return self.get_document_type().filenames.all()
|
||||
|
||||
@@ -3,15 +3,14 @@ from __future__ import absolute_import, unicode_literals
|
||||
import logging
|
||||
|
||||
from django.contrib import messages
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from mayan.apps.acls.models import AccessControlList
|
||||
from mayan.apps.common.generics import (
|
||||
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 ..models import Document, DocumentVersion
|
||||
from ..permissions import (
|
||||
@@ -21,79 +20,22 @@ from ..permissions import (
|
||||
|
||||
from .document_views import DocumentDownloadFormView, DocumentDownloadView
|
||||
|
||||
__all__ = (
|
||||
'DocumentVersionDownloadFormView', 'DocumentVersionDownloadView',
|
||||
'DocumentVersionListView', 'DocumentVersionRevertView',
|
||||
'DocumentVersionView'
|
||||
)
|
||||
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):
|
||||
form_class = DocumentVersionDownloadForm
|
||||
model = DocumentVersion
|
||||
multiple_download_view = None
|
||||
pk_url_kwarg = 'document_version_pk'
|
||||
pk_url_kwarg = 'document_version_id'
|
||||
querystring_form_fields = (
|
||||
'compressed', 'zip_filename', 'preserve_extension'
|
||||
)
|
||||
single_download_view = 'documents:document_version_download'
|
||||
viewname = 'documents:document_version_download'
|
||||
|
||||
def get_extra_context(self):
|
||||
result = super(
|
||||
@@ -106,30 +48,26 @@ class DocumentVersionDownloadFormView(DocumentDownloadFormView):
|
||||
|
||||
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):
|
||||
model = DocumentVersion
|
||||
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
|
||||
def get_item_file(item):
|
||||
return item.file
|
||||
|
||||
def get_encoding(self):
|
||||
return self.get_object().encoding
|
||||
return self.get_object_list().first().encoding
|
||||
|
||||
def get_item_label(self, item):
|
||||
preserve_extension = self.request.GET.get(
|
||||
@@ -143,13 +81,69 @@ class DocumentVersionDownloadView(DocumentDownloadView):
|
||||
return item.get_rendered_string(preserve_extension=preserve_extension)
|
||||
|
||||
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):
|
||||
form_class = DocumentVersionPreviewForm
|
||||
model = DocumentVersion
|
||||
object_permission = permission_document_version_view
|
||||
pk_url_kwarg = 'document_version_id'
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
result = super(
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -24,7 +24,8 @@ class ClearImageCacheView(ConfirmView):
|
||||
def view_action(self):
|
||||
task_clear_image_cache.apply_async()
|
||||
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):
|
||||
task_scan_duplicates_all.apply_async()
|
||||
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()
|
||||
Reference in New Issue
Block a user