Add document pages reset view

Add document version page count update view.
Add tests.
Register permission_document_tools to the Document model.

Signed-off-by: Roberto Rosario <roberto.rosario@mayan-edms.com>
This commit is contained in:
Roberto Rosario
2019-10-09 11:53:29 -04:00
parent 5b37c7715d
commit d0ee8aba16
11 changed files with 255 additions and 152 deletions

View File

@@ -59,7 +59,7 @@ from .links import (
link_document_multiple_delete, link_document_multiple_document_type_edit,
link_document_multiple_download, link_document_multiple_favorites_add,
link_document_multiple_favorites_remove, link_document_multiple_restore,
link_document_multiple_trash, link_document_multiple_update_page_count,
link_document_multiple_trash, link_document_multiple_pages_reset,
link_document_page_disable, link_document_page_multiple_disable,
link_document_page_enable, link_document_page_multiple_enable,
link_document_page_navigation_first, link_document_page_navigation_last,
@@ -74,8 +74,10 @@ from .links import (
link_document_type_filename_create, link_document_type_filename_delete,
link_document_type_filename_edit, link_document_type_filename_list,
link_document_type_list, link_document_type_policies,
link_document_type_setup, link_document_update_page_count,
link_document_type_setup, link_document_pages_reset,
link_document_version_download, link_document_version_list,
link_document_version_multiple_page_count_update,
link_document_version_page_count_update,
link_document_version_return_document, link_document_version_return_list,
link_document_version_revert, link_document_version_view,
link_duplicated_document_list, link_duplicated_document_scan,
@@ -87,10 +89,10 @@ from .permissions import (
permission_document_download, permission_document_edit,
permission_document_new_version, permission_document_print,
permission_document_properties_edit, permission_document_restore,
permission_document_trash, permission_document_type_delete,
permission_document_type_edit, permission_document_type_view,
permission_document_version_revert, permission_document_version_view,
permission_document_view
permission_document_tools, permission_document_trash,
permission_document_type_delete, permission_document_type_edit,
permission_document_type_view, permission_document_version_revert,
permission_document_version_view, permission_document_view,
)
# Just import to initialize the search models
from .search import document_search, document_page_search # NOQA
@@ -190,13 +192,15 @@ class DocumentsApp(MayanAppConfig):
permission_acl_edit, permission_acl_view,
permission_document_delete, permission_document_download,
permission_document_edit, permission_document_new_version,
permission_document_print, permission_document_properties_edit,
permission_document_restore, permission_document_trash,
permission_document_version_revert,
permission_document_print,
permission_document_properties_edit,
permission_document_restore, permission_document_tools,
permission_document_trash, permission_document_version_revert,
permission_document_version_view, permission_document_view,
permission_events_view, permission_transformation_create,
permission_transformation_delete,
permission_transformation_edit, permission_transformation_view,
permission_transformation_edit,
permission_transformation_view,
)
)
@@ -454,7 +458,7 @@ class DocumentsApp(MayanAppConfig):
link_document_quick_download, link_document_download,
link_document_clear_transformations,
link_document_clone_transformations,
link_document_update_page_count,
link_document_pages_reset,
), sources=(Document,)
)
menu_object.bind_links(
@@ -495,7 +499,7 @@ class DocumentsApp(MayanAppConfig):
link_document_multiple_favorites_remove,
link_document_multiple_clear_transformations,
link_document_multiple_trash, link_document_multiple_download,
link_document_multiple_update_page_count,
link_document_multiple_pages_reset,
link_document_multiple_document_type_edit,
), sources=(Document,)
)
@@ -547,6 +551,17 @@ class DocumentsApp(MayanAppConfig):
link_document_version_return_list
), sources=(DocumentVersion,)
)
menu_multi_item.bind_links(
links=(
link_document_version_multiple_page_count_update,
), sources=(DocumentVersion,)
)
menu_object.bind_links(
links=(
link_document_version_page_count_update,
), sources=(DocumentVersion,)
)
menu_list_facet.bind_links(
links=(link_document_version_view,), sources=(DocumentVersion,)
)

