Example #1
0
 def __init__(self, *args, **kwargs):
     super(SmartLinkConditionForm, self).__init__(*args, **kwargs)
     self.fields['foreign_document_data'] = forms.ChoiceField(
         choices=ModelAttribute.get_choices_for(
             Document, type_names=['field', 'query']),
         label=_('Foreign document attribute'))
     self.fields['expression'].help_text = ' '.join([
         self.fields['expression'].help_text,
         ModelAttribute.help_text_for(
             Document, type_names=['field', 'related', 'property'])
     ])
Example #2
0
 def __init__(self, *args, **kwargs):
     super(SmartLinkConditionForm, self).__init__(*args, **kwargs)
     self.fields['foreign_document_data'] = forms.ChoiceField(
         choices=ModelAttribute.get_choices_for(
             Document, type_names=['field', 'query']
         ), label=_('Foreign document attribute')
     )
     self.fields['expression'].help_text = ' '.join(
         [
             force_text(self.fields['expression'].help_text),
             ModelAttribute.help_text_for(
                 Document, type_names=['field', 'related', 'property']
             ).replace('\n', '<br>')
         ]
     )
Example #3
0
 def __init__(self, *args, **kwargs):
     super(SmartLinkForm, self).__init__(*args, **kwargs)
     self.fields['dynamic_title'].help_text = ' '.join([
         self.fields['dynamic_title'].help_text,
         ModelAttribute.help_text_for(
             Document, type_names=['field', 'related', 'property'])
     ])
Example #4
0
 def __init__(self, *args, **kwargs):
     super(IndexTemplateNodeForm, self).__init__(*args, **kwargs)
     self.fields['index'].widget = forms.widgets.HiddenInput()
     self.fields['parent'].widget = forms.widgets.HiddenInput()
     self.fields['expression'].help_text = ' '.join([
         unicode(self.fields['expression'].help_text),
         ModelAttribute.help_text_for(Document, type_names=['indexing'])
     ])
Example #5
0
 def __init__(self, *args, **kwargs):
     super(SmartLinkForm, self).__init__(*args, **kwargs)
     self.fields['dynamic_label'].help_text = ' '.join([
         force_text(self.fields['dynamic_label'].help_text),
         ModelAttribute.help_text_for(
             Document, type_names=['field', 'related',
                                   'property']).replace('\n', '<br>')
     ])
Example #6
0
 def __init__(self, *args, **kwargs):
     super(IndexTemplateNodeForm, self).__init__(*args, **kwargs)
     self.fields['index'].widget = forms.widgets.HiddenInput()
     self.fields['parent'].widget = forms.widgets.HiddenInput()
     self.fields['expression'].help_text = ' '.join(
         [
             unicode(self.fields['expression'].help_text),
             ModelAttribute.help_text_for(Document, type_names=['indexing'])
         ]
     )
Example #7
0
 def __init__(self, *args, **kwargs):
     super(SmartLinkForm, self).__init__(*args, **kwargs)
     self.fields['dynamic_label'].help_text = ' '.join(
         [
             force_text(self.fields['dynamic_label'].help_text),
             ModelAttribute.help_text_for(
                 Document, type_names=['field', 'related', 'property']
             ).replace('\n', '<br>')
         ]
     )
Example #8
0
    def ready(self):
        super(MetadataApp, self).ready()

        from .wizard_steps import WizardStepMetadata  # NOQA

        Document = apps.get_model(app_label='documents', model_name='Document')
        DocumentPageResult = apps.get_model(app_label='documents',
                                            model_name='DocumentPageResult')

        DocumentType = apps.get_model(app_label='documents',
                                      model_name='DocumentType')

        DocumentMetadata = self.get_model('DocumentMetadata')
        DocumentTypeMetadataType = self.get_model('DocumentTypeMetadataType')
        MetadataType = self.get_model('MetadataType')

        Document.add_to_class('metadata_value_of',
                              DocumentMetadataHelper.constructor)

        ModelAttribute(
            Document,
            'metadata',
            type_name='related',
            description=_(
                'Queryset containing a MetadataType instance reference and a '
                'value for that metadata type'))
        ModelAttribute(Document,
                       'metadata__metadata_type__name',
                       label=_('Metadata type name'),
                       type_name='query')
        ModelAttribute(Document,
                       'metadata__value',
                       label=_('Metadata type value'),
                       type_name='query')
        ModelAttribute(
            Document,
            'metadata_value_of',
            label=_('Value of a metadata'),
            description=_('Return the value of a specific document metadata'),
            type_name=['property', 'indexing'])

        ModelPermission.register(model=Document,
                                 permissions=(
                                     permission_metadata_document_add,
                                     permission_metadata_document_edit,
                                     permission_metadata_document_remove,
                                     permission_metadata_document_view,
                                 ))
        ModelPermission.register(model=MetadataType,
                                 permissions=(permission_metadata_type_delete,
                                              permission_metadata_type_edit,
                                              permission_metadata_type_view))

        SourceColumn(
            source=Document,
            label=_('Metadata'),
            func=lambda context: get_metadata_string(context['object']))

        SourceColumn(source=DocumentPageResult,
                     label=_('Metadata'),
                     func=lambda context: get_metadata_string(context['object']
                                                              .document))

        SourceColumn(source=DocumentMetadata,
                     label=_('Value'),
                     attribute='value')
        SourceColumn(source=DocumentMetadata,
                     label=_('Required'),
                     func=lambda context: two_state_template(context['object'].
                                                             is_required))

        app.conf.CELERY_QUEUES.append(
            Queue('metadata', Exchange('metadata'), routing_key='metadata'), )

        app.conf.CELERY_ROUTES.update({
            'metadata.tasks.task_remove_metadata_type': {
                'queue': 'metadata'
            },
            'metadata.tasks.task_add_required_metadata_type': {
                'queue': 'metadata'
            },
        })

        document_search.add_model_field(field='metadata__metadata_type__name',
                                        label=_('Metadata type'))
        document_search.add_model_field(field='metadata__value',
                                        label=_('Metadata value'))

        document_page_search.add_model_field(
            field='document_version__document__metadata__metadata_type__name',
            label=_('Metadata type'))
        document_page_search.add_model_field(
            field='document_version__document__metadata__value',
            label=_('Metadata value'))

        menu_facet.bind_links(links=(link_metadata_view, ),
                              sources=(Document, ))
        menu_multi_item.bind_links(links=(link_metadata_multiple_add,
                                          link_metadata_multiple_edit,
                                          link_metadata_multiple_remove),
                                   sources=(Document, ))
        menu_object.bind_links(
            links=(link_setup_document_type_metadata_types, ),
            sources=(DocumentType, ))
        menu_object.bind_links(links=(link_setup_metadata_type_edit,
                                      link_setup_metadata_type_document_types,
                                      link_setup_metadata_type_delete),
                               sources=(MetadataType, ))
        menu_secondary.bind_links(
            links=(link_setup_metadata_type_list,
                   link_setup_metadata_type_create),
            sources=(MetadataType, 'metadata:setup_metadata_type_list',
                     'metadata:setup_metadata_type_create'))
        menu_setup.bind_links(links=(link_setup_metadata_type_list, ))
        menu_sidebar.bind_links(
            links=(link_metadata_add, link_metadata_edit,
                   link_metadata_remove),
            sources=('metadata:metadata_add', 'metadata:metadata_edit',
                     'metadata:metadata_remove', 'metadata:metadata_view'))

        post_delete.connect(
            post_document_type_metadata_type_delete,
            dispatch_uid='metadata_post_document_type_metadata_type_delete',
            sender=DocumentTypeMetadataType)
        post_document_type_change.connect(
            post_document_type_change_metadata,
            dispatch_uid='metadata_post_document_type_change_metadata',
            sender=Document)
        post_save.connect(
            post_document_type_metadata_type_add,
            dispatch_uid='metadata_post_document_type_metadata_type_add',
            sender=DocumentTypeMetadataType)

        # Index updating

        post_delete.connect(
            handler_index_document,
            dispatch_uid='metadata_handler_index_document_delete',
            sender=DocumentMetadata)
        post_save.connect(handler_index_document,
                          dispatch_uid='metadata_handler_index_document_save',
                          sender=DocumentMetadata)
