Ejemplo n.º 1
0
class IWorkflowRequestUrgencyInfo(Interface):
    """Workflow request urgency info"""

    urgent_request = Bool(
        title=_("Urgent request?"),
        description=_("Please use this option only when really needed..."),
        required=True,
        default=False)
Ejemplo n.º 2
0
 def check_expiration_date(self):
     """Check expiration date"""
     if self.publication_expiration_date is not None:
         if self.publication_effective_date is None:
             raise Invalid(
                 _("Can't define publication end date without publication "
                   "start date!"))
         if self.publication_effective_date >= self.publication_expiration_date:
             raise Invalid(
                 _("Publication end date must be defined after publication "
                   "start date!"))
Ejemplo n.º 3
0
 def check_push_end_date(self):
     """Check push end date"""
     if self.push_end_date is not None:
         if self.publication_effective_date is None:
             raise Invalid(
                 _("Can't define push end date without publication start date!"
                   ))
         if self.publication_effective_date >= self.push_end_date:
             raise Invalid(
                 _("Push end date must be defined after publication start date!"
                   ))
         if self.publication_expiration_date is not None:
             if self.publication_expiration_date < self.push_end_date:
                 raise Invalid(
                     _("Push end date must be null or defined before publication "
                       "end date!"))
Ejemplo n.º 4
0
 def label(self):
     """Label getter"""
     translate = self.request.localizer.translate
     state = IWorkflowState(self.context)
     return translate(_("Version {id} - {state}")).format(
         id=state.version_id,
         state=translate(self.workflow.get_state_label(state.state)))
Ejemplo n.º 5
0
class IWorkflowManagedContent(IAttributeAnnotatable):
    """Workflow managed content"""

    content_class = Attribute("Content class")

    workflow_name = Choice(
        title=_("Workflow name"),
        description=_("Name of workflow utility managing this content"),
        required=True,
        vocabulary=WORKFLOWS_VOCABULARY)

    view_permission = Choice(
        title=_("View permission"),
        description=_("This permission will be required to display content"),
        vocabulary='PyAMS permissions',
        default=VIEW_PERMISSION,
        required=False)
Ejemplo n.º 6
0
class IWorkflowTransitionInfo(Interface):
    """Workflow transition info

    This interface is actually used to provide transition ID in
    workflow management forms.
    """

    transition_id = TextLine(title=_("Transition ID"), required=True)
Ejemplo n.º 7
0
class IWorkflowState(Interface):
    """Store state on workflow object.

    Defined as an adapter.
    """

    version_id = Int(title=_("Version ID"))

    state = TextLine(title=_("Version state"))

    state_date = Datetime(
        title=_("State date"),
        description=_("Date at which the current state was applied"))

    state_principal = PrincipalField(
        title=_("State principal"),
        description=_("ID of the principal which defined current "
                      "state"))

    state_urgency = Bool(title=_("Urgent request?"),
                         required=True,
                         default=False)

    history = List(title="Workflow states history",
                   value_type=Object(schema=IWorkflowStateHistoryItem))

    def get_first_state_date(self, states):
        """Get first date at which given state was set"""
Ejemplo n.º 8
0
 def publication(self):
     """Publication label used to display workflow publication state"""
     request = check_request()
     translate = request.localizer.translate
     sm = get_utility(ISecurityManager)  # pylint: disable=invalid-name
     return translate(_('{date} by {principal}')).format(
         date=format_datetime(tztime(
             IWorkflowPublicationInfo(self).publication_date),
                              request=request),
         principal=translate(sm.get_principal(self.publisher).title))
Ejemplo n.º 9
0
class WorkflowVersionHistoryDateColumn(I18nColumnMixin, DateColumn):
    """Workflow version history date column"""

    i18n_header = _("Date")

    attr_name = 'date'
    css_classes = {'td': 'nowrap'}
    weight = 1

    formatter = SH_DATETIME_FORMAT
Ejemplo n.º 10
0
class WorkflowVersionHistoryCommentColumn(I18nColumnMixin, GetAttrColumn):
    """Workflow version history comment column"""

    i18n_header = _("Comment")

    attr_name = 'comment'
    weight = 15

    def get_value(self, obj):  # pylint: disable=no-self-use
        """Comment column value getter"""
        return text_to_html(obj.comment or '--')
