From 315e70309b2a7fb8e368fcf28601e52097b5cdb0 Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Fri, 14 Dec 2018 15:44:25 -0400 Subject: [PATCH] Documents: Split monolith forms.py Split the documents/forms.py into sub modules for each logical unit: types, document, pages, versions. Signed-off-by: Roberto Rosario --- mayan/apps/documents/forms/__init__.py | 4 + .../{forms.py => forms/document_forms.py} | 176 +++++------------- .../documents/forms/document_page_forms.py | 40 ++++ .../documents/forms/document_type_forms.py | 44 +++++ .../documents/forms/document_version_forms.py | 33 ++++ .../documents/views/document_page_views.py | 100 +++++----- .../documents/views/document_type_views.py | 139 +++++++------- mayan/apps/documents/views/misc_views.py | 2 + 8 files changed, 298 insertions(+), 240 deletions(-) create mode 100644 mayan/apps/documents/forms/__init__.py rename mayan/apps/documents/{forms.py => forms/document_forms.py} (67%) create mode 100644 mayan/apps/documents/forms/document_page_forms.py create mode 100644 mayan/apps/documents/forms/document_type_forms.py create mode 100644 mayan/apps/documents/forms/document_version_forms.py diff --git a/mayan/apps/documents/forms/__init__.py b/mayan/apps/documents/forms/__init__.py new file mode 100644 index 0000000000..a0e859bab2 --- /dev/null +++ b/mayan/apps/documents/forms/__init__.py @@ -0,0 +1,4 @@ +from .document_forms import * # NOQA +from .document_page_forms import * # NOQA +from .document_type_forms import * # NOQA +from .document_version_forms import * # NOQA diff --git a/mayan/apps/documents/forms.py b/mayan/apps/documents/forms/document_forms.py similarity index 67% rename from mayan/apps/documents/forms.py rename to mayan/apps/documents/forms/document_forms.py index f8d0bb2f72..deeda7a1ac 100644 --- a/mayan/apps/documents/forms.py +++ b/mayan/apps/documents/forms/document_forms.py @@ -7,52 +7,45 @@ from django import forms from django.template.defaultfilters import filesizeformat from django.utils.translation import ugettext_lazy as _ -from mayan.apps.acls.models import AccessControlList from mayan.apps.common.forms import DetailForm -from .fields import DocumentField, DocumentPageField, DocumentVersionField -from .literals import DEFAULT_ZIP_FILENAME, PAGE_RANGE_ALL, PAGE_RANGE_CHOICES -from .models import Document, DocumentType, DocumentTypeFilename -from .permissions import permission_document_create -from .runtime import language_choices +from ..fields import DocumentField +from ..literals import DEFAULT_ZIP_FILENAME, PAGE_RANGE_ALL, PAGE_RANGE_CHOICES +from ..models import Document +from ..runtime import language_choices +__all__ = ( + 'DocumentDownloadForm', 'DocumentForm', 'DocumentPreviewForm', + 'DocumentPrintForm', 'DocumentPropertiesForm' +) logger = logging.getLogger(__name__) -# Document page forms - -class DocumentPageForm(forms.Form): - document_page = DocumentPageField() +class DocumentDownloadForm(forms.Form): + compressed = forms.BooleanField( + label=_('Compress'), required=False, + help_text=_( + 'Download the document in the original format or in a compressed ' + 'manner. This option is selectable only when downloading one ' + 'document, for multiple documents, the bundle will always be ' + 'downloads as a compressed file.' + ) + ) + zip_filename = forms.CharField( + initial=DEFAULT_ZIP_FILENAME, label=_('Compressed filename'), + required=False, + help_text=_( + 'The filename of the compressed file that will contain the ' + 'documents to be downloaded, if the previous option is selected.' + ) + ) def __init__(self, *args, **kwargs): - instance = kwargs.pop('instance', None) - rotation = kwargs.pop('rotation', None) - zoom = kwargs.pop('zoom', None) - super(DocumentPageForm, self).__init__(*args, **kwargs) - self.fields['document_page'].initial = instance - self.fields['document_page'].widget.attrs.update({ - 'zoom': zoom, - 'rotation': rotation, - }) - - -# Document forms -class DocumentPreviewForm(forms.Form): - document = DocumentField() - - def __init__(self, *args, **kwargs): - document = kwargs.pop('instance', None) - super(DocumentPreviewForm, self).__init__(*args, **kwargs) - self.fields['document'].initial = document - - -class DocumentVersionPreviewForm(forms.Form): - document_version = DocumentVersionField() - - def __init__(self, *args, **kwargs): - document_version = kwargs.pop('instance', None) - super(DocumentVersionPreviewForm, self).__init__(*args, **kwargs) - self.fields['document_version'].initial = document_version + self.queryset = kwargs.pop('queryset', None) + super(DocumentDownloadForm, self).__init__(*args, **kwargs) + if self.queryset.count() > 1: + self.fields['compressed'].initial = True + self.fields['compressed'].widget.attrs.update({'disabled': True}) class DocumentForm(forms.ModelForm): @@ -133,6 +126,23 @@ class DocumentForm(forms.ModelForm): return filename +class DocumentPreviewForm(forms.Form): + document = DocumentField() + + def __init__(self, *args, **kwargs): + document = kwargs.pop('instance', None) + super(DocumentPreviewForm, self).__init__(*args, **kwargs) + self.fields['document'].initial = document + + +class DocumentPrintForm(forms.Form): + page_group = forms.ChoiceField( + choices=PAGE_RANGE_CHOICES, initial=PAGE_RANGE_ALL, + widget=forms.RadioSelect + ) + page_range = forms.CharField(label=_('Page range'), required=False) + + class DocumentPropertiesForm(DetailForm): """ Detail class form to display a document file based properties @@ -188,93 +198,3 @@ class DocumentPropertiesForm(DetailForm): class Meta: fields = ('document_type', 'description') model = Document - - -class DocumentTypeSelectForm(forms.Form): - """ - Form to select the document type of a document to be created, used - as form #1 in the document creation wizard - """ - def __init__(self, *args, **kwargs): - user = kwargs.pop('user', None) - logger.debug('user: %s', user) - super(DocumentTypeSelectForm, self).__init__(*args, **kwargs) - - queryset = AccessControlList.objects.filter_by_access( - permission_document_create, user, - queryset=DocumentType.objects.all() - ) - - self.fields['document_type'] = forms.ModelChoiceField( - empty_label=None, label=_('Document type'), queryset=queryset, - required=True, widget=forms.widgets.Select(attrs={'size': 10}) - ) - - -class DocumentTypeFilenameForm_create(forms.ModelForm): - """ - Model class form to create a new document type filename - """ - class Meta: - fields = ('filename',) - model = DocumentTypeFilename - - -class DocumentDownloadForm(forms.Form): - compressed = forms.BooleanField( - label=_('Compress'), required=False, - help_text=_( - 'Download the document in the original format or in a compressed ' - 'manner. This option is selectable only when downloading one ' - 'document, for multiple documents, the bundle will always be ' - 'downloads as a compressed file.' - ) - ) - zip_filename = forms.CharField( - initial=DEFAULT_ZIP_FILENAME, label=_('Compressed filename'), - required=False, - help_text=_( - 'The filename of the compressed file that will contain the ' - 'documents to be downloaded, if the previous option is selected.' - ) - ) - - def __init__(self, *args, **kwargs): - self.queryset = kwargs.pop('queryset', None) - super(DocumentDownloadForm, self).__init__(*args, **kwargs) - if self.queryset.count() > 1: - self.fields['compressed'].initial = True - self.fields['compressed'].widget.attrs.update({'disabled': True}) - - -class DocumentVersionDownloadForm(DocumentDownloadForm): - preserve_extension = forms.BooleanField( - label=_('Preserve extension'), required=False, - help_text=_( - 'Takes the file extension and moves it to the end of the ' - 'filename allowing operating systems that rely on file ' - 'extensions to open the downloaded document version correctly.' - ) - ) - - -class DocumentPrintForm(forms.Form): - page_group = forms.ChoiceField( - choices=PAGE_RANGE_CHOICES, initial=PAGE_RANGE_ALL, - widget=forms.RadioSelect - ) - page_range = forms.CharField(label=_('Page range'), required=False) - - -class DocumentPageNumberForm(forms.Form): - page = forms.ModelChoiceField( - help_text=_( - 'Page number from which all the transformation will be cloned. ' - 'Existing transformations will be lost.' - ), queryset=None - ) - - def __init__(self, *args, **kwargs): - self.document = kwargs.pop('document') - super(DocumentPageNumberForm, self).__init__(*args, **kwargs) - self.fields['page'].queryset = self.document.pages.all() diff --git a/mayan/apps/documents/forms/document_page_forms.py b/mayan/apps/documents/forms/document_page_forms.py new file mode 100644 index 0000000000..f93b836f34 --- /dev/null +++ b/mayan/apps/documents/forms/document_page_forms.py @@ -0,0 +1,40 @@ +from __future__ import absolute_import, unicode_literals + +import logging + +from django import forms +from django.utils.translation import ugettext_lazy as _ + +from ..fields import DocumentPageField + +__all__ = ('DocumentPageForm', 'DocumentPageNumberForm') +logger = logging.getLogger(__name__) + + +class DocumentPageForm(forms.Form): + document_page = DocumentPageField() + + def __init__(self, *args, **kwargs): + instance = kwargs.pop('instance', None) + rotation = kwargs.pop('rotation', None) + zoom = kwargs.pop('zoom', None) + super(DocumentPageForm, self).__init__(*args, **kwargs) + self.fields['document_page'].initial = instance + self.fields['document_page'].widget.attrs.update({ + 'zoom': zoom, + 'rotation': rotation, + }) + + +class DocumentPageNumberForm(forms.Form): + page = forms.ModelChoiceField( + help_text=_( + 'Page number from which all the transformation will be cloned. ' + 'Existing transformations will be lost.' + ), queryset=None + ) + + def __init__(self, *args, **kwargs): + self.document = kwargs.pop('document') + super(DocumentPageNumberForm, self).__init__(*args, **kwargs) + self.fields['page'].queryset = self.document.pages.all() diff --git a/mayan/apps/documents/forms/document_type_forms.py b/mayan/apps/documents/forms/document_type_forms.py new file mode 100644 index 0000000000..897525a019 --- /dev/null +++ b/mayan/apps/documents/forms/document_type_forms.py @@ -0,0 +1,44 @@ +from __future__ import absolute_import, unicode_literals + +import logging + +from django import forms +from django.utils.translation import ugettext_lazy as _ + +from mayan.apps.acls.models import AccessControlList + +from ..models import DocumentType, DocumentTypeFilename +from ..permissions import permission_document_create + +__all__ = ('DocumentTypeFilenameForm_create', 'DocumentTypeSelectForm') +logger = logging.getLogger(__name__) + + +class DocumentTypeFilenameForm_create(forms.ModelForm): + """ + Model class form to create a new document type filename + """ + class Meta: + fields = ('filename',) + model = DocumentTypeFilename + + +class DocumentTypeSelectForm(forms.Form): + """ + Form to select the document type of a document to be created, used + as form #1 in the document creation wizard + """ + def __init__(self, *args, **kwargs): + user = kwargs.pop('user', None) + logger.debug('user: %s', user) + super(DocumentTypeSelectForm, self).__init__(*args, **kwargs) + + queryset = AccessControlList.objects.filter_by_access( + permission_document_create, user, + queryset=DocumentType.objects.all() + ) + + self.fields['document_type'] = forms.ModelChoiceField( + empty_label=None, label=_('Document type'), queryset=queryset, + required=True, widget=forms.widgets.Select(attrs={'size': 10}) + ) diff --git a/mayan/apps/documents/forms/document_version_forms.py b/mayan/apps/documents/forms/document_version_forms.py new file mode 100644 index 0000000000..d8e5fddbbe --- /dev/null +++ b/mayan/apps/documents/forms/document_version_forms.py @@ -0,0 +1,33 @@ +from __future__ import absolute_import, unicode_literals + +import logging + +from django import forms +from django.utils.translation import ugettext_lazy as _ + +from ..fields import DocumentVersionField + +from .document_forms import DocumentDownloadForm + +__all__ = ('DocumentVersionDownloadForm', 'DocumentVersionPreviewForm') +logger = logging.getLogger(__name__) + + +class DocumentVersionDownloadForm(DocumentDownloadForm): + preserve_extension = forms.BooleanField( + label=_('Preserve extension'), required=False, + help_text=_( + 'Takes the file extension and moves it to the end of the ' + 'filename allowing operating systems that rely on file ' + 'extensions to open the downloaded document version correctly.' + ) + ) + + +class DocumentVersionPreviewForm(forms.Form): + document_version = DocumentVersionField() + + def __init__(self, *args, **kwargs): + document_version = kwargs.pop('instance', None) + super(DocumentVersionPreviewForm, self).__init__(*args, **kwargs) + self.fields['document_version'].initial = document_version diff --git a/mayan/apps/documents/views/document_page_views.py b/mayan/apps/documents/views/document_page_views.py index 28ffca983a..d6b269eb4c 100644 --- a/mayan/apps/documents/views/document_page_views.py +++ b/mayan/apps/documents/views/document_page_views.py @@ -24,9 +24,49 @@ from ..settings import ( setting_zoom_percent_step ) +__all__ = ( + 'DocumentPageListView', 'DocumentPageNavigationFirst', + 'DocumentPageNavigationLast', 'DocumentPageNavigationNext', + 'DocumentPageNavigationPrevious', 'DocumentPageRotateLeftView', + 'DocumentPageRotateRightView', 'DocumentPageView', + 'DocumentPageViewResetView', 'DocumentPageZoomInView', + 'DocumentPageZoomOutView', +) logger = logging.getLogger(__name__) +class DocumentPageInteractiveTransformation(RedirectView): + def dispatch(self, request, *args, **kwargs): + object = self.get_object() + + AccessControlList.objects.check_access( + permissions=permission_document_view, user=request.user, + obj=object + ) + + return super(DocumentPageInteractiveTransformation, self).dispatch( + request, *args, **kwargs + ) + + def get_object(self): + return get_object_or_404(DocumentPage, pk=self.kwargs['pk']) + + def get_redirect_url(self, *args, **kwargs): + url = reverse( + 'documents:document_page_view', args=(self.kwargs['pk'],) + ) + + query_dict = { + 'rotation': int( + self.request.GET.get('rotation', DEFAULT_ROTATION) + ), 'zoom': int(self.request.GET.get('zoom', DEFAULT_ZOOM_LEVEL)) + } + + self.transformation_function(query_dict) + + return '{}?{}'.format(url, urlencode(query_dict)) + + class DocumentPageListView(SingleObjectListView): def dispatch(self, request, *args, **kwargs): AccessControlList.objects.check_access( @@ -157,6 +197,20 @@ class DocumentPageNavigationPrevious(DocumentPageNavigationBase): return document_page +class DocumentPageRotateLeftView(DocumentPageInteractiveTransformation): + def transformation_function(self, query_dict): + query_dict['rotation'] = ( + 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 + ) % 360 + + class DocumentPageView(SimpleView): template_name = 'appearance/generic_form.html' @@ -204,38 +258,6 @@ class DocumentPageViewResetView(RedirectView): pattern_name = 'documents:document_page_view' -class DocumentPageInteractiveTransformation(RedirectView): - def dispatch(self, request, *args, **kwargs): - object = self.get_object() - - AccessControlList.objects.check_access( - permissions=permission_document_view, user=request.user, - obj=object - ) - - return super(DocumentPageInteractiveTransformation, self).dispatch( - request, *args, **kwargs - ) - - def get_object(self): - return get_object_or_404(DocumentPage, pk=self.kwargs['pk']) - - def get_redirect_url(self, *args, **kwargs): - url = reverse( - 'documents:document_page_view', args=(self.kwargs['pk'],) - ) - - query_dict = { - 'rotation': int( - self.request.GET.get('rotation', DEFAULT_ROTATION) - ), 'zoom': int(self.request.GET.get('zoom', DEFAULT_ZOOM_LEVEL)) - } - - self.transformation_function(query_dict) - - return '{}?{}'.format(url, urlencode(query_dict)) - - class DocumentPageZoomInView(DocumentPageInteractiveTransformation): def transformation_function(self, query_dict): zoom = query_dict['zoom'] + setting_zoom_percent_step.value @@ -254,17 +276,3 @@ class DocumentPageZoomOutView(DocumentPageInteractiveTransformation): zoom = setting_zoom_min_level.value query_dict['zoom'] = zoom - - -class DocumentPageRotateLeftView(DocumentPageInteractiveTransformation): - def transformation_function(self, query_dict): - query_dict['rotation'] = ( - 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 - ) % 360 diff --git a/mayan/apps/documents/views/document_type_views.py b/mayan/apps/documents/views/document_type_views.py index bf1b6d89a8..1c2dbbf4bd 100644 --- a/mayan/apps/documents/views/document_type_views.py +++ b/mayan/apps/documents/views/document_type_views.py @@ -26,50 +26,16 @@ from ..permissions import ( from .document_views import DocumentListView +__all__ = ( + 'DocumentTypeCreateView', 'DocumentTypeDeleteView', + 'DocumentTypeDocumentListView', 'DocumentTypeEditView', + 'DocumentTypeListView', 'DocumentTypeFilenameCreateView', + 'DocumentTypeFilenameDeleteView', 'DocumentTypeFilenameEditView', + 'DocumentTypeFilenameListView' +) logger = logging.getLogger(__name__) -class DocumentTypeDocumentListView(DocumentListView): - def get_document_type(self): - return get_object_or_404(DocumentType, pk=self.kwargs['pk']) - - def get_document_queryset(self): - return self.get_document_type().documents.all() - - def get_extra_context(self): - context = super(DocumentTypeDocumentListView, self).get_extra_context() - context.update( - { - 'object': self.get_document_type(), - 'title': _('Documents of type: %s') % self.get_document_type() - } - ) - return context - - -class DocumentTypeListView(SingleObjectListView): - model = DocumentType - object_permission = permission_document_type_view - - def get_extra_context(self): - return { - 'hide_link': True, - 'no_results_icon': icon_document_type_setup, - 'no_results_main_link': link_document_type_create.resolve( - context=RequestContext(request=self.request) - ), - 'no_results_text': _( - 'Document types are the most basic units of configuration. ' - 'Everything in the system will depend on them. ' - 'Define a document type for each type of physical ' - 'document you intend to upload. Example document types: ' - 'invoice, receipt, manual, prescription, balance sheet.' - ), - 'no_results_title': _('No document types available'), - 'title': _('Document types'), - } - - class DocumentTypeCreateView(SingleObjectCreateView): fields = ( 'label', 'trash_time_period', 'trash_time_unit', 'delete_time_period', @@ -103,6 +69,24 @@ class DocumentTypeDeleteView(SingleObjectDeleteView): } +class DocumentTypeDocumentListView(DocumentListView): + def get_document_type(self): + return get_object_or_404(DocumentType, pk=self.kwargs['pk']) + + def get_document_queryset(self): + return self.get_document_type().documents.all() + + def get_extra_context(self): + context = super(DocumentTypeDocumentListView, self).get_extra_context() + context.update( + { + 'object': self.get_document_type(), + 'title': _('Documents of type: %s') % self.get_document_type() + } + ) + return context + + class DocumentTypeEditView(SingleObjectEditView): fields = ( 'label', 'trash_time_period', 'trash_time_unit', 'delete_time_period', @@ -124,6 +108,29 @@ class DocumentTypeEditView(SingleObjectEditView): } +class DocumentTypeListView(SingleObjectListView): + model = DocumentType + object_permission = permission_document_type_view + + def get_extra_context(self): + return { + 'hide_link': True, + 'no_results_icon': icon_document_type_setup, + 'no_results_main_link': link_document_type_create.resolve( + context=RequestContext(request=self.request) + ), + 'no_results_text': _( + 'Document types are the most basic units of configuration. ' + 'Everything in the system will depend on them. ' + 'Define a document type for each type of physical ' + 'document you intend to upload. Example document types: ' + 'invoice, receipt, manual, prescription, balance sheet.' + ), + 'no_results_title': _('No document types available'), + 'title': _('Document types'), + } + + class DocumentTypeFilenameCreateView(SingleObjectCreateView): form_class = DocumentTypeFilenameForm_create @@ -153,6 +160,31 @@ class DocumentTypeFilenameCreateView(SingleObjectCreateView): return {'document_type': self.get_document_type()} +class DocumentTypeFilenameDeleteView(SingleObjectDeleteView): + model = DocumentTypeFilename + object_permission = permission_document_type_edit + + def get_extra_context(self): + return { + 'document_type': self.get_object().document_type, + 'filename': self.get_object(), + 'navigation_object_list': ('document_type', 'filename',), + 'title': _( + 'Delete the quick label: %(label)s, from document type ' + '"%(document_type)s"?' + ) % { + 'document_type': self.get_object().document_type, + 'label': self.get_object() + }, + } + + def get_post_action_redirect(self): + return reverse( + 'documents:document_type_filename_list', + args=(self.get_object().document_type.pk,) + ) + + class DocumentTypeFilenameEditView(SingleObjectEditView): fields = ('enabled', 'filename',) model = DocumentTypeFilename @@ -181,31 +213,6 @@ class DocumentTypeFilenameEditView(SingleObjectEditView): ) -class DocumentTypeFilenameDeleteView(SingleObjectDeleteView): - model = DocumentTypeFilename - object_permission = permission_document_type_edit - - def get_extra_context(self): - return { - 'document_type': self.get_object().document_type, - 'filename': self.get_object(), - 'navigation_object_list': ('document_type', 'filename',), - 'title': _( - 'Delete the quick label: %(label)s, from document type ' - '"%(document_type)s"?' - ) % { - 'document_type': self.get_object().document_type, - 'label': self.get_object() - }, - } - - def get_post_action_redirect(self): - return reverse( - 'documents:document_type_filename_list', - args=(self.get_object().document_type.pk,) - ) - - class DocumentTypeFilenameListView(SingleObjectListView): access_object_retrieve_method = 'get_document_type' object_permission = permission_document_type_view diff --git a/mayan/apps/documents/views/misc_views.py b/mayan/apps/documents/views/misc_views.py index 482dd15e84..d5d1d22967 100644 --- a/mayan/apps/documents/views/misc_views.py +++ b/mayan/apps/documents/views/misc_views.py @@ -10,6 +10,8 @@ from mayan.apps.common.generics import ConfirmView from ..permissions import permission_document_tools from ..tasks import task_clear_image_cache, task_scan_duplicates_all + +__all__ = ('ClearImageCacheView', 'ScanDuplicatedDocuments') logger = logging.getLogger(__name__)