Example #9
0
    PERMISSION_COMMENT_CREATE, PERMISSION_COMMENT_DELETE,
    PERMISSION_COMMENT_VIEW
])

register_model_list_columns(Comment, [{
    'name': _('Date'),
    'attribute': 'submit_date'
}, {
    'name':
    _('User'),
    'attribute':
    encapsulate(lambda x: x.user.get_full_name()
                if x.user.get_full_name() else x.user)
}, {
    'name': _('Comment'),
    'attribute': 'comment'
}])

register_links([
    'comments:comments_for_document', 'comments:comment_add',
    'comments:comment_delete', 'comments:comment_multiple_delete'
], [comment_add],
               menu_name='sidebar')
register_links(Comment, [comment_delete])
register_links(Document, [comments_for_document], menu_name='form_header')

ModelAttribute(Document,
               label=_('Comments'),
               name='comments',
               type_name='related')
Example #10
0
    PERMISSION_METADATA_DOCUMENT_ADD,
    PERMISSION_METADATA_DOCUMENT_EDIT,
    PERMISSION_METADATA_DOCUMENT_REMOVE,
    PERMISSION_METADATA_DOCUMENT_VIEW,
])

register_model_list_columns(Document, [
    {
        'name': _('Metadata'),
        'attribute': encapsulate(lambda x: get_metadata_string(x))
    },
])

APIEndPoint('metadata')
ModelAttribute(Document,
               'metadata__metadata_type__name',
               label=_('Metadata type name'),
               type_name='query')
ModelAttribute(Document,
               'metadata__value',
               label=_('Metadata type value'),
               type_name='query')
ModelAttribute(
    Document,
    'metadata',
    type_name='related',
    description=
    _('Queryset containing a MetadataType instance reference and a value for that metadata type'
      ))
ModelAttribute(
    Document,
    'metadata_value_of',
Example #11
0
    def ready(self):
        super(MetadataApp, self).ready()

        Document = apps.get_model(app_label='documents', model_name='Document')
        DocumentPageResult = apps.get_model(app_label='documents',
                                            model_name='DocumentPageResult')

        DocumentType = apps.get_model(app_label='documents',
                                      model_name='DocumentType')

        DocumentMetadata = self.get_model('DocumentMetadata')
        DocumentTypeMetadataType = self.get_model('DocumentTypeMetadataType')
        MetadataType = self.get_model('MetadataType')

        APIEndPoint(app=self, version_string='2')

        Document.add_to_class('metadata_value_of',
                              DocumentMetadataHelper.constructor)

        Filter(label=_('Documents missing required metadata'),
               slug='documents-no-required-metadata',
               filter_kwargs=[{
                   'document_type__metadata__required': True,
               }, {
                   'metadata__value__isnull': True
               }, {
                   'is_stub': False
               }],
               model=Document,
               object_permission=permission_document_view,
               hide_links=True)

        Filter(label=_('Documents missing optional metadata'),
               slug='documents-no-optional-metadata',
               filter_kwargs=[{
                   'document_type__metadata__required': False,
               }, {
                   'metadata__value__isnull': True
               }, {
                   'is_stub': False
               }],
               model=Document,
               object_permission=permission_document_view,
               hide_links=True)

        ModelAttribute(
            Document,
            'metadata',
            type_name='related',
            description=_(
                'Queryset containing a MetadataType instance reference and a '
                'value for that metadata type'))
        ModelAttribute(Document,
                       'metadata__metadata_type__name',
                       label=_('Metadata type name'),
                       type_name='query')
        ModelAttribute(Document,
                       'metadata__value',
                       label=_('Metadata type value'),
                       type_name='query')
        ModelAttribute(
            Document,
            'metadata_value_of',
            label=_('Value of a metadata'),
            description=_('Return the value of a specific document metadata'),
            type_name=['property', 'indexing'])

        ModelPermission.register(model=Document,
                                 permissions=(
                                     permission_metadata_document_add,
                                     permission_metadata_document_edit,
                                     permission_metadata_document_remove,
                                     permission_metadata_document_view,
                                 ))

        SourceColumn(
            source=Document,
            label=_('Metadata'),
            func=lambda context: get_metadata_string(context['object']))

        SourceColumn(source=DocumentPageResult,
                     label=_('Metadata'),
                     func=lambda context: get_metadata_string(context['object']
                                                              .document))

        SourceColumn(source=DocumentMetadata,
                     label=_('Value'),
                     attribute='value')
        SourceColumn(source=DocumentMetadata,
                     label=_('Required'),
                     func=lambda context: two_state_template(context['object'].
                                                             is_required))

        app.conf.CELERY_QUEUES.append(
            Queue('metadata', Exchange('metadata'), routing_key='metadata'), )

        app.conf.CELERY_ROUTES.update({
            'metadata.tasks.task_remove_metadata_type': {
                'queue': 'metadata'
            },
            'metadata.tasks.task_add_required_metadata_type': {
                'queue': 'metadata'
            },
        })

        document_search.add_model_field(field='metadata__metadata_type__name',
                                        label=_('Metadata type'))
        document_search.add_model_field(field='metadata__value',
                                        label=_('Metadata value'))

        document_page_search.add_model_field(
            field='document_version__document__metadata__metadata_type__name',
            label=_('Metadata type'))
        document_page_search.add_model_field(
            field='document_version__document__metadata__value',
            label=_('Metadata value'))

        menu_facet.bind_links(links=(link_metadata_view, ),
                              sources=(Document, ))
        menu_multi_item.bind_links(links=(link_metadata_multiple_add,
                                          link_metadata_multiple_edit,
                                          link_metadata_multiple_remove),
                                   sources=(Document, ))
        menu_object.bind_links(
            links=(link_setup_document_type_metadata,
                   link_setup_document_type_metadata_required),
            sources=(DocumentType, ))
        menu_object.bind_links(links=(link_setup_metadata_type_edit,
                                      link_setup_metadata_type_delete),
                               sources=(MetadataType, ))
        menu_secondary.bind_links(
            links=(link_setup_metadata_type_list,
                   link_setup_metadata_type_create),
            sources=(MetadataType, 'metadata:setup_metadata_type_list',
                     'metadata:setup_metadata_type_create'))
        menu_setup.bind_links(links=(link_setup_metadata_type_list, ))
        menu_sidebar.bind_links(
            links=(link_metadata_add, link_metadata_edit,
                   link_metadata_remove),
            sources=('metadata:metadata_add', 'metadata:metadata_edit',
                     'metadata:metadata_remove', 'metadata:metadata_view'))

        post_delete.connect(
            post_document_type_metadata_type_delete,
            dispatch_uid='post_document_type_metadata_type_delete',
            sender=DocumentTypeMetadataType)
        post_document_type_change.connect(
            post_post_document_type_change_metadata,
            dispatch_uid='post_post_document_type_change_metadata',
            sender=Document)
        post_save.connect(post_document_type_metadata_type_add,
                          dispatch_uid='post_document_type_metadata_type_add',
                          sender=DocumentTypeMetadataType)
Example #12
0
    ACLS_EDIT_ACL, ACLS_VIEW_ACL, PERMISSION_DOCUMENT_DELETE,
    PERMISSION_DOCUMENT_DOWNLOAD, PERMISSION_DOCUMENT_EDIT,
    PERMISSION_DOCUMENT_NEW_VERSION, PERMISSION_DOCUMENT_PROPERTIES_EDIT,
    PERMISSION_DOCUMENT_TRANSFORM, PERMISSION_DOCUMENT_VERSION_REVERT,
    PERMISSION_DOCUMENT_VIEW, PERMISSION_EVENTS_VIEW
])

