Exemplo n.º 1
0
 def _task_item_info(ref, type_):
     ob = ref.to_object
     return {
         'title':
         ob.title,
         'url':
         ob.absolute_url(),
         'edit_url':
         addTokenToUrl(ob.absolute_url() + '/@@edit'),
         'state':
         plone.api.content.get_state(ob),
         'intid':
         ref.to_id,
         'transition_date':
         utils.get_pub_date(ob, type_),
         'transition':
         getattr(ob, type_ + '_transition', None)
         or _('label_no_transition', 'No transition'),
         'is_task':
         utils.is_task(ob),
         'is_wfeff':
         utils.is_wfeffectiverange(ob),
     }
Exemplo n.º 2
0
    def items(self, type_):
        intids = getUtility(IIntIds)
        wftool = plone.api.portal.get_tool('portal_workflow')

        query = {'portal_type': 'WFTask' + type_.capitalize()}
        ret_tasks = plone.api.content.find(**query)
        ret_tasks = [it.getObject() for it in ret_tasks]

        # Get all task_items ids for IWFEffectiveRange object filtering.
        task_items_ids = []
        for task in ret_tasks:
            task_items_ids += [it.to_id for it in task.task_items]

        query = {'has_' + type_ + '_transition': True}
        ret_obj = plone.api.content.find(**query)

        # Filter all IWFEffectiveRange objects, which are already related in an
        # IWFTask object.
        # Also, get the object as we need it anyways.
        ret_obj = [it.getObject() for it in ret_obj]
        ret_obj = [
            it for it in ret_obj if utils.is_wfeffectiverange(it)
            and intids.getId(it) not in task_items_ids
        ]

        def _datecomp(x, y):
            dat_x = getattr(x, 'task_date', utils.get_pub_date(x, type_))
            dat_y = getattr(y, 'task_date', utils.get_pub_date(y, type_))
            _cmp = cmp(dat_x, dat_y) if dat_x and dat_y else -1
            return _cmp

        # Sort for date
        ret = sorted(ret_tasks + ret_obj, _datecomp)

        def _task_item_info(ref, type_):
            ob = ref.to_object
            return {
                'title':
                ob.title,
                'url':
                ob.absolute_url(),
                'edit_url':
                addTokenToUrl(ob.absolute_url() + '/@@edit'),
                'state':
                plone.api.content.get_state(ob),
                'intid':
                ref.to_id,
                'transition_date':
                utils.get_pub_date(ob, type_),
                'transition':
                getattr(ob, type_ + '_transition', None)
                or _('label_no_transition', 'No transition'),
                'is_task':
                utils.is_task(ob),
                'is_wfeff':
                utils.is_wfeffectiverange(ob),
            }

        def _common_transitions(item):
            ret = []

            if utils.is_task(item):
                # Get the common transition for all referenced objects.
                task_items = getattr(item, 'task_items', [])
                transitions = []
                for ref in task_items:
                    ob = ref.to_object
                    _trans = [(it['id'], it['name'])
                              for it in wftool.getTransitionsFor(ob)]
                    transitions.append(set(_trans))

                ret = None
                for transition in transitions:
                    if ret is None:
                        ret = transition
                        continue
                    ret = ret.intersection(transition)

                ret = list(ret) if ret else []

            else:
                # Get all current transitions for the given object
                transitions = None
                if type_ == 'effective':
                    transitions = EffectiveTransitionSource()
                else:
                    transitions = ExpiresTransitionSource()
                vocab = transitions(item)

                ret = [(it.token, it.title) for it in vocab]

            return ret

        ret = [{
            'ob':
            it,
            'title':
            it.title,
            'url':
            it.absolute_url(),
            'delete_url':
            addTokenToUrl(it.absolute_url() + '/@@delete_confirmation'),
            'edit_url':
            addTokenToUrl(it.absolute_url() + '/@@edit'),
            'transition_date':
            getattr(it, 'task_date', None)
            if utils.is_task(it) else utils.get_pub_date(it, type_),
            'transition':
            (getattr(it, 'task_transition', None) if utils.is_task(it) else
             getattr(it, type_ + '_transition', None))
            or _('label_no_transition', 'No transition'),
            'state':
            plone.api.content.get_state(it),
            'uuid':
            IUUID(it),
            'is_task':
            utils.is_task(it),
            'is_wfeff':
            utils.is_wfeffectiverange(it),
            'task_items': [
                _task_item_info(ref, type_)
                for ref in getattr(it, 'task_items', [])
            ],
            'common_transitions':
            _common_transitions(it)
        } for it in ret]

        return ret
