Instead of inserting the path of the apps into the Python app, the apps are now referenced by their full import path. This solves name clashes with external or native Python libraries. Example: Mayan statistics app vs. Python new statistics library. Every app reference is now prepended with 'mayan.apps'. Existing config.yml files need to be updated manually. Signed-off-by: Roberto Rosario <roberto.rosario.gonzalez@gmail.com>
195 lines
5.7 KiB
Python
195 lines
5.7 KiB
Python
from __future__ import unicode_literals
|
|
|
|
from furl import furl
|
|
|
|
from django.apps import apps
|
|
from django.contrib import messages
|
|
from django.http import HttpResponseRedirect
|
|
from django.urls import reverse
|
|
from django.utils.decorators import classonlymethod
|
|
from django.utils.translation import ugettext_lazy as _
|
|
|
|
from formtools.wizard.views import SessionWizardView
|
|
|
|
from mayan.apps.documents.forms import DocumentTypeSelectForm
|
|
|
|
from .icons import icon_wizard_submit
|
|
|
|
|
|
class WizardStep(object):
|
|
_registry = {}
|
|
_deregistry = {}
|
|
|
|
@classmethod
|
|
def deregister(cls, step):
|
|
cls._deregistry[step.name] = step
|
|
|
|
@classmethod
|
|
def deregister_all(cls):
|
|
for step in cls.get_all():
|
|
cls.deregister(step=step)
|
|
|
|
@classmethod
|
|
def done(cls, wizard):
|
|
return {}
|
|
|
|
@classmethod
|
|
def get(cls, name):
|
|
for step in cls.get_all():
|
|
if name == step.name:
|
|
return step
|
|
|
|
@classmethod
|
|
def get_all(cls):
|
|
return sorted(
|
|
[
|
|
step for step in cls._registry.values() if step.name not in cls._deregistry
|
|
], key=lambda x: x.number
|
|
)
|
|
|
|
@classmethod
|
|
def get_choices(cls, attribute_name):
|
|
return [
|
|
(step.name, getattr(step, attribute_name)) for step in cls.get_all()
|
|
]
|
|
|
|
@classmethod
|
|
def get_form_initial(cls, wizard):
|
|
return {}
|
|
|
|
@classmethod
|
|
def get_form_kwargs(cls, wizard):
|
|
return {}
|
|
|
|
@classmethod
|
|
def post_upload_process(cls, document, querystring=None):
|
|
for step in cls.get_all():
|
|
step.step_post_upload_process(
|
|
document=document, querystring=querystring
|
|
)
|
|
|
|
@classmethod
|
|
def register(cls, step):
|
|
if step.name in cls._registry:
|
|
raise Exception('A step with this name already exists: %s' % step.name)
|
|
|
|
if step.number in [reigstered_step.number for reigstered_step in cls.get_all()]:
|
|
raise Exception('A step with this number already exists: %s' % step.name)
|
|
|
|
cls._registry[step.name] = step
|
|
|
|
@classmethod
|
|
def reregister(cls, name):
|
|
cls._deregistry.pop(name)
|
|
|
|
@classmethod
|
|
def reregister_all(cls):
|
|
cls._deregistry = {}
|
|
|
|
@classmethod
|
|
def step_post_upload_process(cls, document, querystring=None):
|
|
pass
|
|
|
|
|
|
class WizardStepDocumentType(WizardStep):
|
|
form_class = DocumentTypeSelectForm
|
|
label = _('Select document type')
|
|
name = 'document_type_selection'
|
|
number = 0
|
|
|
|
@classmethod
|
|
def condition(cls, wizard):
|
|
return True
|
|
|
|
@classmethod
|
|
def done(cls, wizard):
|
|
cleaned_data = wizard.get_cleaned_data_for_step(cls.name)
|
|
if cleaned_data:
|
|
return {
|
|
'document_type_id': cleaned_data['document_type'].pk
|
|
}
|
|
|
|
@classmethod
|
|
def get_form_kwargs(cls, wizard):
|
|
return {'user': wizard.request.user}
|
|
|
|
|
|
WizardStep.register(WizardStepDocumentType)
|
|
|
|
|
|
class DocumentCreateWizard(SessionWizardView):
|
|
template_name = 'appearance/generic_wizard.html'
|
|
|
|
@classonlymethod
|
|
def as_view(cls, *args, **kwargs):
|
|
cls.form_list = WizardStep.get_choices(attribute_name='form_class')
|
|
cls.condition_dict = dict(WizardStep.get_choices(attribute_name='condition'))
|
|
return super(DocumentCreateWizard, cls).as_view(*args, **kwargs)
|
|
|
|
def dispatch(self, request, *args, **kwargs):
|
|
InteractiveSource = apps.get_model(
|
|
app_label='sources', model_name='InteractiveSource'
|
|
)
|
|
|
|
form_list = WizardStep.get_choices(attribute_name='form_class')
|
|
condition_dict = dict(WizardStep.get_choices(attribute_name='condition'))
|
|
|
|
result = self.__class__.get_initkwargs(form_list=form_list, condition_dict=condition_dict)
|
|
self.form_list = result['form_list']
|
|
self.condition_dict = result['condition_dict']
|
|
|
|
if not InteractiveSource.objects.filter(enabled=True).exists():
|
|
messages.error(
|
|
request,
|
|
_(
|
|
'No interactive document sources have been defined or '
|
|
'none have been enabled, create one before proceeding.'
|
|
)
|
|
)
|
|
return HttpResponseRedirect(reverse('sources:setup_source_list'))
|
|
|
|
return super(
|
|
DocumentCreateWizard, self
|
|
).dispatch(request, *args, **kwargs)
|
|
|
|
def get_context_data(self, form, **kwargs):
|
|
context = super(
|
|
DocumentCreateWizard, self
|
|
).get_context_data(form=form, **kwargs)
|
|
|
|
wizard_step = WizardStep.get(name=self.steps.current)
|
|
|
|
context.update({
|
|
'step_title': _(
|
|
'Step %(step)d of %(total_steps)d: %(step_label)s'
|
|
) % {
|
|
'step': self.steps.step1, 'total_steps': len(self.form_list),
|
|
'step_label': wizard_step.label,
|
|
},
|
|
'submit_label': _('Next step'),
|
|
'submit_icon_class': icon_wizard_submit,
|
|
'title': _('Document upload wizard'),
|
|
'wizard_step': wizard_step,
|
|
'wizard_steps': WizardStep.get_all(),
|
|
})
|
|
return context
|
|
|
|
def get_form_initial(self, step):
|
|
return WizardStep.get(name=step).get_form_initial(wizard=self) or {}
|
|
|
|
def get_form_kwargs(self, step):
|
|
return WizardStep.get(name=step).get_form_kwargs(wizard=self) or {}
|
|
|
|
def done(self, form_list, **kwargs):
|
|
query_dict = {}
|
|
|
|
for step in WizardStep.get_all():
|
|
query_dict.update(step.done(wizard=self) or {})
|
|
|
|
url = furl(reverse('sources:upload_interactive'))
|
|
# Use equal and not .update() to get the same result as using
|
|
# urlencode(doseq=True)
|
|
url.args = query_dict
|
|
|
|
return HttpResponseRedirect(url)
|