document_search = SearchModel('documents', 'Document', permission=PERMISSION_DOCUMENT_VIEW, serializer_string='documents.serializers.DocumentSerializer')

# TODO: move these to their respective apps
# Moving these to other apps cause an ImportError; circular import?
document_search.add_model_field('document_type__name', label=_('Document type'))
document_search.add_model_field('versions__mimetype', label=_('MIME type'))
document_search.add_model_field('label', label=_('Label'))
document_search.add_model_field('metadata__metadata_type__name', label=_('Metadata type'))
document_search.add_model_field('metadata__value', label=_('Metadata value'))
document_search.add_model_field('versions__pages__content', label=_('Content'))
document_search.add_model_field('description', label=_('Description'))
document_search.add_model_field('tags__label', label=_('Tags'))

namespace = StatisticNamespace(name='documents', label=_('Documents'))
namespace.add_statistic(DocumentStatistics(name='document_stats', label=_('Document tendencies')))
namespace.add_statistic(DocumentUsageStatistics(name='document_usage', label=_('Document usage')))

APIEndPoint('documents')

ModelAttribute(Document, label=_('Label'), name='label', type_name='field')

FrontPageButton(link=document_list_recent)
FrontPageButton(link=document_list)
Example #13
0
    def ready(self):
        super(DocumentStatesApp, self).ready()

        APIEndPoint(app=self, version_string='1')

        Document = apps.get_model(
            app_label='documents', model_name='Document'
        )

        Document.add_to_class(
            'workflow', DocumentStateHelper.constructor
        )

        Workflow = self.get_model('Workflow')
        WorkflowInstance = self.get_model('WorkflowInstance')
        WorkflowInstanceLogEntry = self.get_model('WorkflowInstanceLogEntry')
        WorkflowRuntimeProxy = self.get_model('WorkflowRuntimeProxy')
        WorkflowState = self.get_model('WorkflowState')
        WorkflowStateRuntimeProxy = self.get_model('WorkflowStateRuntimeProxy')
        WorkflowTransition = self.get_model('WorkflowTransition')

        ModelAttribute(
            Document, 'workflow.< workflow internal name >.get_current_state',
            label=_('Current state of a workflow'), description=_(
                'Return the current state of the selected workflow'
            ), type_name=['property', 'indexing']
        )
        ModelAttribute(
            Document,
            'workflow.< workflow internal name >.get_current_state.completion',
            label=_('Current state of a workflow'), description=_(
                'Return the completion value of the current state of the '
                'selected workflow'
            ), type_name=['property', 'indexing']
        )

        ModelPermission.register(
            model=Workflow, permissions=(permission_workflow_transition,)
        )

        ModelPermission.register(
            model=WorkflowTransition,
            permissions=(permission_workflow_transition,)
        )

        SourceColumn(
            source=Workflow, label=_('Label'), attribute='label'
        )
        SourceColumn(
            source=Workflow, label=_('Internal name'),
            attribute='internal_name'
        )
        SourceColumn(
            source=Workflow, label=_('Initial state'),
            func=lambda context: context['object'].get_initial_state() or _('None')
        )

        SourceColumn(
            source=WorkflowInstance, label=_('Current state'),
            attribute='get_current_state'
        )
        SourceColumn(
            source=WorkflowInstance, label=_('User'),
            func=lambda context: getattr(
                context['object'].get_last_log_entry(), 'user', _('None')
            )
        )
        SourceColumn(
            source=WorkflowInstance, label=_('Last transition'),
            attribute='get_last_transition'
        )
        SourceColumn(
            source=WorkflowInstance, label=_('Date and time'),
            func=lambda context: getattr(
                context['object'].get_last_log_entry(), 'datetime', _('None')
            )
        )
        SourceColumn(
            source=WorkflowInstance, label=_('Completion'),
            func=lambda context: getattr(
                context['object'].get_current_state(), 'completion', _('None')
            )
        )

        SourceColumn(
            source=WorkflowInstanceLogEntry, label=_('Date and time'),
            attribute='datetime'
        )
        SourceColumn(
            source=WorkflowInstanceLogEntry, label=_('User'), attribute='user'
        )
        SourceColumn(
            source=WorkflowInstanceLogEntry, label=_('Transition'),
            attribute='transition'
        )
        SourceColumn(
            source=WorkflowInstanceLogEntry, label=_('Comment'),
            attribute='comment'
        )

        SourceColumn(
            source=WorkflowState, label=_('Is initial state?'),
            func=lambda context: two_state_template(context['object'].initial)
        )
        SourceColumn(
            source=WorkflowState, label=_('Completion'), attribute='completion'
        )

        SourceColumn(
            source=WorkflowTransition, label=_('Origin state'),
            attribute='origin_state'
        )
        SourceColumn(
            source=WorkflowTransition, label=_('Destination state'),
            attribute='destination_state'
        )

        app.conf.CELERY_QUEUES.extend(
            (
                Queue(
                    'document_states', Exchange('document_states'),
                    routing_key='document_states'
                ),
            )
        )

        app.conf.CELERY_ROUTES.update(
            {
                'document_states.tasks.task_launch_all_workflows': {
                    'queue': 'document_states'
                },
            }
        )

        menu_facet.bind_links(
            links=(link_document_workflow_instance_list,), sources=(Document,)
        )
        menu_main.bind_links(links=(link_workflow_list,), position=10)
        menu_object.bind_links(
            links=(
                link_setup_workflow_states, link_setup_workflow_transitions,
                link_setup_workflow_document_types, link_setup_workflow_edit,
                link_acl_list, link_setup_workflow_delete
            ), sources=(Workflow,)
        )
        menu_object.bind_links(
            links=(
                link_setup_workflow_state_edit,
                link_setup_workflow_state_delete
            ), sources=(WorkflowState,)
        )
        menu_object.bind_links(
            links=(
                link_setup_workflow_transition_edit, link_acl_list,
                link_setup_workflow_transition_delete
            ), sources=(WorkflowTransition,)
        )
        menu_object.bind_links(
            links=(
                link_workflow_instance_detail,
                link_workflow_instance_transition
            ), sources=(WorkflowInstance,)
        )
        menu_object.bind_links(
            links=(
                link_workflow_document_list, link_workflow_state_list,
            ), sources=(WorkflowRuntimeProxy,)
        )
        menu_object.bind_links(
            links=(
                link_workflow_state_document_list,
            ), sources=(WorkflowStateRuntimeProxy,)
        )
        menu_secondary.bind_links(
            links=(link_setup_workflow_list, link_setup_workflow_create),
            sources=(
                Workflow, 'document_states:setup_workflow_create',
                'document_states:setup_workflow_list'
            )
        )
        menu_secondary.bind_links(
            links=(link_workflow_list,),
            sources=(
                WorkflowRuntimeProxy,
            )
        )
        menu_setup.bind_links(links=(link_setup_workflow_list,))
        menu_sidebar.bind_links(
            links=(
                link_setup_workflow_state_create,
                link_setup_workflow_transition_create
            ), sources=(Workflow,)
        )
        menu_tools.bind_links(links=(link_tool_launch_all_workflows,))

        post_save.connect(
            launch_workflow, dispatch_uid='launch_workflow', sender=Document
        )

        # Index updating

        post_save.connect(
            handler_index_document,
            dispatch_uid='handler_index_document_save',
            sender=WorkflowInstanceLogEntry
        )