Ejemplo n.º 11
0
class WorkflowVersionHistoryView(TableAdminView):
    """Workflow version history view"""
    @property
    def title(self):
        """Title getter"""
        translate = self.request.localizer.translate  # pylint: disable=no-member
        return translate(_("Version {version} history")).format(
            version=IWorkflowState(self.context).version_id)  # pylint: disable=no-member

    table_class = WorkflowVersionHistoryTable
    table_label = _("History of this version")
Ejemplo n.º 12
0
class WorkflowVersionHistoryPrincipalColumn(I18nColumnMixin, GetAttrColumn):
    """Workflow version history principal column"""

    i18n_header = _("Modifier")

    attr_name = 'principal'
    weight = 10

    def get_value(self, obj):
        """Principal column value getter"""
        principal = get_principal(self.request, obj.principal)
        if isinstance(principal, MissingPrincipal):
            return '--'
        return principal.title
Ejemplo n.º 13
0
 def _get_viewlets(self):
     translate = self.request.localizer.translate
     for version in IWorkflowVersions(
             self.context).get_last_versions(count=0):
         state = IWorkflowState(version)
         item = MenuItem(version, self.request, self.view, self)
         item.label = translate(_("Version {id} - {state}")).format(
             id=state.version_id,
             state=translate(self.workflow.get_state_label(state.state)))
         item.icon_class = 'fas fa-arrow-right'
         if version is self.context:
             item.css_class = 'bg-primary text-white'
         item.href = absolute_url(version, self.request,
                                  'admin#{}'.format(self.request.view_name))
         yield 'version_{}'.format(state.version_id), item
Ejemplo n.º 14
0
def handle_cloned_object(event):
    """Add comment when an object is cloned"""
    request = check_request()
    translate = request.localizer.translate
    source_state = IWorkflowState(event.source)
    factory = get_object_factory(IWorkflowStateHistoryItem)
    if factory is not None:
        item = factory(
            date=datetime.utcnow(),
            principal=request.principal.id,
            comment=translate(
                _("Clone created from version {source} (in « {state} » "
                  "state)")).format(source=source_state.version_id,
                                    state=translate(
                                        IWorkflow(
                                            event.source).get_state_label(
                                                source_state.state))))
        target_state = IWorkflowState(event.object)
        target_state.history.clear()  # pylint: disable=no-member
        target_state.history.append(item)  # pylint: disable=no-member
Ejemplo n.º 15
0
class WorkflowTransitionsMenu(DropdownMenu):
    """Workflow transitions menu"""

    status = 'danger'
    css_class = 'btn-sm'
    label = _("Change status...")

    def _get_viewlets(self):
        viewlets = []
        content = get_parent(self.context, IWorkflowManagedContent)
        wf = get_utility(IWorkflow, name=content.workflow_name)  # pylint: disable=invalid-name
        if wf is None:
            return viewlets
        info = IWorkflowInfo(self.context)
        for transition_id in info.get_manual_transition_ids():
            transition = wf.get_transition_by_id(transition_id)
            menu = TransitionMenuItem(self.context, self.request, self.view,
                                      self, transition)
            viewlets.append((transition_id, menu))
        return sorted(viewlets, key=lambda x: x[1].weight)
Ejemplo n.º 16
0
class WorkflowVersionHistoryStateColumn(I18nColumnMixin, GetAttrColumn):
    """Workflow version history source column"""

    i18n_header = _("New state")

    attr_name = 'target_state'
    weight = 5

    def get_value(self, obj):
        """State column value getter"""
        state = super().get_value(obj)
        workflow = IWorkflow(self.context, None)
        if workflow is None:
            return state
        try:
            term = workflow.states.getTerm(state)
        except LookupError:
            return state or '--'
        else:
            translate = self.request.localizer.translate
            return translate(term.title)
