199 lines
6.5 KiB
Text
199 lines
6.5 KiB
Text
===============================================================
|
|
loops - Linked Objects for Organization and Processing Services
|
|
===============================================================
|
|
|
|
>>> from zope import component
|
|
>>> from zope.traversing.api import getName
|
|
|
|
First we set up a loops site with basic and example concepts and resources.
|
|
|
|
>>> from zope.app.testing.setup import placefulSetUp, placefulTearDown
|
|
>>> site = placefulSetUp(True)
|
|
|
|
>>> from loops.organize.setup import SetupManager
|
|
>>> component.provideAdapter(SetupManager, name='organize')
|
|
>>> from loops.expert.testsetup import TestSite
|
|
>>> t = TestSite(site)
|
|
>>> concepts, resources, views = t.setup()
|
|
>>> loopsRoot = site['loops']
|
|
|
|
|
|
Stateful Objects
|
|
================
|
|
|
|
A simple publishing workflow
|
|
----------------------------
|
|
|
|
Let's start with registering the states definitions and adapters needed.
|
|
The states definition (aka 'workflow') is registered as a utility; for
|
|
making an object statful we'll use an adapter.
|
|
|
|
>>> from cybertools.stateful.interfaces import IStatesDefinition, IStateful
|
|
>>> from cybertools.stateful.publishing import simplePublishing
|
|
>>> component.provideUtility(simplePublishing(), name='simple_publishing')
|
|
|
|
>>> from loops.organize.stateful.base import SimplePublishable
|
|
>>> component.provideAdapter(SimplePublishable, name='simple_publishing')
|
|
|
|
We may now take a document and adapt it to IStateful so that we may
|
|
check the document's state and perform transitions to other states.
|
|
|
|
>>> from loops.resource import Resource
|
|
>>> from loops.setup import addAndConfigureObject
|
|
>>> tText = concepts['textdocument']
|
|
>>> doc01 = resources['doc01.txt'] = addAndConfigureObject(resources,
|
|
... Resource, 'doc01.txt', conceptType=tText)
|
|
>>> statefulDoc01 = component.getAdapter(doc01, IStateful,
|
|
... name='simple_publishing')
|
|
|
|
>>> statefulDoc01.state
|
|
'draft'
|
|
|
|
>>> statefulDoc01.doTransition('publish')
|
|
>>> statefulDoc01.state
|
|
'published'
|
|
|
|
Let's check if the state is really stored in the underlying object and
|
|
not just kept in the adapter.
|
|
|
|
>>> statefulDoc01_x = component.getAdapter(doc01, IStateful,
|
|
... name='simple_publishing')
|
|
|
|
>>> statefulDoc01.state
|
|
'published'
|
|
|
|
|
|
Controlling classification quality
|
|
----------------------------------
|
|
|
|
We again first have to register states definitions and adapter classes.
|
|
|
|
>>> from loops.organize.stateful.quality import classificationQuality
|
|
>>> component.provideUtility(classificationQuality(),
|
|
... name='classification_quality')
|
|
>>> from loops.organize.stateful.quality import ClassificationQualityCheckable
|
|
>>> component.provideAdapter(ClassificationQualityCheckable,
|
|
... name='classification_quality')
|
|
>>> from loops.organize.stateful.quality import assign, deassign
|
|
>>> component.provideHandler(assign)
|
|
>>> component.provideHandler(deassign)
|
|
|
|
Now we can get a stateful adapter for a resource.
|
|
|
|
>>> qcheckedDoc01 = component.getAdapter(doc01, IStateful,
|
|
... name='classification_quality')
|
|
>>> qcheckedDoc01.state
|
|
'new'
|
|
|
|
Let's create two customer objects to be used for classification of resources
|
|
later.
|
|
|
|
>>> tCustomer = concepts['customer']
|
|
>>> from loops.concept import Concept
|
|
>>> c01 = addAndConfigureObject(concepts, Concept, 'c01', conceptType=tCustomer,
|
|
... title='im publishing')
|
|
>>> c02 = addAndConfigureObject(concepts, Concept, 'c02', conceptType=tCustomer,
|
|
... title='DocFive')
|
|
|
|
When we change the concept assignments of the resource - i.e. its classification
|
|
- the classification quality state changes automatically
|
|
|
|
>>> c01.assignResource(doc01)
|
|
>>> qcheckedDoc01 = component.getAdapter(doc01, IStateful,
|
|
... name='classification_quality')
|
|
>>> qcheckedDoc01.state
|
|
'classified'
|
|
|
|
>>> c02.assignResource(doc01)
|
|
>>> qcheckedDoc01.state
|
|
'classified'
|
|
|
|
In order to mark the classification as "verified" (i.e. quality-checked)
|
|
we have to perform the corresponding transition explicitly.
|
|
|
|
>>> qcheckedDoc01.doTransition('verify')
|
|
>>> qcheckedDoc01.state
|
|
'verified'
|
|
|
|
Upon later changes of classification the "verified" state gets lost again.
|
|
|
|
>>> c02.deassignResource(doc01)
|
|
>>> qcheckedDoc01.state
|
|
'classified'
|
|
|
|
>>> c01.deassignResource(doc01)
|
|
>>> qcheckedDoc01.state
|
|
'unclassified'
|
|
|
|
Changing states when editing
|
|
----------------------------
|
|
|
|
We first need a node that provides us access to the resource as its target
|
|
|
|
>>> from loops.view import Node
|
|
>>> node = addAndConfigureObject(views, Node, 'node', target=doc01)
|
|
|
|
>>> from loops.browser.form import EditObjectForm, EditObject
|
|
>>> from zope.publisher.browser import TestRequest
|
|
|
|
The form view gives us access to the states of the object.
|
|
|
|
>>> loopsRoot.options = ['organize.stateful.resource:'
|
|
... 'classification_quality,simple_publishing']
|
|
|
|
>>> form = EditObjectForm(node, TestRequest())
|
|
>>> for st in form.states:
|
|
... sto = st.getStateObject()
|
|
... transitions = st.getAvailableTransitions()
|
|
... userTrans = st.getAvailableTransitionsForUser()
|
|
... print st.statesDefinition, sto.title, [t.title for t in transitions],
|
|
... print [t.title for t in userTrans]
|
|
classification_quality unclassified ['classify', 'verify'] ['verify']
|
|
simple_publishing published ['retract', 'archive'] ['retract', 'archive']
|
|
|
|
Let's now update the form.
|
|
|
|
>>> input = {'state.classification_quality': 'verify'}
|
|
>>> proc = EditObject(form, TestRequest(form=input))
|
|
>>> proc.update()
|
|
False
|
|
|
|
>>> qcheckedDoc01.state
|
|
'verified'
|
|
|
|
Querying objects by state
|
|
-------------------------
|
|
|
|
>>> stateQuery = addAndConfigureObject(concepts, Concept, 'state_query',
|
|
... conceptType=concepts['query'], viewName='select_state.html')
|
|
>>> from loops.organize.stateful.browser import StateQuery
|
|
>>> view = StateQuery(stateQuery, TestRequest())
|
|
|
|
>>> view.rcStatesDefinitions
|
|
{'concept': [], 'resource': [...StatesDefinition..., ...StatesDefinition...]}
|
|
|
|
>>> input = {'state.resource.classification_quality': ['verified']}
|
|
>>> view = StateQuery(stateQuery, TestRequest(form=input))
|
|
>>> view.selectedStates
|
|
{'state.resource.classification_quality': ['verified']}
|
|
|
|
>>> list(view.results)
|
|
[<...>]
|
|
|
|
|
|
Task States
|
|
===========
|
|
|
|
>>> from loops.organize.stateful.task import taskStates, publishableTask
|
|
|
|
|
|
Contact States
|
|
===========
|
|
|
|
>>> from loops.organize.stateful.contact import contactStates
|
|
|
|
|
|
Fin de partie
|
|
=============
|
|
|
|
>>> placefulTearDown()
|