Example #14
0
 def __init__(self, *args, **kwargs):
     super(SmartLinkForm, self).__init__(*args, **kwargs)
     self.fields['dynamic_title'].help_text = ' '.join([self.fields['dynamic_title'].help_text, ModelAttribute.help_text_for(Document, type_names=['field', 'related', 'property'])])
Example #15
0
    def ready(self):
        super(DocumentStatesApp, self).ready()

        Action = apps.get_model(app_label='actstream', model_name='Action')
        Document = apps.get_model(app_label='documents', model_name='Document')
        ErrorLogEntry = apps.get_model(app_label='common',
                                       model_name='ErrorLogEntry')

        Workflow = self.get_model('Workflow')
        WorkflowInstance = self.get_model('WorkflowInstance')
        WorkflowInstanceLogEntry = self.get_model('WorkflowInstanceLogEntry')
        WorkflowRuntimeProxy = self.get_model('WorkflowRuntimeProxy')
        WorkflowState = self.get_model('WorkflowState')
        WorkflowStateAction = self.get_model('WorkflowStateAction')
        WorkflowStateRuntimeProxy = self.get_model('WorkflowStateRuntimeProxy')
        WorkflowTransition = self.get_model('WorkflowTransition')
        WorkflowTransitionTriggerEvent = self.get_model(
            'WorkflowTransitionTriggerEvent')

        Document.add_to_class('workflow', DocumentStateHelper.constructor)

        ErrorLogEntry.objects.register(model=WorkflowStateAction)

        WorkflowAction.initialize()

        ModelAttribute(
            model=Document,
            name='workflow.< workflow internal name >.get_current_state',
            label=_('Current state of a workflow'),
            description=_('Return the current state of the selected workflow'))
        ModelAttribute(
            model=Document,
            name=
            'workflow.< workflow internal name >.get_current_state.completion',
            label=_('Current state of a workflow'),
            description=_(
                'Return the completion value of the current state of the '
                'selected workflow'))

        ModelPermission.register(model=Document,
                                 permissions=(permission_workflow_view, ))
        ModelPermission.register(model=Workflow,
                                 permissions=(
                                     permission_error_log_view,
                                     permission_workflow_delete,
                                     permission_workflow_edit,
                                     permission_workflow_transition,
                                     permission_workflow_view,
                                 ))

        ModelPermission.register_inheritance(
            model=WorkflowInstance,
            related='workflow',
        )
        ModelPermission.register_inheritance(
            model=WorkflowInstanceLogEntry,
            related='workflow_instance__workflow',
        )
        ModelPermission.register(
            model=WorkflowTransition,
            permissions=(permission_workflow_transition, ))

        ModelPermission.register_inheritance(
            model=WorkflowState,
            related='workflow',
        )
        ModelPermission.register_inheritance(
            model=WorkflowStateAction,
            related='state__workflow',
        )
        ModelPermission.register_inheritance(
            model=WorkflowTransition,
            related='workflow',
        )
        ModelPermission.register_inheritance(
            model=WorkflowTransitionTriggerEvent,
            related='transition__workflow',
        )

        SourceColumn(source=Workflow, label=_('Label'), attribute='label')
        SourceColumn(source=Workflow,
                     label=_('Internal name'),
                     attribute='internal_name')
        SourceColumn(source=Workflow,
                     label=_('Initial state'),
                     func=lambda context: context['object'].get_initial_state(
                     ) or _('None'))

        SourceColumn(source=WorkflowInstance,
                     label=_('Current state'),
                     attribute='get_current_state')
        SourceColumn(
            source=WorkflowInstance,
            label=_('User'),
            func=lambda context: getattr(
                context['object'].get_last_log_entry(), 'user', _('None')))
        SourceColumn(source=WorkflowInstance,
                     label=_('Last transition'),
                     attribute='get_last_transition')
        SourceColumn(
            source=WorkflowInstance,
            label=_('Date and time'),
            func=lambda context: getattr(
                context['object'].get_last_log_entry(), 'datetime', _('None')))
        SourceColumn(
            source=WorkflowInstance,
            label=_('Completion'),
            func=lambda context: getattr(context['object'].get_current_state(),
                                         'completion', _('None')))

        SourceColumn(source=WorkflowInstanceLogEntry,
                     label=_('Date and time'),
                     attribute='datetime')
        SourceColumn(source=WorkflowInstanceLogEntry,
                     label=_('User'),
                     attribute='user')
        SourceColumn(source=WorkflowInstanceLogEntry,
                     label=_('Transition'),
                     attribute='transition')
        SourceColumn(source=WorkflowInstanceLogEntry,
                     label=_('Comment'),
                     attribute='comment')

        SourceColumn(source=WorkflowState,
                     label=_('Is initial state?'),
                     func=lambda context: TwoStateWidget(state=context[
                         'object'].initial).render())
        SourceColumn(source=WorkflowState,
                     label=_('Completion'),
                     attribute='completion')

        SourceColumn(source=WorkflowStateAction,
                     label=_('Label'),
                     attribute='label')
        SourceColumn(source=WorkflowStateAction,
                     label=_('Enabled?'),
                     func=lambda context: TwoStateWidget(state=context[
                         'object'].enabled).render())
        SourceColumn(source=WorkflowStateAction,
                     label=_('When?'),
                     attribute='get_when_display')
        SourceColumn(source=WorkflowStateAction,
                     label=_('Action type'),
                     attribute='get_class_label')

        SourceColumn(source=WorkflowTransition,
                     label=_('Origin state'),
                     attribute='origin_state')
        SourceColumn(source=WorkflowTransition,
                     label=_('Destination state'),
                     attribute='destination_state')
        SourceColumn(source=WorkflowTransition,
                     label=_('Triggers'),
                     func=lambda context: widget_transition_events(
                         transition=context['object']))

        app.conf.CELERY_QUEUES.extend((Queue('document_states',
                                             Exchange('document_states'),
                                             routing_key='document_states'), ))

        app.conf.CELERY_ROUTES.update({
            'document_states.tasks.task_launch_all_workflows': {
                'queue': 'document_states'
            },
        })

        menu_facet.bind_links(links=(link_document_workflow_instance_list, ),
                              sources=(Document, ))
        menu_main.bind_links(links=(link_workflow_list, ), position=10)
        menu_object.bind_links(
            links=(link_setup_workflow_states, link_setup_workflow_transitions,
                   link_setup_workflow_document_types,
                   link_setup_workflow_edit, link_acl_list,
                   link_workflow_preview, link_setup_workflow_delete),
            sources=(Workflow, ))
        menu_object.bind_links(links=(link_setup_workflow_state_edit,
                                      link_setup_workflow_state_action_list,
                                      link_setup_workflow_state_delete),
                               sources=(WorkflowState, ))
        menu_object.bind_links(links=(link_setup_workflow_transition_edit,
                                      link_workflow_instance_transition_events,
                                      link_acl_list,
                                      link_setup_workflow_transition_delete),
                               sources=(WorkflowTransition, ))
        menu_object.bind_links(links=(link_workflow_instance_detail,
                                      link_workflow_instance_transition),
                               sources=(WorkflowInstance, ))
        menu_object.bind_links(links=(
            link_workflow_document_list,
            link_workflow_state_list,
        ),
                               sources=(WorkflowRuntimeProxy, ))
        menu_object.bind_links(links=(link_workflow_state_document_list, ),
                               sources=(WorkflowStateRuntimeProxy, ))
        menu_object.bind_links(links=(
            link_setup_workflow_state_action_edit,
            link_object_error_list,
            link_setup_workflow_state_action_delete,
        ),
                               sources=(WorkflowStateAction, ))

        menu_secondary.bind_links(
            links=(link_setup_workflow_list, link_setup_workflow_create),
            sources=(Workflow, 'document_states:setup_workflow_create',
                     'document_states:setup_workflow_list'))
        menu_secondary.bind_links(links=(link_workflow_list, ),
                                  sources=(WorkflowRuntimeProxy, ))
        menu_secondary.bind_links(
            links=(link_setup_workflow_state_action_selection, ),
            sources=(WorkflowState, ))
        menu_setup.bind_links(links=(link_setup_workflow_list, ))
        menu_sidebar.bind_links(links=(link_setup_workflow_state_create,
                                       link_setup_workflow_transition_create),
                                sources=(Workflow, ))
        menu_tools.bind_links(links=(link_tool_launch_all_workflows, ))

        post_save.connect(launch_workflow,
                          dispatch_uid='launch_workflow',
                          sender=Document)

        # Index updating

        post_save.connect(handler_index_document,
                          dispatch_uid='handler_index_document_save',
                          sender=WorkflowInstanceLogEntry)
        post_save.connect(
            handler_trigger_transition,
            dispatch_uid='document_states_handler_trigger_transition',
            sender=Action)
