228 lines
6.5 KiB
Python
228 lines
6.5 KiB
Python
from __future__ import unicode_literals
|
|
|
|
from django.contrib import messages
|
|
from django.http import HttpResponseRedirect
|
|
from django.urls import reverse
|
|
from django.utils.decorators import classonlymethod
|
|
from django.utils.encoding import force_text
|
|
from django.utils.http import urlencode
|
|
from django.utils.translation import ugettext_lazy as _
|
|
|
|
from formtools.wizard.views import SessionWizardView
|
|
|
|
from common.mixins import ViewPermissionCheckMixin
|
|
from documents.forms import DocumentTypeSelectForm
|
|
from metadata.forms import DocumentMetadataFormSet
|
|
from tags.forms import TagMultipleSelectionForm
|
|
from tags.models import Tag
|
|
|
|
from .models import InteractiveSource
|
|
|
|
|
|
class WizardStep(object):
|
|
_registry = {}
|
|
|
|
@classmethod
|
|
def done(cls, wizard):
|
|
return {}
|
|
|
|
@classmethod
|
|
def get(cls, name):
|
|
return cls._registry[name]
|
|
|
|
@classmethod
|
|
def get_all(cls):
|
|
return sorted(
|
|
cls._registry.values(), key=lambda x: x.number
|
|
)
|
|
|
|
@classmethod
|
|
def get_choices(cls, attribute_name):
|
|
return sorted(
|
|
[
|
|
(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 register(cls, step):
|
|
cls._registry[step.name] = step
|
|
|
|
|
|
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}
|
|
|
|
|
|
class WizardStepMetadata(WizardStep):
|
|
form_class = DocumentMetadataFormSet
|
|
label = _('Enter document metadata')
|
|
name = 'metadata_entry'
|
|
number = 1
|
|
|
|
@classmethod
|
|
def condition(cls, wizard):
|
|
"""
|
|
Skip step if document type has no associated metadata
|
|
"""
|
|
cleaned_data = wizard.get_cleaned_data_for_step(WizardStepDocumentType.name) or {}
|
|
|
|
document_type = cleaned_data.get('document_type')
|
|
|
|
if document_type:
|
|
return document_type.metadata.exists()
|
|
|
|
@classmethod
|
|
def get_form_initial(cls, wizard):
|
|
initial = []
|
|
|
|
step_data = wizard.get_cleaned_data_for_step(WizardStepDocumentType.name)
|
|
if step_data:
|
|
document_type = step_data['document_type']
|
|
for document_type_metadata_type in document_type.metadata.all():
|
|
initial.append(
|
|
{
|
|
'document_type': document_type,
|
|
'metadata_type': document_type_metadata_type.metadata_type,
|
|
}
|
|
)
|
|
|
|
return initial
|
|
|
|
@classmethod
|
|
def done(cls, wizard):
|
|
result = {}
|
|
cleaned_data = wizard.get_cleaned_data_for_step(cls.name)
|
|
if cleaned_data:
|
|
for identifier, metadata in enumerate(wizard.get_cleaned_data_for_step(cls.name)):
|
|
if metadata.get('update'):
|
|
result['metadata%s_id' % identifier] = metadata['id']
|
|
result['metadata%s_value' % identifier] = metadata['value']
|
|
|
|
return result
|
|
|
|
|
|
class WizardStepTags(WizardStep):
|
|
form_class = TagMultipleSelectionForm
|
|
label = _('Select tags')
|
|
name = 'tag_selection'
|
|
number = 2
|
|
|
|
@classmethod
|
|
def condition(cls, wizard):
|
|
return Tag.objects.exists()
|
|
|
|
@classmethod
|
|
def get_form_kwargs(self, wizard):
|
|
return {
|
|
'help_text': _('Tags to be attached.'),
|
|
'user': wizard.request.user
|
|
}
|
|
|
|
@classmethod
|
|
def done(cls, wizard):
|
|
result = {}
|
|
cleaned_data = wizard.get_cleaned_data_for_step(cls.name)
|
|
if cleaned_data:
|
|
result['tags'] = [
|
|
force_text(tag.pk) for tag in cleaned_data['tags']
|
|
]
|
|
|
|
return result
|
|
|
|
|
|
WizardStep.register(WizardStepDocumentType)
|
|
WizardStep.register(WizardStepMetadata)
|
|
WizardStep.register(WizardStepTags)
|
|
|
|
|
|
class DocumentCreateWizard(ViewPermissionCheckMixin, 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):
|
|
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': 'fa fa-arrow-right',
|
|
'title': _('Document upload wizard'),
|
|
})
|
|
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 = '?'.join(
|
|
[
|
|
reverse('sources:upload_interactive'),
|
|
urlencode(query_dict, doseq=True)
|
|
]
|
|
)
|
|
return HttpResponseRedirect(url)
|