Exemplo n.º 3
0
    def __call__(self, *args, **kwargs):

        form = self.request.form
        uuid = form.get('uuid', None)
        wftype = form.get('wftype', None)

        infos = []
        warnings = []

        if uuid and wftype and form.get('run_task', None):
            task = uuidToObject(uuid)

            infos, warnings = run_task(task, include_wfer=True, wftype=wftype)

        elif uuid:

            items = [uuidToObject(uuid)]

            if utils.is_task(items[0]):
                # Extend the list of items by all IWFEffectiveRange objects for
                # multi-editing those.
                items += [
                    it.to_object for it in getattr(items[0], 'task_items', [])
                    if utils.is_wfeffectiverange(it.to_object)
                ]

            transition_date = form.get('transition_date', None)
            transition = form.get('transition', None)
            ob_remove = form.get('ob_remove', None)

            for item in items:

                is_task = utils.is_task(item)
                is_wfeffectiverange = utils.is_wfeffectiverange(item)

                item_url = item.absolute_url()

                if transition_date is not None:
                    # Parse a Python datetime from a string using Zope DateTime
                    # If set, but empty clear the field with None.
                    transition_date = DateTime(transition_date).asdatetime(
                    ) if transition_date else None  # noqa
                    if is_task:
                        item.task_date = transition_date

                        infos.append(
                            _(
                                'info_task_set_transition_date',
                                default=
                                u'Set transition date ${transition_date} on task ${url}.',  # noqa
                                mapping={
                                    'transition_date': transition_date,
                                    'url': item_url
                                }))

                    elif is_wfeffectiverange and wftype:
                        utils.set_pub_date(item, wftype, transition_date)
                        infos.append(
                            _(
                                'info_wf_set_transition_date',
                                default=
                                u'Set ${wftype} transition date ${transition_date} on object ${url}.',  # noqa
                                mapping={
                                    'wftype': wftype,
                                    'transition_date': transition_date,
                                    'url': item_url
                                }))

                if transition is not None:
                    if is_task:
                        item.task_transition = transition

                        infos.append(
                            _(
                                'info_task_set_transition',
                                default=
                                u'Set transition "${transition}" on task ${url}.',  # noqa
                                mapping={
                                    'transition': transition,
                                    'url': item_url
                                }))

                    elif is_wfeffectiverange and wftype:
                        setattr(item, wftype + '_transition', transition)

                        infos.append(
                            _(
                                'info_wf_set_transition',
                                default=
                                u'Set ${wftype} transition "${transition}" on object ${url}.',  # noqa
                                mapping={
                                    'wftype': wftype,
                                    'transition': transition,
                                    'url': item_url
                                }))

                if is_task and ob_remove:
                    # Remove the referenced item from the task
                    item.task_items = [
                        it for it in item.task_items
                        if it.to_id != int(ob_remove)
                    ]
                    intids = getUtility(IIntIds)
                    ob = intids.getObject(int(ob_remove))

                    infos.append(
                        _(
                            'info_task_object_removed',
                            default=
                            u'Removed referenced object ${obj_url} from task "${task_title}".',  # noqa
                            mapping={
                                'ob_url': ob.absolute_url(),
                                'task_title': item.title
                            }))

                elif is_wfeffectiverange and ob_remove == uuid and wftype:
                    # Clear the IWFEffectiveRange date and transition
                    utils.set_pub_date(item, wftype, None)
                    setattr(item, wftype + '_transition', None)

                    infos.append(
                        _(
                            'info_wf_cleared',
                            default=
                            u'Cleared the ${wftype} date and transition from ${url} and removed it from this list.',  # noqa
                            mapping={
                                'wftype': wftype,
                                'url': item_url
                            }))

                item.reindexObject()

        messages = IStatusMessage(self.request)
        for msg in infos:
            messages.add(msg, type=u"info")
        for msg in warnings:
            messages.add(msg, type=u"warning")

        return super(WFTaskOverviewView, self).__call__(*args, **kwargs)
def has_effective_transition(context):
    context = aq_base(context)
    if not utils.is_wfeffectiverange(context):
        raise AttributeError
    return bool(getattr(context, 'effective_transition', False))