Example #16
0
    def ready(self):
        super(DocumentsApp, self).ready()

        APIEndPoint(app=self, version_string='1')

        DeletedDocument = self.get_model('DeletedDocument')
        Document = self.get_model('Document')
        DocumentPage = self.get_model('DocumentPage')
        DocumentType = self.get_model('DocumentType')
        DocumentTypeFilename = self.get_model('DocumentTypeFilename')
        DocumentVersion = self.get_model('DocumentVersion')

        MissingItem(
            label=_('Create a document type'),
            description=_(
                'Every uploaded document must be assigned a document type, '
                'it is the basic way Mayan EDMS categorizes documents.'
            ), condition=lambda: not DocumentType.objects.exists(),
            view='documents:document_type_list'
        )

        ModelAttribute(
            Document, label=_('Label'), name='label', type_name='field'
        )

        ModelAttribute(
            Document,
            description=_('The MIME type of any of the versions of a document'),
            label=_('MIME type'), name='versions__mimetype', type_name='field'
        )

        ModelPermission.register(
            model=Document, permissions=(
                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_view,
                permission_events_view, permission_transformation_create,
                permission_transformation_delete,
                permission_transformation_edit, permission_transformation_view,
            )
        )

        ModelPermission.register(
            model=DocumentType, permissions=(permission_document_create,)
        )

        ModelPermission.register_proxy(
            source=Document, model=DocumentType,
        )

        ModelPermission.register_inheritance(
            model=Document, related='document_type',
        )

        ModelPermission.register_inheritance(
            model=DocumentVersion, related='document',
        )

        ModelPermission.register_inheritance(
            model=DocumentPage, related='document',
        )

        SourceColumn(
            source=Document, label=_('Thumbnail'),
            func=lambda context: document_thumbnail(
                context['object'], gallery_name='documents:document_list',
                size=setting_thumbnail_size.value,
                title=getattr(context['object'], 'label', None),
            )
        )
        SourceColumn(
            source=Document, label=_('Type'), attribute='document_type'
        )

        SourceColumn(
            source=DocumentType, label=_('Documents'),
            func=lambda context: context['object'].get_document_count(
                user=context['request'].user
            )
        )

        SourceColumn(
            source=DocumentTypeFilename, label=_('Enabled'),
            func=lambda context: two_state_template(context['object'].enabled)
        )

        SourceColumn(
            source=DeletedDocument, label=_('Thumbnail'),
            func=lambda context: document_thumbnail(
                context['object'],
                gallery_name='documents:delete_document_list',
                size=setting_thumbnail_size.value,
                title=getattr(context['object'], 'label', None),
                disable_title_link=True
            )
        )
        SourceColumn(
            source=DeletedDocument, label=_('Type'), attribute='document_type'
        )
        SourceColumn(
            source=DeletedDocument, label=_('Date time trashed'),
            attribute='deleted_date_time'
        )

        SourceColumn(
            source=DocumentVersion, label=_('Time and date'),
            attribute='timestamp'
        )
        SourceColumn(
            source=DocumentVersion, label=_('MIME type'),
            attribute='mimetype'
        )
        SourceColumn(
            source=DocumentVersion, label=_('Encoding'),
            attribute='encoding'
        )
        SourceColumn(
            source=DocumentVersion, label=_('Comment'),
            attribute='comment'
        )

        app.conf.CELERYBEAT_SCHEDULE.update(
            {
                'task_check_delete_periods': {
                    'task': 'documents.tasks.task_check_delete_periods',
                    'schedule': timedelta(
                        seconds=CHECK_DELETE_PERIOD_INTERVAL
                    ),
                },
                'task_check_trash_periods': {
                    'task': 'documents.tasks.task_check_trash_periods',
                    'schedule': timedelta(seconds=CHECK_TRASH_PERIOD_INTERVAL),
                },
                'task_delete_stubs': {
                    'task': 'documents.tasks.task_delete_stubs',
                    'schedule': timedelta(seconds=DELETE_STALE_STUBS_INTERVAL),
                },
            }
        )

        app.conf.CELERY_QUEUES.extend(
            (
                Queue(
                    'converter', Exchange('converter'),
                    routing_key='converter', delivery_mode=1
                ),
                Queue(
                    'documents_periodic', Exchange('documents_periodic'),
                    routing_key='documents_periodic', delivery_mode=1
                ),
                Queue('uploads', Exchange('uploads'), routing_key='uploads'),
            )
        )

        app.conf.CELERY_ROUTES.update(
            {
                'documents.tasks.task_check_delete_periods': {
                    'queue': 'documents_periodic'
                },
                'documents.tasks.task_check_trash_periods': {
                    'queue': 'documents_periodic'
                },
                'documents.tasks.task_delete_stubs': {
                    'queue': 'documents_periodic'
                },
                'documents.tasks.task_clear_image_cache': {
                    'queue': 'tools'
                },
                'documents.tasks.task_get_document_page_image': {
                    'queue': 'converter'
                },
                'documents.tasks.task_update_page_count': {
                    'queue': 'uploads'
                },
                'documents.tasks.task_upload_new_version': {
                    'queue': 'uploads'
                },
            }
        )

        menu_front_page.bind_links(
            links=(
                link_document_list_recent, link_document_list,
                link_document_list_deleted
            )
        )
        menu_setup.bind_links(links=(link_document_type_setup,))
        menu_tools.bind_links(links=(link_clear_image_cache,))

        # Document type links
        menu_object.bind_links(
            links=(
                link_document_type_edit, link_document_type_filename_list,
                link_acl_list, link_document_type_delete
            ), sources=(DocumentType,)
        )
        menu_object.bind_links(
            links=(
                link_document_type_filename_edit,
                link_document_type_filename_delete
            ), sources=(DocumentTypeFilename,)
        )
        menu_secondary.bind_links(
            links=(link_document_type_list, link_document_type_create),
            sources=(
                DocumentType, 'documents:document_type_create',
                'documents:document_type_list'
            )
        )
        menu_sidebar.bind_links(
            links=(link_document_type_filename_create,),
            sources=(
                DocumentTypeFilename, 'documents:document_type_filename_list',
                'documents:document_type_filename_create'
            )
        )
        menu_sidebar.bind_links(
            links=(link_trash_can_empty,),
            sources=(
                'documents:document_list_deleted', 'documents:trash_can_empty'
            )
        )

        # Document object links
        menu_object.bind_links(
            links=(
                link_document_edit, link_document_document_type_edit,
                link_document_print, link_document_trash,
                link_document_download, link_document_clear_transformations,
                link_document_update_page_count
            ), sources=(Document,)
        )
        menu_object.bind_links(
            links=(link_document_restore, link_document_delete),
            sources=(DeletedDocument,)
        )

        # Document facet links
        menu_facet.bind_links(links=(link_acl_list,), sources=(Document,))
        menu_facet.bind_links(
            links=(link_document_preview,), sources=(Document,), position=0
        )
        menu_facet.bind_links(
            links=(link_document_properties,), sources=(Document,), position=2
        )
        menu_facet.bind_links(
            links=(link_events_for_object, link_document_version_list,),
            sources=(Document,), position=2
        )
        menu_facet.bind_links(links=(link_document_pages,), sources=(Document,))

        # Document actions
        menu_object.bind_links(
            links=(
                link_document_version_revert, link_document_version_download
            ),
            sources=(DocumentVersion,)
        )
        menu_multi_item.bind_links(
            links=(
                link_document_multiple_clear_transformations,
                link_document_multiple_trash, link_document_multiple_download,
                link_document_multiple_update_page_count,
                link_document_multiple_document_type_edit
            ), sources=(Document,)
        )
        menu_multi_item.bind_links(
            links=(
                link_document_multiple_restore, link_document_multiple_delete
            ), sources=(DeletedDocument,)
        )

        # Document pages
        menu_facet.bind_links(
            links=(
                link_document_page_rotate_left,
                link_document_page_rotate_right, link_document_page_zoom_in,
                link_document_page_zoom_out, link_document_page_view_reset
            ), sources=('documents:document_page_view',)
        )
        menu_facet.bind_links(
            links=(link_document_page_return, link_document_page_view),
            sources=(DocumentPage,)
        )
        menu_facet.bind_links(
            links=(
                link_document_page_navigation_first,
                link_document_page_navigation_previous,
                link_document_page_navigation_next,
                link_document_page_navigation_last, link_transformation_list
            ), sources=(DocumentPage,)
        )
        menu_object.bind_links(
            links=(link_transformation_list,), sources=(DocumentPage,)
        )

        namespace = StatisticNamespace(slug='documents', label=_('Documents'))
        namespace.add_statistic(
            slug='new-documents-per-month',
            label=_('New documents per month'),
            func=new_documents_per_month,
            renderer=CharJSLine,
            minute='0'
        )
        namespace.add_statistic(
            slug='new-document-versions-per-month',
            label=_('New document versions per month'),
            func=new_document_versions_per_month,
            renderer=CharJSLine,
            minute='0'
        )
        namespace.add_statistic(
            slug='new-document-pages-per-month',
            label=_('New document pages per month'),
            func=new_document_pages_per_month,
            renderer=CharJSLine,
            minute='0'
        )
        namespace.add_statistic(
            slug='total-documents-at-each-month',
            label=_('Total documents at each month'),
            func=total_document_per_month,
            renderer=CharJSLine,
            minute='0'
        )
        namespace.add_statistic(
            slug='total-document-versions-at-each-month',
            label=_('Total document versions at each month'),
            func=total_document_version_per_month,
            renderer=CharJSLine,
            minute='0'
        )
        namespace.add_statistic(
            slug='total-document-pages-at-each-month',
            label=_('Total document pages at each month'),
            func=total_document_page_per_month,
            renderer=CharJSLine,
            minute='0'
        )

        post_initial_setup.connect(
            create_default_document_type,
            dispatch_uid='create_default_document_type'
        )

        registry.register(DeletedDocument)
        registry.register(Document)
