diff -r 000000000000 -r 7c0001cacf8e src/pyams_content/shared/common/zmi/workflow.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pyams_content/shared/common/zmi/workflow.py Thu Oct 08 13:37:29 2015 +0200 @@ -0,0 +1,813 @@ +# +# Copyright (c) 2008-2015 Thierry Florac +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# +from pyams_utils.text import text_to_html + +__docformat__ = 'restructuredtext' + + +# import standard library +from datetime import datetime + +# import interfaces +from pyams_content.shared.common.interfaces import IWfSharedContent, ISharedTool, ISharedContent +from pyams_form.interfaces.form import IInnerTabForm, IFormPrefixViewletsManager, IWidgetsPrefixViewletsManager, \ + IFormSuffixViewletsManager +from pyams_security.interfaces import ISecurityManager +from pyams_skin.interfaces import IInnerPage +from pyams_skin.layer import IPyAMSLayer +from pyams_workflow.interfaces import IWorkflowInfo, IWorkflowTransitionInfo, IWorkflowPublicationInfo, \ + IWorkflowCommentInfo, IWorkflowVersions, IWorkflowState, IWorkflowManagedContent, IWorkflow, IWorkflowStateLabel, \ + IWorkflowRequestUrgencyInfo, SYSTEM, MANUAL +from z3c.form.interfaces import IDataExtractedEvent + +# import packages +from pyams_content.shared.common.zmi.summary import SharedContentSummaryForm +from pyams_content.workflow import DRAFT, DELETED +from pyams_form.form import AJAXAddForm, InnerDisplayForm +from pyams_form.schema import CloseButton +from pyams_pagelet.pagelet import pagelet_config +from pyams_template.template import template_config +from pyams_utils.adapter import adapter_config +from pyams_utils.date import format_datetime +from pyams_utils.registry import get_utility +from pyams_utils.timezone import tztime +from pyams_utils.traversing import get_parent +from pyams_utils.url import absolute_url +from pyams_viewlet.viewlet import viewlet_config, Viewlet +from pyams_workflow.zmi.transition import WorkflowContentTransitionForm, WorkflowContentTransitionAJAXForm +from pyramid.events import subscriber +from pyramid.view import view_config +from z3c.form import field, button +from zope.interface import implementer, Interface, Invalid + +from pyams_content import _ + + +# +# Workflow summary view +# + +@adapter_config(name='workflow-summary', + context=(IWfSharedContent, IPyAMSLayer, SharedContentSummaryForm), + provides=IInnerTabForm) +class WfSharedContentWorkflowSummary(InnerDisplayForm): + """Shared content workflow summary""" + + weight = 10 + tab_label = _("Workflow") + tab_target = 'workflow-summary.html' + + fields = field.Fields(Interface) + + +@pagelet_config(name='workflow-summary.html', context=IWfSharedContent, layer=IPyAMSLayer) +@implementer(IInnerPage, IInnerTabForm) +class WorkflowSummaryDisplayForm(InnerDisplayForm): + """Workflow summary display form""" + + @property + def fields(self): + fields = field.Fields(IWorkflowState).omit('history') + \ + field.Fields(IWorkflowPublicationInfo) + workflow = IWorkflow(self.context) + if IWorkflowState(self.context).state not in workflow.waiting_states: + fields = fields.omit('state_urgency') + return fields + + def updateWidgets(self, prefix=None): + super(WorkflowSummaryDisplayForm, self).updateWidgets(prefix) + state = IWorkflowState(self.context) + content = get_parent(self.context, IWorkflowManagedContent) + workflow = get_utility(IWorkflow, name=content.workflow_name) + self.widgets['state'].value = self.request.localizer.translate(workflow.get_state_label(state.state)) + self.widgets['state_date'].value = format_datetime(tztime(state.state_date)) + info = IWorkflowPublicationInfo(self.context) + if info.publication_date: + self.widgets['publication_date'].value = format_datetime(tztime(info.publication_date)) + if info.first_publication_date: + self.widgets['first_publication_date'].value = format_datetime(tztime(info.first_publication_date)) + if info.publication_effective_date: + self.widgets['publication_effective_date'].value = format_datetime(tztime(info.publication_effective_date)) + if info.publication_expiration_date: + self.widgets['publication_expiration_date'].value = format_datetime((tztime(info.publication_expiration_date))) + + +# +# Generic transition info +# + +@viewlet_config(name='wf-transition-info', context=IWfSharedContent, layer=IPyAMSLayer, + view=WorkflowContentTransitionForm, manager=IFormSuffixViewletsManager, weight=10) +@template_config(template='templates/wf-transition-info.pt') +class WorkflowContentTransitionFormInfo(Viewlet): + """Publication request form info message""" + + @property + def previous_step(self): + translate = self.request.localizer.translate + workflow = IWorkflow(self.context) + state = IWorkflowState(self.context) + adapter = self.request.registry.queryAdapter(workflow, IWorkflowStateLabel, + name=state.state) + if adapter is None: + adapter = self.request.registry.queryAdapter(workflow, IWorkflowStateLabel) + if adapter is not None: + state_label = adapter.get_label(self.context, request=self.request) + else: + security = get_utility(ISecurityManager) + state_label = translate(_("{state} by {principal}")).format( + state=translate(workflow.get_state_label(state.state)), + principal=security.get_principal(state.state_principal).title) + return translate(_("{state} {date}")).format(state=state_label, + date=format_datetime(state.state_date, request=self.request)) + + @property + def previous_message(self): + workflow = IWorkflow(self.context) + state = IWorkflowState(self.context) + position = 0 + history_item = None + trigger = SYSTEM + while trigger != MANUAL: + position -= 1 + history_item = state.history[position] + if history_item.transition_id: + trigger = workflow.get_transition_by_id(history_item.transition_id).trigger + else: + break + if history_item: + return text_to_html((history_item.comment or '').strip()) + + @property + def next_step(self): + transition = self.__parent__.transition + return self.request.localizer.translate(transition.user_data.get('next_step')) \ + if 'next_step' in transition.user_data else None + + +# +# Request publication form +# + +class IPublicationRequestButtons(Interface): + """Shared content publication request buttons""" + + close = CloseButton(name='close', title=_("Cancel")) + action = button.Button(name='action', title=_("Request publication")) + + +@pagelet_config(name='wf-propose.html', context=IWfSharedContent, layer=IPyAMSLayer, permission='pyams.ManageContent') +class PublicationRequestForm(WorkflowContentTransitionForm): + """Shared content publication request form""" + + fields = field.Fields(IWorkflowTransitionInfo) + \ + field.Fields(IWorkflowPublicationInfo).select('publication_effective_date', + 'publication_expiration_date') + \ + field.Fields(IWorkflowRequestUrgencyInfo) + \ + field.Fields(IWorkflowCommentInfo) + buttons = button.Buttons(IPublicationRequestButtons) + ajax_handler = 'wf-propose.json' + + def updateWidgets(self, prefix=None): + super(PublicationRequestForm, self).updateWidgets(prefix) + self.widgets['publication_effective_date'].required = True + self.widgets['publication_effective_date'].value = datetime.now().strftime('%d/%m/%y %H:%M') + self.widgets['comment'].required = True + + def createAndAdd(self, data): + pub_info = IWorkflowPublicationInfo(self.context) + pub_info.publication_effective_date = data.get('publication_effective_date') + pub_info.publication_expiration_date = data.get('publication_expiration_date') + return super(PublicationRequestForm, self).createAndAdd(data) + + +@view_config(name='wf-propose.json', context=IWfSharedContent, request_type=IPyAMSLayer, + permission='pyams.ManageContent', renderer='json', xhr=True) +class PublicationRequestAJAXForm(WorkflowContentTransitionAJAXForm, PublicationRequestForm): + """Shared content publication request form, JSON renderer""" + + +@subscriber(IDataExtractedEvent, form_selector=PublicationRequestForm) +def handle_publication_request_form_data_extraction(event): + """Handle publication request form data extraction""" + if not event.data.get('publication_effective_date'): + event.form.widgets.errors += (Invalid(_("Publication start date is required")), ) + comment = (event.data.get('comment') or '').strip() + if not comment: + event.form.widgets.errors += (Invalid(_("A comment is required")), ) + + +@viewlet_config(name='wf-propose-owner-warning', context=IWfSharedContent, layer=IPyAMSLayer, + view=PublicationRequestForm, manager=IFormPrefixViewletsManager, weight=10) +@template_config(template='templates/wf-owner-warning.pt') +class PublicationRequestFormWarning(Viewlet): + """Publication request form warning message""" + + def __new__(cls, context, request, view, manager): + if request.principal.id in context.owner: + return None + return Viewlet.__new__(cls) + + +@viewlet_config(name='wf-propose-message', context=IWfSharedContent, layer=IPyAMSLayer, view=PublicationRequestForm, + manager=IWidgetsPrefixViewletsManager, weight=20) +@template_config(template='templates/wf-propose-message.pt') +class PublicationRequestFormMessage(Viewlet): + """Publication request form info message""" + + +# +# Cancel publication request form +# + +class IPublicationRequestCancelButtons(Interface): + """Shared content publication request cancel buttons""" + + close = CloseButton(name='close', title=_("Cancel")) + action = button.Button(name='action', title=_("Cancel publication request")) + + +@pagelet_config(name='wf-cancel-propose.html', context=IWfSharedContent, layer=IPyAMSLayer, + permission='pyams.ManageContent') +class PublicationRequestCancelForm(WorkflowContentTransitionForm): + """Shared content publication request cancel form""" + + buttons = button.Buttons(IPublicationRequestCancelButtons) + ajax_handler = 'wf-cancel-propose.json' + + +@view_config(name='wf-cancel-propose.json', context=IWfSharedContent, request_type=IPyAMSLayer, + permission='pyams.ManageContent', renderer='json', xhr=True) +class PublicationRequestCancelAJAXForm(WorkflowContentTransitionAJAXForm, PublicationRequestCancelForm): + """Shared content publication request cancel form, JSON renderer""" + + +@viewlet_config(name='wf-cancel-propose-owner-warning', context=IWfSharedContent, layer=IPyAMSLayer, + view=PublicationRequestCancelForm, manager=IFormPrefixViewletsManager, weight=10) +@template_config(template='templates/wf-owner-warning.pt') +class PublicationRequestCancelFormWarning(Viewlet): + """Publication request cancel form warning message""" + + def __new__(cls, context, request, view, manager): + if request.principal.id in context.owner: + return None + return Viewlet.__new__(cls) + + +@viewlet_config(name='wf-cancel-propose-message', context=IWfSharedContent, layer=IPyAMSLayer, + view=PublicationRequestCancelForm, manager=IWidgetsPrefixViewletsManager, weight=20) +@template_config(template='templates/wf-cancel-propose-message.pt') +class PublicationRequestCancelFormMessage(Viewlet): + """Publication request cancel form info message""" + + +# +# Refuse publication form +# + +class IPublicationRequestRefuseButtons(Interface): + """Shared content publication request refuse buttons""" + + close = CloseButton(name='close', title=_("Cancel")) + action = button.Button(name='action', title=_("Refuse publication request")) + + +@pagelet_config(name='wf-refuse.html', context=IWfSharedContent, layer=IPyAMSLayer, + permission='pyams.PublishContent') +class PublicationRequestRefuseForm(WorkflowContentTransitionForm): + """Shared content publication request refuse form""" + + buttons = button.Buttons(IPublicationRequestRefuseButtons) + ajax_handler = 'wf-refuse.json' + + def updateWidgets(self, prefix=None): + super(PublicationRequestRefuseForm, self).updateWidgets(prefix) + self.widgets['comment'].required = True + + +@view_config(name='wf-refuse.json', context=IWfSharedContent, request_type=IPyAMSLayer, + permission='pyams.PublishContent', renderer='json', xhr=True) +class PublicationRequestRefuseAJAXForm(WorkflowContentTransitionAJAXForm, PublicationRequestRefuseForm): + """Shared content publication request refuse form, JSON renderer""" + + +@subscriber(IDataExtractedEvent, form_selector=PublicationRequestRefuseForm) +def handle_publication_request_refuse_form_data_extraction(event): + """Handle publication request refuse form data extraction""" + comment = (event.data.get('comment') or '').strip() + if not comment: + event.form.widgets.errors += (Invalid(_("A comment is required")), ) + + +@viewlet_config(name='wf-refuse-operator-warning', context=IWfSharedContent, layer=IPyAMSLayer, + view=PublicationRequestRefuseForm, manager=IFormPrefixViewletsManager, weight=10) +@template_config(template='templates/wf-operator-warning.pt') +class PublicationRequestRefuseFormWarning(Viewlet): + """Publication request refuse form warning message""" + + def __new__(cls, context, request, view, manager): + state = IWorkflowState(context) + if state.state_principal in context.owner: + return None + return Viewlet.__new__(cls) + + +@viewlet_config(name='wf-refuse-message', context=IWfSharedContent, layer=IPyAMSLayer, + view=PublicationRequestRefuseForm, manager=IWidgetsPrefixViewletsManager, weight=20) +@template_config(template='templates/wf-refuse-propose-message.pt') +class PublicationRequestRefuseFormMessage(Viewlet): + """Publication request refuse form info message""" + + +# +# Publish form +# + +class IPublicationButtons(Interface): + """Shared content publication buttons""" + + close = CloseButton(name='close', title=_("Cancel")) + action = button.Button(name='action', title=_("Publish")) + + +@pagelet_config(name='wf-publish.html', context=IWfSharedContent, layer=IPyAMSLayer, permission='pyams.PublishContent') +class PublicationForm(WorkflowContentTransitionForm): + """Shared content publication form""" + + fields = field.Fields(IWorkflowTransitionInfo) + \ + field.Fields(IWorkflowPublicationInfo).select('publication_effective_date', + 'publication_expiration_date') + \ + field.Fields(IWorkflowCommentInfo) + buttons = button.Buttons(IPublicationButtons) + ajax_handler = 'wf-publish.json' + + def updateWidgets(self, prefix=None): + super(PublicationForm, self).updateWidgets(prefix) + pub_info = IWorkflowPublicationInfo(self.context) + self.widgets['publication_effective_date'].required = True + if ('publication_effective_date' in self.widgets) and pub_info.publication_effective_date: + self.widgets['publication_effective_date'].value = \ + tztime(pub_info.publication_effective_date).strftime('%d/%m/%y %H:%M') + if ('publication_expiration_date' in self.widgets) and pub_info.publication_expiration_date: + self.widgets['publication_expiration_date'].value = \ + tztime(pub_info.publication_expiration_date).strftime('%d/%m/%y %H:%M') + + def createAndAdd(self, data): + pub_info = IWorkflowPublicationInfo(self.context) + pub_info.publication_effective_date = data.get('publication_effective_date') + pub_info.publication_expiration_date = data.get('publication_expiration_date') + return super(PublicationForm, self).createAndAdd(data) + + +@view_config(name='wf-publish.json', context=IWfSharedContent, request_type=IPyAMSLayer, + permission='pyams.PublishContent', renderer='json', xhr=True) +class PublicationAJAXForm(WorkflowContentTransitionAJAXForm, PublicationForm): + """Shared content publication form, JSON renderer""" + + +@subscriber(IDataExtractedEvent, form_selector=PublicationForm) +def handle_publication_form_data_extraction(event): + """Handle publication form data extraction""" + if not event.data.get('publication_effective_date'): + event.form.widgets.errors += (Invalid(_("Publication start date is required")), ) + + +@viewlet_config(name='wf-publish-operator-warning', context=IWfSharedContent, layer=IPyAMSLayer, + view=PublicationForm, manager=IFormPrefixViewletsManager, weight=10) +@template_config(template='templates/wf-operator-warning.pt') +class PublicationFormWarning(Viewlet): + """Shared content publication form warning message""" + + def __new__(cls, context, request, view, manager): + state = IWorkflowState(context) + if state.state_principal in context.owner: + return None + return Viewlet.__new__(cls) + + +@viewlet_config(name='wf-publish-message', context=IWfSharedContent, layer=IPyAMSLayer, + view=PublicationForm, manager=IWidgetsPrefixViewletsManager, weight=20) +@template_config(template='templates/wf-publish-message.pt') +class PublicationFormMessage(Viewlet): + """Shared content publication form info message""" + + +# +# Publication retire request form +# + +class IPublicationRetireRequestButtons(Interface): + """Shared content publication retire request buttons""" + + close = CloseButton(name='close', title=_("Cancel")) + action = button.Button(name='action', title=_("Request retire")) + + +@pagelet_config(name='wf-retiring.html', context=IWfSharedContent, layer=IPyAMSLayer, + permission='pyams.ManageContent') +class PublicationRetireRequestForm(WorkflowContentTransitionForm): + """Shared content publication request refuse form""" + + fields = field.Fields(IWorkflowTransitionInfo) + \ + field.Fields(IWorkflowRequestUrgencyInfo) + \ + field.Fields(IWorkflowCommentInfo) + buttons = button.Buttons(IPublicationRetireRequestButtons) + ajax_handler = 'wf-retiring.json' + + def updateWidgets(self, prefix=None): + super(PublicationRetireRequestForm, self).updateWidgets(prefix) + self.widgets['comment'].required = True + + +@view_config(name='wf-retiring.json', context=IWfSharedContent, request_type=IPyAMSLayer, + permission='pyams.ManageContent', renderer='json', xhr=True) +class PublicationRetireRequestAJAXForm(WorkflowContentTransitionAJAXForm, PublicationRetireRequestForm): + """Shared content publication retire request form, JSON renderer""" + + +@subscriber(IDataExtractedEvent, form_selector=PublicationRetireRequestForm) +def handle_publication_retire_request_form_data_extraction(event): + """Handle publication retire request form data extraction""" + comment = (event.data.get('comment') or '').strip() + if not comment: + event.form.widgets.errors += (Invalid(_("A comment is required")), ) + + +@viewlet_config(name='wf-retiring-owner-warning', context=IWfSharedContent, layer=IPyAMSLayer, + view=PublicationRetireRequestForm, manager=IFormPrefixViewletsManager, weight=10) +@template_config(template='templates/wf-owner-warning.pt') +class PublicationRetireRequestFormWarning(Viewlet): + """Publication retire request form warning message""" + + def __new__(cls, context, request, view, manager): + if request.principal.id in context.owner: + return None + return Viewlet.__new__(cls) + + +@viewlet_config(name='wf-retiring-message', context=IWfSharedContent, layer=IPyAMSLayer, + view=PublicationRetireRequestForm, manager=IWidgetsPrefixViewletsManager, weight=20) +@template_config(template='templates/wf-retiring-message.pt') +class PublicationRetireRequestFormMessage(Viewlet): + """Publication retire request form info message""" + + +# +# Publication retire cancel form +# + +class IPublicationRetireCancelButtons(Interface): + """Shared content publication retire request cancel buttons""" + + close = CloseButton(name='close', title=_("Cancel")) + action = button.Button(name='action', title=_("Cancel retire request")) + + +@pagelet_config(name='wf-cancel-retiring.html', context=IWfSharedContent, layer=IPyAMSLayer, + permission='pyams.ManageContent') +class PublicationRetireCancelForm(WorkflowContentTransitionForm): + """Shared content publication retire request cancel form""" + + buttons = button.Buttons(IPublicationRetireCancelButtons) + ajax_handler = 'wf-cancel-retiring.json' + + +@view_config(name='wf-cancel-retiring.json', context=IWfSharedContent, request_type=IPyAMSLayer, + permission='pyams.ManageContent', renderer='json', xhr=True) +class PublicationRetireCancelAJAXForm(WorkflowContentTransitionAJAXForm, PublicationRetireCancelForm): + """Shared content publication retire request cancel form, JSON renderer""" + + +@viewlet_config(name='wf-cancel-retiring-owner-warning', context=IWfSharedContent, layer=IPyAMSLayer, + view=PublicationRetireCancelForm, manager=IFormPrefixViewletsManager, weight=10) +@template_config(template='templates/wf-owner-warning.pt') +class PublicationRetireCancelFormWarning(Viewlet): + """Publication retire request cancel form warning message""" + + def __new__(cls, context, request, view, manager): + if request.principal.id in context.owner: + return None + return Viewlet.__new__(cls) + + +@viewlet_config(name='wf-cancel-retiring-message', context=IWfSharedContent, layer=IPyAMSLayer, + view=PublicationRetireCancelForm, manager=IWidgetsPrefixViewletsManager, weight=20) +@template_config(template='templates/wf-cancel-retiring-message.pt') +class PublicationRetireCancelFormMessage(Viewlet): + """Publication retire request form info message""" + + +# +# Publication retire form +# + +class IPublicationRetireButtons(Interface): + """Shared content publication retire buttons""" + + close = CloseButton(name='close', title=_("Cancel")) + action = button.Button(name='action', title=_("Retire")) + + +@pagelet_config(name='wf-retire.html', context=IWfSharedContent, layer=IPyAMSLayer, + permission='pyams.PublishContent') +class PublicationRetireForm(WorkflowContentTransitionForm): + """Shared content publication retire form""" + + buttons = button.Buttons(IPublicationRetireButtons) + ajax_handler = 'wf-retire.json' + + +@view_config(name='wf-retire.json', context=IWfSharedContent, request_type=IPyAMSLayer, + permission='pyams.PublishContent', renderer='json', xhr=True) +class PublicationRetireAJAXForm(WorkflowContentTransitionAJAXForm, PublicationRetireForm): + """Shared content publication retire form, JSON renderer""" + + +@viewlet_config(name='wf-retire-operator-warning', context=IWfSharedContent, layer=IPyAMSLayer, + view=PublicationRetireForm, manager=IFormPrefixViewletsManager, weight=10) +@template_config(template='templates/wf-operator-warning.pt') +class PublicationRetireFormWarning(Viewlet): + """Publication retire form warning message""" + + def __new__(cls, context, request, view, manager): + state = IWorkflowState(context) + if state.state_principal in context.owner: + return None + return Viewlet.__new__(cls) + + +@viewlet_config(name='wf-retire-message', context=IWfSharedContent, layer=IPyAMSLayer, + view=PublicationRetireForm, manager=IWidgetsPrefixViewletsManager, weight=20) +@template_config(template='templates/wf-retire-message.pt') +class PublicationRetireFormMessage(Viewlet): + """Publication retire form info message""" + + +# +# Publication archive request form +# + +class IPublicationArchiveRequestButtons(Interface): + """Shared content publication archive request buttons""" + + close = CloseButton(name='close', title=_("Cancel")) + action = button.Button(name='action', title=_("Request archive")) + + +@pagelet_config(name='wf-archiving.html', context=IWfSharedContent, layer=IPyAMSLayer, + permission='pyams.ManageContent') +class PublicationArchiveRequestForm(WorkflowContentTransitionForm): + """Shared content publication request archive form""" + + fields = field.Fields(IWorkflowTransitionInfo) + \ + field.Fields(IWorkflowRequestUrgencyInfo) + \ + field.Fields(IWorkflowCommentInfo) + buttons = button.Buttons(IPublicationArchiveRequestButtons) + ajax_handler = 'wf-archiving.json' + + def updateWidgets(self, prefix=None): + super(PublicationArchiveRequestForm, self).updateWidgets(prefix) + self.widgets['comment'].required = True + + +@view_config(name='wf-archiving.json', context=IWfSharedContent, request_type=IPyAMSLayer, + permission='pyams.ManageContent', renderer='json', xhr=True) +class PublicationArchiveRequestAJAXForm(WorkflowContentTransitionAJAXForm, PublicationArchiveRequestForm): + """Shared content publication archive request form, JSON renderer""" + + +@subscriber(IDataExtractedEvent, form_selector=PublicationArchiveRequestForm) +def handle_archive_request_form_data_extraction(event): + """Handle archive request form data extraction""" + comment = (event.data.get('comment') or '').strip() + if not comment: + event.form.widgets.errors += (Invalid(_("A comment is required")), ) + + +@viewlet_config(name='wf-archiving-owner-warning', context=IWfSharedContent, layer=IPyAMSLayer, + view=PublicationArchiveRequestForm, manager=IFormPrefixViewletsManager, weight=10) +@template_config(template='templates/wf-owner-warning.pt') +class PublicationArchiveRequestFormWarning(Viewlet): + """Publication archive request form warning message""" + + def __new__(cls, context, request, view, manager): + if request.principal.id in context.owner: + return None + return Viewlet.__new__(cls) + + +@viewlet_config(name='wf-archiving-message', context=IWfSharedContent, layer=IPyAMSLayer, + view=PublicationArchiveRequestForm, manager=IWidgetsPrefixViewletsManager, weight=20) +@template_config(template='templates/wf-archiving-message.pt') +class PublicationArchiveRequestFormMessage(Viewlet): + """Publication archive request form info message""" + + +# +# Publication archive cancel form +# + +class IPublicationArchiveCancelButtons(Interface): + """Shared content publication archive request cancel buttons""" + + close = CloseButton(name='close', title=_("Cancel")) + action = button.Button(name='action', title=_("Cancel archive request")) + + +@pagelet_config(name='wf-cancel-archiving.html', context=IWfSharedContent, layer=IPyAMSLayer, + permission='pyams.ManageContent') +class PublicationArchiveCancelForm(WorkflowContentTransitionForm): + """Shared content publication archive request cancel form""" + + buttons = button.Buttons(IPublicationArchiveCancelButtons) + ajax_handler = 'wf-cancel-archiving.json' + + +@view_config(name='wf-cancel-archiving.json', context=IWfSharedContent, request_type=IPyAMSLayer, + permission='pyams.ManageContent', renderer='json', xhr=True) +class PublicationArchiveCancelAJAXForm(WorkflowContentTransitionAJAXForm, PublicationArchiveCancelForm): + """Shared content publication archive request cancel form, JSON renderer""" + + +@viewlet_config(name='wf-cancel-archiving-owner-warning', context=IWfSharedContent, layer=IPyAMSLayer, + view=PublicationArchiveCancelForm, manager=IFormPrefixViewletsManager, weight=10) +@template_config(template='templates/wf-owner-warning.pt') +class PublicationArchiveCancelFormWarning(Viewlet): + """Publication archive cancel form warning message""" + + def __new__(cls, context, request, view, manager): + if request.principal.id in context.owner: + return None + return Viewlet.__new__(cls) + + +@viewlet_config(name='wf-cancel-archiving-message', context=IWfSharedContent, layer=IPyAMSLayer, + view=PublicationArchiveCancelForm, manager=IWidgetsPrefixViewletsManager, weight=20) +@template_config(template='templates/wf-cancel-archiving-message.pt') +class PublicationArchiveCancelFormMessage(Viewlet): + """Publication archive cancel form info message""" + + +# +# Publication archive form +# + +class IPublicationArchiveButtons(Interface): + """Shared content publication archive buttons""" + + close = CloseButton(name='close', title=_("Cancel")) + action = button.Button(name='action', title=_("Archive")) + + +@pagelet_config(name='wf-archive.html', context=IWfSharedContent, layer=IPyAMSLayer, + permission='pyams.PublishContent') +class PublicationArchiveForm(WorkflowContentTransitionForm): + """Shared content publication archive form""" + + buttons = button.Buttons(IPublicationArchiveButtons) + ajax_handler = 'wf-archive.json' + + +@view_config(name='wf-archive.json', context=IWfSharedContent, request_type=IPyAMSLayer, + permission='pyams.PublishContent', renderer='json', xhr=True) +class PublicationArchiveAJAXForm(WorkflowContentTransitionAJAXForm, PublicationArchiveForm): + """Shared content publication archive form, JSON renderer""" + + +@viewlet_config(name='wf-archive-operator-warning', context=IWfSharedContent, layer=IPyAMSLayer, + view=PublicationArchiveForm, manager=IFormPrefixViewletsManager, weight=10) +@template_config(template='templates/wf-operator-warning.pt') +class PublicationArchiveFormWarning(Viewlet): + """Publication archive form warning message""" + + def __new__(cls, context, request, view, manager): + state = IWorkflowState(context) + if state.state_principal in context.owner: + return None + return Viewlet.__new__(cls) + + +@viewlet_config(name='wf-archive-message', context=IWfSharedContent, layer=IPyAMSLayer, + view=PublicationArchiveForm, manager=IWidgetsPrefixViewletsManager, weight=20) +@template_config(template='templates/wf-archive-message.pt') +class PublicationArchiveFormMessage(Viewlet): + """Publication archive form info message""" + + +# +# Clone form +# + +class ISharedContentCloneButtons(Interface): + """Shared content clone buttons""" + + close = CloseButton(name='close', title=_("Cancel")) + action = button.Button(name='action', title=_("Create new version")) + + +@pagelet_config(name='wf-clone.html', context=IWfSharedContent, layer=IPyAMSLayer, permission='pyams.CreateContent') +class SharedContentCloneForm(WorkflowContentTransitionForm): + """Shared content clone form""" + + buttons = button.Buttons(ISharedContentCloneButtons) + ajax_handler = 'wf-clone.json' + + def createAndAdd(self, data): + info = IWorkflowInfo(self.context) + return info.fire_transition_toward(DRAFT, comment=data.get('comment')) + + +@view_config(name='wf-clone.json', context=IWfSharedContent, request_type=IPyAMSLayer, + permission='pyams.CreateContent', renderer='json', xhr=True) +class SharedContentCloneAJAXForm(AJAXAddForm, SharedContentCloneForm): + """Shared content clone form, JSON rendener""" + + def get_ajax_output(self, changes): + return {'status': 'redirect', + 'location': absolute_url(changes, self.request, 'admin.html#properties.html')} + + +@viewlet_config(name='wf-clone-owner-warning', context=IWfSharedContent, layer=IPyAMSLayer, + view=SharedContentCloneForm, manager=IFormPrefixViewletsManager, weight=10) +@template_config(template='templates/wf-owner-warning.pt') +class SharedContentCloneFormWarning(Viewlet): + """Shared content clone form warning message""" + + def __new__(cls, context, request, view, manager): + if request.principal.id in context.owner: + return None + return Viewlet.__new__(cls) + + +@viewlet_config(name='wf-clone-message', context=IWfSharedContent, layer=IPyAMSLayer, + view=SharedContentCloneForm, manager=IWidgetsPrefixViewletsManager, weight=20) +@template_config(template='templates/wf-clone-message.pt') +class SharedContentCloneFormMessage(Viewlet): + """Shared content clone form info message""" + + +# +# Delete form +# + +class ISharedContentDeleteButtons(Interface): + """Shared content delete form buttons""" + + close = CloseButton(name='close', title=_("Cancel")) + action = button.Button(name='action', title=_("Delete version")) + + +@pagelet_config(name='wf-delete.html', context=IWfSharedContent, layer=IPyAMSLayer, permission='pyams.ManageContent') +class SharedContentDeleteForm(WorkflowContentTransitionForm): + """Shared content delete form""" + + buttons = button.Buttons(ISharedContentDeleteButtons) + ajax_handler = 'wf-delete.json' + + def createAndAdd(self, data): + state = IWorkflowState(self.context) + if state.version_id == 1: # remove the first and only version => remove all + content = get_parent(self.context, ISharedContent) + self.__target = get_parent(content, ISharedTool) + del content.__parent__[content.__name__] + else: + self.__target = get_parent(self.context, ISharedTool) + IWorkflowVersions(self.context).remove_version(state.version_id, state=DELETED, comment=data.get('comment')) + + +@view_config(name='wf-delete.json', context=IWfSharedContent, request_type=IPyAMSLayer, + permission='pyams.ManageContent', renderer='json', xhr=True) +class SharedContentDeleteAJAXForm(AJAXAddForm, SharedContentDeleteForm): + """Shared content delete form, JSON rendener""" + + def get_ajax_output(self, changes): + return {'status': 'redirect', + 'location': absolute_url(self._SharedContentDeleteForm__target, self.request, 'admin.html')} + + +@viewlet_config(name='wf-delete-owner-warning', context=IWfSharedContent, layer=IPyAMSLayer, + view=SharedContentDeleteForm, manager=IFormPrefixViewletsManager, weight=10) +@template_config(template='templates/wf-owner-warning.pt') +class SharedContentDeleteFormWarning(Viewlet): + """Shared content delete form warning message""" + + def __new__(cls, context, request, view, manager): + if request.principal.id in context.owner: + return None + return Viewlet.__new__(cls) + + +@viewlet_config(name='wf-delete-message', context=IWfSharedContent, layer=IPyAMSLayer, + view=SharedContentDeleteForm, manager=IWidgetsPrefixViewletsManager, weight=20) +@template_config(template='templates/wf-delete-message.pt') +class SharedContentDeleteFormMessage(Viewlet): + """Shared content delete form info message"""