Exemplo n.º 5
0
def run_task(task, include_wfer=False, wftype=None):
    """Run a IWFTask.
    """
    infos = []
    warnings = []

    if wftype:
        # If wftype is given - say that a IWFEffectiveRange "task" is run
        # manually - one of the following wftypes must be given.
        assert wftype in ('effective', 'expires')

    items = []
    is_task = utils.is_task(task)
    if is_task:
        items = [it.to_object for it in getattr(task, 'task_items', [])]
    elif utils.is_wfeffectiverange(task):
        items = [task]

    for obj in items:
        is_wfer = utils.is_wfeffectiverange(obj)

        if not obj:
            # Invalid
            continue
        if not include_wfer and is_wfer:
            # WFEffectiveRange objects referenced by a task will get
            # multi-edited by the task and run individually via the
            # code above.
            # Do not run them again.
            continue

        transition = None
        if is_task:
            transition = getattr(task, 'task_transition', None)
        elif is_wfer and wftype:
            transition = getattr(
                IWFEffectiveRange(obj, None),
                wftype + '_transition',
                None
            )
        if not transition:
            # Incomplete
            continue

        try:
            if is_wfer and include_wfer:
                obj._v_wfeffectiverange_ignore = True
            plone.api.content.transition(
                obj=obj,
                transition=transition
            )
            if is_wfer and include_wfer:
                obj._v_wfeffectiverange_ignore = True
                if wftype == 'effective'\
                        or task.portal_type == 'WFTaskEffective':
                    obj.effective_transition = None
                else:
                    obj.expires_transition = None
            obj.reindexObject()
            infos.append(u'Task "{0}" with transition "{1}" successfully run for object {2}.'.format(  # noqa
                task.title,
                transition,
                obj.absolute_url()
            ))
            logger.info(infos[-1])

        except plone.api.exc.InvalidParameterError:
            warnings.append(u'Could not apply task "{0}" with transition {1} for object {2}.'.format(  # noqa
                task.title,
                transition,
                obj.absolute_url()
            ))
            logger.warn(warnings[-1])

    if IWFTask.providedBy(task):
        # After running, clear the task transition and date.
        IWFTask(task).task_transition = None
        IWFTask(task).task_date = None

    annotations = IAnnotations(task)
    tasklogger = annotations.get(WFTASK_LOGGER_KEY, {})
    tasklogger[datetime.now().isoformat()] = {
        'infos': infos,
        'warnings': warnings
    }
    annotations[WFTASK_LOGGER_KEY] = tasklogger

    task.reindexObject()

    return infos, warnings
Exemplo n.º 6
0
    def __call__(self):
        alsoProvides(self.request, IDisableCSRFProtection)

        infos = []
        warnings = []

        # for effective transition
        query = {
            'effective': {'query': datetime.now(), 'range': 'max'},
            'has_effective_transition': True,
            # 'object_provides': IWFEffectiveRange.__identifier__
        }
        for brain in plone.api.content.find(**query):
            obj = brain.getObject()
            if utils.is_wfeffectiverange(obj) and getattr(obj, 'effective_transition', None):  # noqa
                new_transition = obj.effective_transition
                obj.effective_transition = None
                obj._v_wfeffectiverange_ignore = True
                try:
                    plone.api.content.transition(
                        obj=obj, transition=new_transition
                    )
                    infos.append(u'Effective transition "{0}" successfully run for object {1}.'.format(  # noqa
                        new_transition,
                        obj.absolute_url()
                    ))
                    logger.info(infos[-1])
                except plone.api.exc.InvalidParameterError:
                    warnings.append(u'Error on running effective transition "{0}" on object {1}'.format(  # noqa
                        new_transition,
                        obj.absolute_url()
                    ))
                    logger.warn(warnings[-1])
                obj._v_wfeffectiverange_ignore = False
                obj.reindexObject()
                logger.info(
                    'autotransition "effective" for {0}'.format(
                        obj.absolute_url()
                    )
                )

        # for expires transition
        query = {
            'expires': {'query': datetime.now(), 'range': 'max'},
            'has_expires_transition': True,
            # 'object_provides': IWFEffectiveRange.__identifier__
        }
        for brain in plone.api.content.find(**query):
            obj = brain.getObject()
            if utils.is_wfeffectiverange(obj) and getattr(obj, 'expires_transition', None):  # noqa
                new_transition = obj.expires_transition
                obj.expires_transition = None
                obj._v_wfeffectiverange_ignore = True
                try:
                    plone.api.content.transition(
                        obj=obj, transition=new_transition
                    )
                    infos.append(u'Expires transition "{0}" successfully run for object {1}.'.format(  # noqa
                        new_transition,
                        obj.absolute_url()
                    ))
                    logger.info(infos[-1])
                except plone.api.exc.InvalidParameterError:
                    warnings.append(u'Error on running expires transition "{0}" on object {1}'.format(  # noqa
                        new_transition,
                        obj.absolute_url()
                    ))
                    logger.warn(warnings[-1])
                obj._v_wfeffectiverange_ignore = False
                obj.reindexObject()
                logger.info(
                    'autotransition "expires" for {0}'.format(
                        obj.absolute_url())
                )

        # Run Tasks
        query = {
            'start': {'query': datetime.now(), 'range': 'max'},
            'object_provides': IWFTask.__identifier__
        }

        for brain in plone.api.content.find(**query):
            task = brain.getObject()
            _infos, _warnings = run_task(task, include_wfer=False)
            infos += _infos
            warnings += _warnings

        transaction.commit()

        return u'''
Task infos
----------
{0}

Task warnings
-------------
{1}
'''.format(
            u'\n'.join(infos),
            u'\n'.join(warnings)
        )