Example #17
0
    def ready(self):
        super(DocumentsApp, self).ready()
        from actstream import registry

        DeletedDocument = self.get_model('DeletedDocument')
        Document = self.get_model('Document')
        DocumentPage = self.get_model('DocumentPage')
        DocumentPageResult = self.get_model('DocumentPageResult')
        DocumentType = self.get_model('DocumentType')
        DocumentTypeFilename = self.get_model('DocumentTypeFilename')
        DocumentVersion = self.get_model('DocumentVersion')
        DuplicatedDocument = self.get_model('DuplicatedDocument')

        DynamicSerializerField.add_serializer(
            klass=Document,
            serializer_class='documents.serializers.DocumentSerializer')

        MissingItem(
            label=_('Create a document type'),
            description=_(
                'Every uploaded document must be assigned a document type, '
                'it is the basic way Mayan EDMS categorizes documents.'),
            condition=lambda: not DocumentType.objects.exists(),
            view='documents:document_type_list')

        ModelAttribute(Document,
                       label=_('Label'),
                       name='label',
                       type_name='field')

        ModelAttribute(
            Document,
            description=_(
                'The MIME type of any of the versions of a document'),
            label=_('MIME type'),
            name='versions__mimetype',
            type_name='field')

        ModelEventType.register(model=DocumentType,
                                event_types=(event_document_create, ))
        ModelEventType.register(model=Document,
                                event_types=(event_document_download,
                                             event_document_properties_edit,
                                             event_document_type_change,
                                             event_document_new_version,
                                             event_document_version_revert,
                                             event_document_view))

        ModelPermission.register(model=Document,
                                 permissions=(
                                     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_version_view,
                                     permission_document_view,
                                     permission_events_view,
                                     permission_transformation_create,
                                     permission_transformation_delete,
                                     permission_transformation_edit,
                                     permission_transformation_view,
                                 ))

        ModelPermission.register(model=DocumentType,
                                 permissions=(permission_document_create,
                                              permission_document_type_delete,
                                              permission_document_type_edit,
                                              permission_document_type_view))

        ModelPermission.register_proxy(
            source=Document,
            model=DocumentType,
        )

        ModelPermission.register_inheritance(
            model=Document,
            related='document_type',
        )
        ModelPermission.register_inheritance(
            model=DocumentPage,
            related='document',
        )
        ModelPermission.register_inheritance(
            model=DocumentPageResult,
            related='document_version__document',
        )
        ModelPermission.register_inheritance(
            model=DocumentTypeFilename,
            related='document_type',
        )
        ModelPermission.register_inheritance(
            model=DocumentVersion,
            related='document',
        )

        # Document and document page thumbnail widget
        document_page_thumbnail_widget = DocumentPageThumbnailWidget()

        # Document
        SourceColumn(source=Document,
                     label=_('Thumbnail'),
                     func=lambda context: document_page_thumbnail_widget.
                     render(instance=context['object']))
        SourceColumn(source=Document, attribute='document_type')
        SourceColumn(source=Document,
                     label=_('Pages'),
                     func=lambda context: widget_document_page_number(
                         document=context['object']))

        # DocumentPage
        SourceColumn(source=DocumentPage,
                     label=_('Thumbnail'),
                     func=lambda context: document_page_thumbnail_widget.
                     render(instance=context['object']))

        SourceColumn(source=DocumentPageResult,
                     label=_('Thumbnail'),
                     func=lambda context: document_page_thumbnail_widget.
                     render(instance=context['object']))

        SourceColumn(source=DocumentPageResult,
                     label=_('Type'),
                     attribute='document_version.document.document_type')

        # DocumentType
        SourceColumn(source=DocumentType,
                     label=_('Documents'),
                     func=lambda context: context['object'].get_document_count(
                         user=context['request'].user))

        SourceColumn(
            source=DocumentTypeFilename,
            label=_('Enabled'),
            func=lambda context: two_state_template(context['object'].enabled))

        # DeletedDocument
        SourceColumn(source=DeletedDocument,
                     label=_('Thumbnail'),
                     func=lambda context: document_page_thumbnail_widget.
                     render(instance=context['object']))

        SourceColumn(source=DeletedDocument, attribute='document_type')
        SourceColumn(source=DeletedDocument, attribute='deleted_date_time')

        # DocumentVersion
        SourceColumn(source=DocumentVersion,
                     label=_('Thumbnail'),
                     func=lambda context: document_page_thumbnail_widget.
                     render(instance=context['object']))
        SourceColumn(source=DocumentVersion, attribute='timestamp')
        SourceColumn(source=DocumentVersion,
                     label=_('Pages'),
                     func=lambda context: widget_document_version_page_number(
                         document_version=context['object']))
        SourceColumn(source=DocumentVersion, attribute='mimetype')
        SourceColumn(source=DocumentVersion, attribute='encoding')
        SourceColumn(source=DocumentVersion, attribute='comment')

        # DuplicatedDocument
        SourceColumn(source=DuplicatedDocument,
                     label=_('Thumbnail'),
                     func=lambda context: document_page_thumbnail_widget.
                     render(instance=context['object'].document))
        SourceColumn(source=DuplicatedDocument,
                     label=_('Duplicates'),
                     func=lambda context: context['object'].documents.count())

        app.conf.CELERYBEAT_SCHEDULE.update({
            'task_check_delete_periods': {
                'task': 'documents.tasks.task_check_delete_periods',
                'schedule': timedelta(seconds=CHECK_DELETE_PERIOD_INTERVAL),
            },
            'task_check_trash_periods': {
                'task': 'documents.tasks.task_check_trash_periods',
                'schedule': timedelta(seconds=CHECK_TRASH_PERIOD_INTERVAL),
            },
            'task_delete_stubs': {
                'task': 'documents.tasks.task_delete_stubs',
                'schedule': timedelta(seconds=DELETE_STALE_STUBS_INTERVAL),
            },
        })

        app.conf.CELERY_QUEUES.extend((
            Queue('converter',
                  Exchange('converter'),
                  routing_key='converter',
                  delivery_mode=1),
            Queue('documents_periodic',
                  Exchange('documents_periodic'),
                  routing_key='documents_periodic',
                  delivery_mode=1),
            Queue('uploads', Exchange('uploads'), routing_key='uploads'),
            Queue('documents', Exchange('documents'), routing_key='documents'),
        ))

        app.conf.CELERY_ROUTES.update({
            'documents.tasks.task_check_delete_periods': {
                'queue': 'documents_periodic'
            },
            'documents.tasks.task_check_trash_periods': {
                'queue': 'documents_periodic'
            },
            'documents.tasks.task_clean_empty_duplicate_lists': {
                'queue': 'documents'
            },
            'documents.tasks.task_clear_image_cache': {
                'queue': 'tools'
            },
            'documents.tasks.task_delete_document': {
                'queue': 'documents'
            },
            'documents.tasks.task_delete_stubs': {
                'queue': 'documents_periodic'
            },
            'documents.tasks.task_generate_document_page_image': {
                'queue': 'converter'
            },
            'documents.tasks.task_scan_duplicates_all': {
                'queue': 'tools'
            },
            'documents.tasks.task_scan_duplicates_for': {
                'queue': 'uploads'
            },
            'documents.tasks.task_update_page_count': {
                'queue': 'uploads'
            },
            'documents.tasks.task_upload_new_version': {
                'queue': 'uploads'
            },
        })

        dashboard_main.add_widget(widget=widget_document_types)
        dashboard_main.add_widget(widget=widget_documents_in_trash)
        dashboard_main.add_widget(widget=widget_new_documents_this_month)
        dashboard_main.add_widget(widget=widget_pages_per_month)
        dashboard_main.add_widget(widget=widget_total_documents)

        menu_documents.bind_links(links=(link_document_list_recent,
                                         link_document_list,
                                         link_document_list_deleted,
                                         link_duplicated_document_list))

        menu_main.bind_links(links=(menu_documents, ), position=0)

        menu_setup.bind_links(links=(link_document_type_setup, ))
        menu_tools.bind_links(links=(link_clear_image_cache,
                                     link_duplicated_document_scan))

        # Document type links
        menu_object.bind_links(
            links=(link_document_type_edit, link_document_type_filename_list,
                   link_acl_list,
                   link_object_event_types_user_subcriptions_list,
                   link_document_type_delete),
            sources=(DocumentType, ))
        menu_object.bind_links(links=(link_document_type_filename_edit,
                                      link_document_type_filename_delete),
                               sources=(DocumentTypeFilename, ))
        menu_secondary.bind_links(links=(link_document_type_list,
                                         link_document_type_create),
                                  sources=(DocumentType,
                                           'documents:document_type_create',
                                           'documents:document_type_list'))
        menu_sidebar.bind_links(
            links=(link_document_type_filename_create, ),
            sources=(DocumentTypeFilename,
                     'documents:document_type_filename_list',
                     'documents:document_type_filename_create'))
        menu_sidebar.bind_links(links=(link_trash_can_empty, ),
                                sources=('documents:document_list_deleted',
                                         'documents:trash_can_empty'))

        # Document object links
        menu_object.bind_links(links=(
            link_document_edit,
            link_document_document_type_edit,
            link_document_print,
            link_document_trash,
            link_document_quick_download,
            link_document_download,
            link_document_clear_transformations,
            link_document_clone_transformations,
            link_document_update_page_count,
        ),
                               sources=(Document, ))
        menu_object.bind_links(links=(link_document_restore,
                                      link_document_delete),
                               sources=(DeletedDocument, ))

        # Document facet links
        menu_facet.bind_links(links=(
            link_document_duplicates_list,
            link_acl_list_with_icon,
        ),
                              sources=(Document, ))
        menu_facet.bind_links(links=(link_document_preview, ),
                              sources=(Document, ),
                              position=0)
        menu_facet.bind_links(links=(link_document_properties, ),
                              sources=(Document, ),
                              position=2)
        menu_facet.bind_links(links=(
            link_events_for_object,
            link_object_event_types_user_subcriptions_list_with_icon,
            link_document_version_list,
        ),
                              sources=(Document, ),
                              position=2)
        menu_facet.bind_links(links=(link_document_pages, ),
                              sources=(Document, ))

        # Document actions
        menu_object.bind_links(links=(link_document_version_revert,
                                      link_document_version_download),
                               sources=(DocumentVersion, ))
        menu_multi_item.bind_links(
            links=(link_document_multiple_clear_transformations,
                   link_document_multiple_trash,
                   link_document_multiple_download,
                   link_document_multiple_update_page_count,
                   link_document_multiple_document_type_edit),
            sources=(Document, ))
        menu_multi_item.bind_links(links=(link_document_multiple_restore,
                                          link_document_multiple_delete),
                                   sources=(DeletedDocument, ))

        # Document pages
        menu_facet.bind_links(
            links=(link_document_page_rotate_left,
                   link_document_page_rotate_right, link_document_page_zoom_in,
                   link_document_page_zoom_out, link_document_page_view_reset),
            sources=('documents:document_page_view', ))
        menu_facet.bind_links(links=(link_document_page_return,
                                     link_document_page_view),
                              sources=(DocumentPage, ))
        menu_facet.bind_links(links=(link_document_page_navigation_first,
                                     link_document_page_navigation_previous,
                                     link_document_page_navigation_next,
                                     link_document_page_navigation_last,
                                     link_transformation_list),
                              sources=(DocumentPage, ))
        menu_object.bind_links(links=(link_transformation_list, ),
                               sources=(DocumentPage, ))

        # Document versions
        menu_facet.bind_links(links=(link_document_version_return_document,
                                     link_document_version_return_list),
                              sources=(DocumentVersion, ))
        menu_facet.bind_links(links=(link_document_version_view, ),
                              sources=(DocumentVersion, ))

        post_delete.connect(
            dispatch_uid='handler_remove_empty_duplicates_lists',
            receiver=handler_remove_empty_duplicates_lists,
            sender=Document,
        )
        post_initial_setup.connect(create_default_document_type,
                                   dispatch_uid='create_default_document_type')
        post_version_upload.connect(
            handler_scan_duplicates_for,
            dispatch_uid='handler_scan_duplicates_for',
        )

        registry.register(DeletedDocument)
        registry.register(Document)
        registry.register(DocumentType)
        registry.register(DocumentVersion)