View File

@@ -36,7 +36,10 @@ icon_document_edit = Icon(
)
icon_document = Icon(driver_name='fontawesome', symbol='book')
icon_document_list = icon_document
icon_document_page_count_update = Icon(
icon_document_pages_reset = Icon(
driver_name='fontawesome', symbol='copy'
)
icon_document_version_page_count_update = Icon(
driver_name='fontawesome', symbol='copy'
)
icon_document_preview = Icon(driver_name='fontawesome', symbol='eye')

View File

@@ -168,12 +168,12 @@ link_document_quick_download = Link(
permissions=(permission_document_download,), text=_('Quick download'),
view='documents:document_download',
)
link_document_update_page_count = Link(
link_document_pages_reset = Link(
args='resolved_object.pk',
icon_class_path='mayan.apps.documents.icons.icon_document_page_count_update',
icon_class_path='mayan.apps.documents.icons.icon_document_pages_reset',
permissions=(permission_document_tools,),
text=_('Recalculate page count'),
view='documents:document_update_page_count'
text=_('Reset pages'),
view='documents:document_pages_reset'
)
link_document_restore = Link(
permissions=(permission_document_restore,),
@@ -217,10 +217,10 @@ link_document_multiple_download = Link(
text=_('Advanced download'),
view='documents:document_multiple_download_form'
)
link_document_multiple_update_page_count = Link(
icon_class_path='mayan.apps.documents.icons.icon_document_page_count_update',
text=_('Recalculate page count'),
view='documents:document_multiple_update_page_count'
link_document_multiple_pages_reset = Link(
icon_class_path='mayan.apps.documents.icons.icon_document_pages_reset',
text=_('Reset pages'),
view='documents:document_multiple_pages_reset'
)
link_document_multiple_restore = Link(
icon_class_path='mayan.apps.documents.icons.icon_trashed_document_restore',
@@ -246,6 +246,18 @@ link_document_version_return_list = Link(
permissions=(permission_document_version_view,), text=_('Versions'),
view='documents:document_version_list',
)
link_document_version_page_count_update = Link(
args='resolved_object.pk',
icon_class_path='mayan.apps.documents.icons.icon_document_version_page_count_update',
permissions=(permission_document_tools,),
text=_('Update page count'),
view='documents:document_version_page_count_update'
)
link_document_version_multiple_page_count_update = Link(
icon_class_path='mayan.apps.documents.icons.icon_document_version_page_count_update',
text=_('Update page count'),
view='documents:document_version_multiple_page_count_update'
)
link_document_version_view = Link(
args='resolved_object.pk',
icon_class_path='mayan.apps.documents.icons.icon_document_version_view',

View File

@@ -170,6 +170,9 @@ class Document(models.Model):
document_version.save(_user=_user)
logger.info('New document version queued for document: %s', self)
self.reset_pages(update_page_count=False)
return document_version
def open(self, *args, **kwargs):
@@ -186,15 +189,6 @@ class Document(models.Model):
@property
def pages(self):
return self.pages.all()
#try:
# return self.latest_version.pages
#except AttributeError:
# # Document has no version yet
# DocumentPage = apps.get_model(
# app_label='documents', model_name='DocumentVersionPage'
# )
# return DocumentPage.objects.none()
@property
def pages_all(self):
@@ -203,19 +197,16 @@ class Document(models.Model):
)
return DocumentPage.passthrough.filter(document=self)
def reset_pages(self):
def reset_pages(self, update_page_count=True):
with transaction.atomic():
for page in self.pages.all():
page.delete()
if update_page_count:
self.latest_version.update_page_count()
for version_page in self.latest_version.pages.all():
document_page = self.pages.create(
#content_type = models.ForeignKey(
# on_delete=models.CASCADE, to=ContentType
#)
#object_id = models.PositiveIntegerField()
content_object = version_page
)

View File

@@ -69,6 +69,7 @@ class DocumentTestMixin(object):
self.test_document = document
self.test_documents.append(document)
self.test_document_version = document.latest_version
class DocumentTypeViewTestMixin(object):
@@ -148,6 +149,26 @@ class DocumentVersionTestMixin(object):
)
class DocumentVersionViewTestMixin(object):
def _request_document_version_list_view(self):
return self.get(
viewname='documents:document_version_list',
kwargs={'pk': self.test_document.pk}
)
def _request_document_version_revert_view(self, document_version):
return self.post(
viewname='documents:document_version_revert',
kwargs={'pk': document_version.pk}
)
def _request_test_document_version_page_count_update_view(self):
return self.post(
viewname='documents:document_version_page_count_update',
kwargs={'pk': self.test_document_version.pk}
)
class DocumentViewTestMixin(object):
def _request_document_properties_view(self):
return self.get(
@@ -200,6 +221,12 @@ class DocumentViewTestMixin(object):
data={'id_list': self.test_document.pk}
)
def _request_document_pages_reset_view(self):
return self.post(
viewname='documents:document_pages_reset',
kwargs={'pk': self.test_document.pk}
)
def _request_document_version_download(self, data=None):
data = data or {}
return self.get(
@@ -208,18 +235,6 @@ class DocumentViewTestMixin(object):
}, data=data
)
def _request_document_update_page_count_view(self):
return self.post(
viewname='documents:document_update_page_count',
kwargs={'pk': self.test_document.pk}
)
def _request_document_multiple_update_page_count_view(self):
return self.post(
viewname='documents:document_multiple_update_page_count',
data={'id_list': self.test_document.pk}
)
def _request_document_clear_transformations_view(self):
return self.post(
viewname='documents:document_clear_transformations',
@@ -232,8 +247,11 @@ class DocumentViewTestMixin(object):
data={'id_list': self.test_document.pk}
)
def _request_empty_trash_view(self):
return self.post(viewname='documents:trash_can_empty')
def _request_document_multiple_pages_reset_view(self):
return self.post(
viewname='documents:document_multiple_pages_reset',
data={'id_list': self.test_document.pk}
)
def _request_document_print_view(self):
return self.get(
@@ -243,3 +261,7 @@ class DocumentViewTestMixin(object):
'page_group': PAGE_RANGE_ALL
}
)
def _request_empty_trash_view(self):
return self.post(viewname='documents:trash_can_empty')

View File

@@ -1,21 +1,19 @@
from __future__ import unicode_literals
from ..permissions import (
permission_document_version_revert, permission_document_version_view,
permission_document_tools, permission_document_version_revert,
permission_document_version_view,
)
from .base import GenericDocumentViewTestCase
from .literals import TEST_VERSION_COMMENT
from .mixins import DocumentVersionTestMixin
from .mixins import DocumentVersionTestMixin, DocumentVersionViewTestMixin
class DocumentVersionTestCase(DocumentVersionTestMixin, GenericDocumentViewTestCase):
def _request_document_version_list_view(self):
return self.get(
viewname='documents:document_version_list',
kwargs={'pk': self.test_document.pk}
)
class DocumentVersionTestCase(
DocumentVersionViewTestMixin, DocumentVersionTestMixin,
GenericDocumentViewTestCase
):
def test_document_version_list_no_permission(self):
self._upload_new_version()
@@ -33,12 +31,6 @@ class DocumentVersionTestCase(DocumentVersionTestMixin, GenericDocumentViewTestC
response=response, text=TEST_VERSION_COMMENT, status_code=200
)
def _request_document_version_revert_view(self, document_version):
return self.post(
viewname='documents:document_version_revert',
kwargs={'pk': document_version.pk}
)
def test_document_version_revert_no_permission(self):
first_version = self.test_document.latest_version
self._upload_new_version()
@@ -64,3 +56,25 @@ class DocumentVersionTestCase(DocumentVersionTestMixin, GenericDocumentViewTestC
self.assertEqual(response.status_code, 302)
self.assertEqual(self.test_document.versions.count(), 1)
def test_document_version_page_count_update_view_no_permission(self):
self.test_document_version.pages.all().delete()
response = self._request_test_document_version_page_count_update_view()
self.assertEqual(response.status_code, 404)
self.assertEqual(self.test_document_version.pages.count(), 0)
def test_document_version_page_count_update_view_with_access(self):
page_count = self.test_document_version.pages.count()
self.test_document_version.pages.all().delete()
self.grant_access(
obj=self.test_document, permission=permission_document_tools
)
response = self._request_test_document_version_page_count_update_view()
self.assertEqual(response.status_code, 302)
self.assertEqual(self.test_document_version.pages.count(), page_count)

View File

@@ -292,46 +292,44 @@ class DocumentsViewsTestCase(
)
)
def test_document_update_page_count_view_no_permission(self):
def test_document_pages_reset_view_no_permission(self):
self.test_document.pages.all().delete()
self.assertEqual(self.test_document.pages.count(), 0)
response = self._request_document_update_page_count_view()
response = self._request_document_pages_reset_view()
self.assertEqual(response.status_code, 404)
self.assertEqual(self.test_document.pages.count(), 0)
def test_document_update_page_count_view_with_permission(self):
# TODO: Revise permission association
def test_document_pages_reset_view_with_access(self):
page_count = self.test_document.pages.count()
self.test_document.pages.all().delete()
self.assertEqual(self.test_document.pages.count(), 0)
self.grant_permission(permission=permission_document_tools)
self.grant_access(
obj=self.test_document, permission=permission_document_tools
)
response = self._request_document_update_page_count_view()
response = self._request_document_pages_reset_view()
self.assertEqual(response.status_code, 302)
self.assertEqual(self.test_document.pages.count(), page_count)
def test_document_multiple_update_page_count_view_no_permission(self):
def test_document_multiple_pages_reset_view_no_permission(self):
self.test_document.pages.all().delete()
self.assertEqual(self.test_document.pages.count(), 0)
response = self._request_document_multiple_update_page_count_view()
response = self._request_document_multiple_pages_reset_view()
self.assertEqual(response.status_code, 404)
self.assertEqual(self.test_document.pages.count(), 0)
def test_document_multiple_update_page_count_view_with_permission(self):
def test_document_multiple_pages_reset_view_with_access(self):
page_count = self.test_document.pages.count()
self.test_document.pages.all().delete()
self.assertEqual(self.test_document.pages.count(), 0)
self.grant_permission(permission=permission_document_tools)
self.grant_access(
obj=self.test_document, permission=permission_document_tools
)
response = self._request_document_multiple_update_page_count_view()
response = self._request_document_multiple_pages_reset_view()
self.assertEqual(response.status_code, 302)
self.assertEqual(self.test_document.pages.count(), page_count)

View File

@@ -18,9 +18,10 @@ from .views.document_views import (
DocumentDocumentTypeEditView, DocumentDownloadFormView,
DocumentDownloadView, DocumentDuplicatesListView, DocumentEditView,
DocumentListView, DocumentPreviewView, DocumentPrint,
DocumentTransformationsClearView, DocumentTransformationsCloneView,
DocumentUpdatePageCountView, DocumentView, DuplicatedDocumentListView,
RecentAccessDocumentListView, RecentAddedDocumentListView
DocumentPagesResetView, DocumentTransformationsClearView,
DocumentTransformationsCloneView, DocumentView,
DuplicatedDocumentListView, RecentAccessDocumentListView,
RecentAddedDocumentListView
)
from .views.document_page_views import (
DocumentPageDisable, DocumentPageEnable, DocumentPageListView,
@@ -32,7 +33,8 @@ from .views.document_page_views import (
)
from .views.document_version_views import (
DocumentVersionDownloadFormView, DocumentVersionDownloadView,
DocumentVersionListView, DocumentVersionRevertView, DocumentVersionView,
DocumentVersionListView, DocumentVersionRevertView,
DocumentVersionUpdatePageCountView, DocumentVersionView,
)
from .views.document_type_views import (
DocumentTypeCreateView, DocumentTypeDeleteView,
@@ -174,14 +176,14 @@ urlpatterns_documents = [
name='document_print'
),
url(
regex=r'^documents/(?P<pk>\d+)/reset_page_count/$',
view=DocumentUpdatePageCountView.as_view(),
name='document_update_page_count'
regex=r'^documents/(?P<pk>\d+)/pages/reset/$',
view=DocumentPagesResetView.as_view(),
name='document_pages_reset'
),
url(
regex=r'^documents/multiple/reset_page_count/$',
view=DocumentUpdatePageCountView.as_view(),
name='document_multiple_update_page_count'
regex=r'^documents/multiple/pages/reset/$',
view=DocumentPagesResetView.as_view(),
name='document_multiple_pages_reset'
),
url(
regex=r'^documents/(?P<pk>\d+)/download/form/$',
@@ -307,6 +309,16 @@ urlpatterns_document_versions = [
view=DocumentVersionDownloadView.as_view(),
name='document_version_download'
),
url(
regex=r'^documents/versions/(?P<pk>\d+)/pages/update/$',
view=DocumentVersionUpdatePageCountView.as_view(),
name='document_version_page_count_update'
),
url(
regex=r'^documents/versions/multiple/pages/update/$',
view=DocumentVersionUpdatePageCountView.as_view(),
name='document_version_multiple_page_count_update'
),
url(
regex=r'^documents/versions/(?P<pk>\d+)/revert/$',
view=DocumentVersionRevertView.as_view(),

View File

@@ -20,7 +20,7 @@ from mayan.apps.converter.literals import DEFAULT_ROTATION, DEFAULT_ZOOM_LEVEL
from ..forms import DocumentPageForm
from ..icons import icon_document_pages
from ..links import link_document_update_page_count
from ..links import link_document_pages_reset
from ..models import Document, DocumentPage, DocumentVersionPage
from ..permissions import permission_document_edit, permission_document_view
from ..settings import (
@@ -50,13 +50,13 @@ class DocumentPageListView(ExternalObjectMixin, SingleObjectListView):
'hide_object': True,
'list_as_items': True,
'no_results_icon': icon_document_pages,
'no_results_main_link': link_document_update_page_count.resolve(
'no_results_main_link': link_document_pages_reset.resolve(
request=self.request, resolved_object=self.external_object
),
'no_results_text': _(
'This could mean that the document is of a format that is '
'not supported, that it is corrupted or that the upload '
'process was interrupted. Use the document page recalculation '
'not supported, that it is corrupted, or that the upload '
'process was interrupted. Use the document page reset '
'action to attempt to introspect the page count again.'
),
'no_results_title': _('No document pages available'),

View File

@@ -3,10 +3,11 @@ from __future__ import absolute_import, unicode_literals
import logging
from django.contrib import messages
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ugettext_lazy as _, ungettext
from mayan.apps.common.generics import (
ConfirmView, SingleObjectDetailView, SingleObjectListView
ConfirmView, MultipleObjectConfirmActionView, SingleObjectDetailView,
SingleObjectListView
)
from mayan.apps.common.mixins import ExternalObjectMixin
@@ -14,9 +15,10 @@ from ..events import event_document_view
from ..forms import DocumentVersionDownloadForm, DocumentVersionPreviewForm
from ..models import Document, DocumentVersion
from ..permissions import (
permission_document_download, permission_document_version_revert,
permission_document_version_view
permission_document_download, permission_document_tools,
permission_document_version_revert, permission_document_version_view
)
from ..tasks import task_update_page_count
from .document_views import DocumentDownloadFormView, DocumentDownloadView
@@ -142,6 +144,45 @@ class DocumentVersionRevertView(ExternalObjectMixin, ConfirmView):
)
class DocumentVersionUpdatePageCountView(MultipleObjectConfirmActionView):
model = DocumentVersion
object_permission = permission_document_tools
success_message = _(
'%(count)d document version queued for page count recalculation'
)
success_message_plural = _(
'%(count)d documents version queued for page count recalculation'
)
def get_extra_context(self):
queryset = self.object_list
result = {
'title': ungettext(
singular='Recalculate the page count of the selected document version?',
plural='Recalculate the page count of the selected document versions?',
number=queryset.count()
)
}
if queryset.count() == 1:
result.update(
{
'object': queryset.first(),
'title': _(
'Recalculate the page count of the document version: %s?'
) % queryset.first()
}
)
return result
def object_action(self, form, instance):
task_update_page_count.apply_async(
kwargs={'version_id': instance.pk}
)
class DocumentVersionView(SingleObjectDetailView):
form_class = DocumentVersionPreviewForm
model = DocumentVersion

View File

@@ -44,14 +44,14 @@ from ..permissions import (
from ..settings import (
setting_print_width, setting_print_height, setting_recent_added_count
)
from ..tasks import task_update_page_count
from ..tasks import task_document_reset_pages
from ..utils import parse_range
__all__ = (
'DocumentListView', 'DocumentDocumentTypeEditView',
'DocumentDuplicatesListView', 'DocumentEditView', 'DocumentPreviewView',
'DocumentView', 'DocumentDownloadFormView', 'DocumentDownloadView',
'DocumentUpdatePageCountView', 'DocumentTransformationsClearView',
'DocumentPagesResetView', 'DocumentTransformationsClearView',
'DocumentTransformationsCloneView', 'DocumentPrint',
'DuplicatedDocumentListView', 'RecentAccessDocumentListView',
'RecentAddedDocumentListView'
@@ -418,6 +418,52 @@ class DocumentPreviewView(SingleObjectDetailView):
}
class DocumentPagesResetView(MultipleObjectConfirmActionView):
model = Document
object_permission = permission_document_tools
success_message = _('%(count)d document queued for pages reset')
success_message_plural = _('%(count)d documents queued for pages reset')
def get_extra_context(self):
queryset = self.object_list
result = {
'title': ungettext(
singular='Reset the pages of the selected document?',
plural='Reset the pages of the selected documents?',
number=queryset.count()
)
}
if queryset.count() == 1:
result.update(
{
'object': queryset.first(),
'title': _(
'Reset the pages of the document: %s?'
) % queryset.first()
}
)
return result
def object_action(self, form, instance):
latest_version = instance.latest_version
if latest_version:
task_document_reset_pages.apply_async(
kwargs={'document_id': instance.pk}
)
else:
messages.error(
self.request, _(
'Document "%(document)s" is empty. Upload at least one '
'document version before attempting to reset the pages. '
) % {
'document': instance,
}
)
class DocumentView(SingleObjectDetailView):
form_class = DocumentPropertiesForm
model = Document
@@ -436,57 +482,6 @@ class DocumentView(SingleObjectDetailView):
}
class DocumentUpdatePageCountView(MultipleObjectConfirmActionView):
model = Document
object_permission = permission_document_tools
success_message = _(
'%(count)d document queued for page count recalculation'
)
success_message_plural = _(
'%(count)d documents queued for page count recalculation'
)
def get_extra_context(self):
queryset = self.object_list
result = {
'title': ungettext(
singular='Recalculate the page count of the selected document?',
plural='Recalculate the page count of the selected documents?',
number=queryset.count()
)
}
if queryset.count() == 1:
result.update(
{
'object': queryset.first(),
'title': _(
'Recalculate the page count of the document: %s?'
) % queryset.first()
}
)
return result
def object_action(self, form, instance):
latest_version = instance.latest_version
if latest_version:
task_update_page_count.apply_async(
kwargs={'version_id': latest_version.pk}
)
else:
messages.error(
self.request, _(
'Document "%(document)s" is empty. Upload at least one '
'document version before attempting to detect the '
'page count.'
) % {
'document': instance,
}
)
class DocumentTransformationsClearView(MultipleObjectConfirmActionView):
model = Document
object_permission = permission_transformation_delete