Ejemplo n.º 17
0
class IWorkflowPublicationInfo(Interface):
    """Workflow content publication info

    This interface is used to specify publication dates applied on a
    given content.
    """

    publication_date = Datetime(
        title=_("Publication date"),
        description=_("Last date at which content was accepted for "
                      "publication"),
        required=False)

    publisher = PrincipalField(
        title=_("Publisher"),
        description=_("Name of the manager who published the document"),
        required=False)

    publication = TextLine(title=_("Publication"),
                           description=_("Last publication date and actor"),
                           required=False,
                           readonly=True)

    first_publication_date = Datetime(
        title=_("First publication date"),
        description=_("First date at which content was accepted "
                      "for publication"),
        required=False)

    publication_effective_date = Datetime(
        title=_("Publication start date"),
        description=_("Date from which content will be "
                      "visible"),
        required=False)

    push_end_date = Datetime(
        title=_("Push end date"),
        description=_("Some contents can be pushed by components to "
                      "front-office pages; if you set a date here, this "
                      "content will not be pushed anymore passed this "
                      "date, but will still be available via search engine "
                      "or direct links"),
        required=False)

    push_end_date_index = Attribute(
        "Push end date value used by catalog indexes")

    @invariant
    def check_push_end_date(self):
        """Check push end date"""
        if self.push_end_date is not None:
            if self.publication_effective_date is None:
                raise Invalid(
                    _("Can't define push end date without publication start date!"
                      ))
            if self.publication_effective_date >= self.push_end_date:
                raise Invalid(
                    _("Push end date must be defined after publication start date!"
                      ))
            if self.publication_expiration_date is not None:
                if self.publication_expiration_date < self.push_end_date:
                    raise Invalid(
                        _("Push end date must be null or defined before publication "
                          "end date!"))

    publication_expiration_date = Datetime(
        title=_("Publication end date"),
        description=_("Date past which content will not be "
                      "visible"),
        required=False)

    @invariant
    def check_expiration_date(self):
        """Check expiration date"""
        if self.publication_expiration_date is not None:
            if self.publication_effective_date is None:
                raise Invalid(
                    _("Can't define publication end date without publication "
                      "start date!"))
            if self.publication_effective_date >= self.publication_expiration_date:
                raise Invalid(
                    _("Publication end date must be defined after publication "
                      "start date!"))

    displayed_publication_date = Choice(
        title=_("Displayed publication date"),
        description=_("The matching date will be displayed in "
                      "front-office"),
        vocabulary=PYAMS_CONTENT_PUBLICATION_DATES,
        default=DISPLAY_FIRST_VERSION,
        required=True)

    visible_publication_date = Attribute("Visible publication date")

    def reset(self, complete=True):
        """Reset all publication info (used by clone features)

        If 'complete' argument is True, all date fields are reset; otherwise, push and
        publication end dates are preserved in new versions.
        """

    def is_published(self, check_parent=True):
        """Is the content published?"""

    def is_visible(self, request=None, check_parent=True):
        """Is the content visible?"""
Ejemplo n.º 18
0
class WorkflowVersionHistoryMenuItem(NavigationMenuItem):
    """Workflow history menu item"""

    label = _("Version history")
    icon_class = 'fas fa-history'
    href = '#version-history.html'
Ejemplo n.º 19
0
 def title(self):
     """Title getter"""
     translate = self.request.localizer.translate  # pylint: disable=no-member
     return translate(_("Version {version} history")).format(
         version=IWorkflowState(self.context).version_id)  # pylint: disable=no-member
Ejemplo n.º 20
0
class IWorkflowCommentInfo(Interface):
    """Workflow comment info"""

    comment = Text(title=_("Comment"),
                   description=_("Comment associated with this operation"),
                   required=False)
Ejemplo n.º 21
0
 def get_state_label(self, state):
     """Get label matching given state"""
     try:
         return self.states.getTerm(state).title
     except LookupError:
         return _('-- unknown --')
Ejemplo n.º 22
0
    view_permission = Choice(
        title=_("View permission"),
        description=_("This permission will be required to display content"),
        vocabulary='PyAMS permissions',
        default=VIEW_PERMISSION,
        required=False)


DISPLAY_FIRST_VERSION = 'first'
"""Displayed publication date is the first publication date"""

DISPLAY_CURRENT_VERSION = 'current'
"""Displayed publication date is the publication date of the current version"""

VERSION_DISPLAY = {
    DISPLAY_FIRST_VERSION: _("Display first version date"),
    DISPLAY_CURRENT_VERSION: _("Display current version date")
}

VERSION_DISPLAY_VOCABULARY = SimpleVocabulary(
    [SimpleTerm(v, title=t) for v, t in VERSION_DISPLAY.items()])

PYAMS_CONTENT_PUBLICATION_DATES = 'PyAMS_workflow.content.publication_date'
"""Publication dates vocabulary name"""

WORKFLOW_CONTENT_KEY = 'pyams_workflow.content_info'
"""Annotations key used to store content publication information"""


class IWorkflowPublicationInfo(Interface):
    """Workflow content publication info