provide State query and fix bug in state event notification
git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@2561 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
parent
883656bd1e
commit
45efbd3c6f
5 changed files with 71 additions and 24 deletions
|
@ -27,7 +27,7 @@ configuration):
|
|||
>>> concepts, resources, views = t.setup()
|
||||
|
||||
>>> len(concepts) + len(resources)
|
||||
36
|
||||
32
|
||||
|
||||
>>> loopsRoot = site['loops']
|
||||
|
||||
|
@ -47,11 +47,11 @@ Type- and text-based queries
|
|||
>>> from loops.expert import query
|
||||
>>> qu = query.Title('ty*')
|
||||
>>> list(qu.apply())
|
||||
[0, 1, 47]
|
||||
[0, 1, 45]
|
||||
|
||||
>>> qu = query.Type('loops:*')
|
||||
>>> len(list(qu.apply()))
|
||||
36
|
||||
32
|
||||
|
||||
>>> qu = query.Type('loops:concept:predicate')
|
||||
>>> len(list(qu.apply()))
|
||||
|
@ -61,6 +61,53 @@ Type- and text-based queries
|
|||
>>> list(qu.apply())
|
||||
[1]
|
||||
|
||||
State-based queries
|
||||
-------------------
|
||||
|
||||
>>> qu = query.State('loops.classification_quality', 'new')
|
||||
>>> list(qu.apply())
|
||||
[]
|
||||
|
||||
>>> from cybertools.stateful.publishing import simplePublishing
|
||||
>>> component.provideUtility(simplePublishing(), name='loops.simple_publishing')
|
||||
>>> from loops.organize.stateful.base import SimplePublishable
|
||||
>>> component.provideAdapter(SimplePublishable, name='loops.simple_publishing')
|
||||
>>> from loops.organize.stateful.quality import classificationQuality
|
||||
>>> component.provideUtility(classificationQuality(),
|
||||
... name='loops.classification_quality')
|
||||
>>> from loops.organize.stateful.quality import ClassificationQualityCheckable
|
||||
>>> component.provideAdapter(ClassificationQualityCheckable,
|
||||
... name='loops.classification_quality')
|
||||
|
||||
>>> loopsRoot.options = ['organize.stateful.resource:'
|
||||
... 'loops.classification_quality,loops.simple_publishing']
|
||||
|
||||
>>> from zope.app.catalog.interfaces import ICatalog
|
||||
>>> catalog = component.getUtility(ICatalog)
|
||||
>>> from loops import util
|
||||
|
||||
>>> for r in resources.values():
|
||||
... catalog.index_doc(int(util.getUidForObject(r)), r)
|
||||
|
||||
>>> qu = query.State('loops.classification_quality', 'new')
|
||||
>>> list(qu.apply())
|
||||
[23, 25, 27]
|
||||
|
||||
>>> from cybertools.stateful.interfaces import IStateful
|
||||
>>> statefulD001 = component.getAdapter(resources['d001.txt'], IStateful,
|
||||
... name='loops.classification_quality')
|
||||
|
||||
>>> from loops.organize.stateful.base import handleTransition
|
||||
>>> component.provideHandler(handleTransition)
|
||||
|
||||
>>> statefulD001.doTransition('classify')
|
||||
>>> list(qu.apply())
|
||||
[25, 27]
|
||||
|
||||
>>> qu = query.State('loops.classification_quality', 'classified')
|
||||
>>> list(qu.apply())
|
||||
[23]
|
||||
|
||||
Relationship-based queries
|
||||
--------------------------
|
||||
|
||||
|
@ -69,10 +116,10 @@ relations to other objects the expert package provides methods
|
|||
for selecting and filtering related objects using our basic querying
|
||||
syntax (that in turn is based on hurry.query).
|
||||
|
||||
>>> stateNew = concepts['new']
|
||||
>>> qu = query.Resources(stateNew)
|
||||
>>> cust1 = concepts['cust1']
|
||||
>>> qu = query.Resources(cust1)
|
||||
>>> list(qu.apply())
|
||||
[25, 27]
|
||||
[23, 27]
|
||||
|
||||
Getting objects
|
||||
---------------
|
||||
|
@ -136,7 +183,7 @@ Organizing Queries and Filters with Query Instances
|
|||
A query instance consists of
|
||||
|
||||
- a base query (a composition of terms)
|
||||
- one or more query filter that will be joined with the base query
|
||||
- one or more query filters that will be joined with the base query
|
||||
- a result filter that will be applied to the result set of the
|
||||
preceding steps
|
||||
|
||||
|
|
|
@ -23,8 +23,8 @@ $Id$
|
|||
"""
|
||||
|
||||
from BTrees.IIBTree import IITreeSet
|
||||
from BTrees.IFBTree import IFBTree, IFTreeSet
|
||||
from BTrees.IOBTree import IOBTree
|
||||
from BTrees.IFBTree import IFBucket, IFBTree, IFTreeSet
|
||||
from BTrees.IOBTree import IOBucket, IOBTree
|
||||
from zope import interface, component
|
||||
from zope.app.intid.interfaces import IIntIds
|
||||
from zope.component import adapts
|
||||
|
@ -33,6 +33,7 @@ from zope.cachedescriptors.property import Lazy
|
|||
|
||||
from cybertools.catalog.query import Term, Eq, Between
|
||||
from cybertools.catalog.query import Text as BaseText
|
||||
from cybertools.catalog.query import AnyOf
|
||||
from loops.expert.interfaces import IQuery
|
||||
from loops.security.common import canListObject
|
||||
from loops import util
|
||||
|
@ -40,8 +41,11 @@ from loops import util
|
|||
titleIndex = ('', 'loops_title')
|
||||
textIndex = ('', 'loops_text')
|
||||
typeIndex = ('', 'loops_type')
|
||||
stateIndex = ('', 'loops_state')
|
||||
|
||||
|
||||
# standard text/field/keyword index queries
|
||||
|
||||
@implementer(IQuery)
|
||||
def Title(value):
|
||||
return BaseText(titleIndex, value)
|
||||
|
@ -58,6 +62,12 @@ def Type(value):
|
|||
return Between(typeIndex, v1, v2)
|
||||
return Eq(typeIndex, value)
|
||||
|
||||
@implementer(IQuery)
|
||||
def State(statesDefinition, value):
|
||||
return AnyOf(stateIndex, ':'.join((statesDefinition, value)))
|
||||
|
||||
|
||||
# concept map queries
|
||||
|
||||
class ConceptMapTerm(Term):
|
||||
|
||||
|
@ -105,6 +115,8 @@ class Children(ConceptMapTerm):
|
|||
self.getRecursive(c, result)
|
||||
|
||||
|
||||
# utility functions
|
||||
|
||||
def getObjects(uids, root=None, checkPermission=canListObject):
|
||||
intIds = component.getUtility(IIntIds)
|
||||
for uid in uids:
|
||||
|
|
|
@ -44,8 +44,6 @@ class TestSite(BaseTestSite):
|
|||
type=tType)
|
||||
tCustomer = addObject(concepts, Concept, 'customer', title=u'Customer',
|
||||
type=tType)
|
||||
tState = addObject(concepts, Concept, 'state', title=u'State',
|
||||
type=tType)
|
||||
tDocumentType = addObject(concepts, Concept, 'documenttype',
|
||||
title=u'Document Type', type=tType)
|
||||
dGeneral = addObject(concepts, Concept, 'general',
|
||||
|
@ -53,7 +51,6 @@ class TestSite(BaseTestSite):
|
|||
dProjects = addObject(concepts, Concept, 'projects',
|
||||
title=u'Project Domain', type=tDomain)
|
||||
tCountry.assignParent(dGeneral)
|
||||
tState.assignParent(dGeneral)
|
||||
tCustomer.assignParent(dProjects)
|
||||
tDocumentType.assignParent(dProjects)
|
||||
|
||||
|
@ -70,12 +67,6 @@ class TestSite(BaseTestSite):
|
|||
cust1.assignParent(countryDe)
|
||||
cust2.assignParent(countryDe)
|
||||
cust3.assignParent(countryUs)
|
||||
stateNew = addObject(concepts, Concept, 'new',
|
||||
title=u'New', type=tState)
|
||||
stateReleased = addObject(concepts, Concept, 'released',
|
||||
title=u'Released', type=tState)
|
||||
stateObsolete = addObject(concepts, Concept, 'obsolete',
|
||||
title=u'Obsolete', type=tState)
|
||||
dtStudy = addObject(concepts, Concept, 'dt_study',
|
||||
title=u'Study', type=tDocumentType)
|
||||
dtNote = addObject(concepts, Concept, 'dt_note',
|
||||
|
@ -86,15 +77,12 @@ class TestSite(BaseTestSite):
|
|||
|
||||
d001 = resources['d001.txt']
|
||||
d001.assignConcept(cust1)
|
||||
d001.assignConcept(stateReleased)
|
||||
d001.assignConcept(dtNote)
|
||||
d002 = resources['d002.txt']
|
||||
d002.assignConcept(cust3)
|
||||
d002.assignConcept(stateNew)
|
||||
d002.assignConcept(dtNote)
|
||||
d003 = resources['d003.txt']
|
||||
d003.assignConcept(cust1)
|
||||
d003.assignConcept(stateNew)
|
||||
d003.assignConcept(dtStudy)
|
||||
|
||||
catalog = component.getUtility(ICatalog)
|
||||
|
|
|
@ -95,7 +95,7 @@ later.
|
|||
... title='DocFive')
|
||||
|
||||
When we change the concept assignments of the resource - i.e. its classification
|
||||
- the classification quality state changes automaticalls
|
||||
- the classification quality state changes automatically
|
||||
|
||||
>>> c01.assignResource(doc01)
|
||||
>>> qcheckedDoc01 = component.getAdapter(doc01, IStateful,
|
||||
|
|
|
@ -61,9 +61,9 @@ class StatefulResourceIndexInfo(IndexInfo):
|
|||
|
||||
|
||||
@adapter(IResource, ITransitionEvent)
|
||||
def handleTransition(self, obj, event):
|
||||
def handleTransition(obj, event):
|
||||
previous = event.previousState
|
||||
next = event.transition.targetState
|
||||
if next != previous:
|
||||
cat = getUtility(ICatalog)
|
||||
cat = component.getUtility(ICatalog)
|
||||
cat.index_doc(int(util.getUidForObject(obj)), obj)
|
||||
|
|
Loading…
Add table
Reference in a new issue