[Checkins] SVN: Products.DCWorkflow/branches/jens_worklistcatalogmatches_tal/Products/DCWorkflow/ - Worklist catalog variable matches can be expressions or formatted strings

Jens Vagelpohl jens at dataflake.org
Tue May 19 07:35:35 EDT 2009


Log message for revision 100124:
  - Worklist catalog variable matches can be expressions or formatted strings
  

Changed:
  U   Products.DCWorkflow/branches/jens_worklistcatalogmatches_tal/Products/DCWorkflow/DCWorkflow.py
  U   Products.DCWorkflow/branches/jens_worklistcatalogmatches_tal/Products/DCWorkflow/Worklists.py
  U   Products.DCWorkflow/branches/jens_worklistcatalogmatches_tal/Products/DCWorkflow/dtml/worklist_properties.dtml
  A   Products.DCWorkflow/branches/jens_worklistcatalogmatches_tal/Products/DCWorkflow/tests/test_Worklist.py

-=-
Modified: Products.DCWorkflow/branches/jens_worklistcatalogmatches_tal/Products/DCWorkflow/DCWorkflow.py
===================================================================
--- Products.DCWorkflow/branches/jens_worklistcatalogmatches_tal/Products/DCWorkflow/DCWorkflow.py	2009-05-19 11:31:33 UTC (rev 100123)
+++ Products.DCWorkflow/branches/jens_worklistcatalogmatches_tal/Products/DCWorkflow/DCWorkflow.py	2009-05-19 11:35:34 UTC (rev 100124)
@@ -226,12 +226,7 @@
                     var_match_keys = qdef.getVarMatchKeys()
                     if var_match_keys:
                         # Check the catalog for items in the worklist.
-                        catalog = getToolByName(self, 'portal_catalog')
-                        kw = {}
-                        for k in var_match_keys:
-                            v = qdef.getVarMatch(k)
-                            kw[k] = [ x % info for x in v ]
-                        searchres = catalog.searchResults(**kw)
+                        searchres = qdef.search(info)
                         if not searchres:
                             continue
                     if fmt_data is None:

Modified: Products.DCWorkflow/branches/jens_worklistcatalogmatches_tal/Products/DCWorkflow/Worklists.py
===================================================================
--- Products.DCWorkflow/branches/jens_worklistcatalogmatches_tal/Products/DCWorkflow/Worklists.py	2009-05-19 11:31:33 UTC (rev 100123)
+++ Products.DCWorkflow/branches/jens_worklistcatalogmatches_tal/Products/DCWorkflow/Worklists.py	2009-05-19 11:35:34 UTC (rev 100124)
@@ -15,6 +15,8 @@
 $Id$
 """
 
+import re
+
 from AccessControl.SecurityInfo import ClassSecurityInfo
 from Acquisition import aq_inner
 from Acquisition import aq_parent
@@ -23,12 +25,18 @@
 from OFS.SimpleItem import SimpleItem
 from Persistence import PersistentMapping
 
+from Products.CMFCore.utils import getToolByName
 from Products.DCWorkflow.ContainerTab import ContainerTab
+from Products.DCWorkflow.Expression import createExprContext
+from Products.DCWorkflow.Expression import Expression
+from Products.DCWorkflow.Expression import StateChangeInfo
 from Products.DCWorkflow.Guard import Guard
 from Products.DCWorkflow.permissions import ManagePortal
 from Products.DCWorkflow.utils import _dtmldir
 
+tales_re = re.compile(r'(\w+:)?(.*)')
 
+
 class WorklistDefinition(SimpleItem):
     """Worklist definiton"""
 
@@ -85,7 +93,7 @@
     def getVarMatch(self, id):
         if self.var_matches:
             matches = self.var_matches.get(id, ())
-            if not isinstance(matches, tuple):
+            if not isinstance(matches, (tuple, Expression)):
                 # Old version, convert it.
                 matches = (matches,)
                 self.var_matches[id] = matches
@@ -95,6 +103,8 @@
 
     def getVarMatchText(self, id):
         values = self.getVarMatch(id)
+        if isinstance(values, Expression):
+            return values.text
         return '; '.join(values)
 
     _properties_form = DTMLFile('worklist_properties', _dtmldir)
@@ -122,8 +132,15 @@
             if v:
                 if not self.var_matches:
                     self.var_matches = PersistentMapping()
-                v = [ var.strip() for var in v.split(';') ]
-                self.var_matches[key] = tuple(v)
+
+                if tales_re.match(v).group(1):
+                    # Found a TALES prefix
+                    self.var_matches[key] = Expression(v)
+                else:
+                    # Falling back to formatted string
+                    v = [ var.strip() for var in v.split(';') ]
+                    self.var_matches[key] = tuple(v)
+
             else:
                 if self.var_matches and self.var_matches.has_key(key):
                     del self.var_matches[key]
@@ -139,6 +156,36 @@
         if REQUEST is not None:
             return self.manage_properties(REQUEST, 'Properties changed.')
 
+    def search(self, info=None, **kw):
+        """ Perform the search corresponding to this worklist
+
+        Returns sequence of ZCatalog brains
+        - info is a mapping for resolving formatted string variable references
+        - additional keyword/value pairs may be used to restrict the query
+        """
+        if not self.var_matches:
+            return
+
+        if info is None:
+            info = {}
+
+        catalog = getToolByName(self, 'portal_catalog')
+        criteria = {}
+
+        for key, values in self.var_matches.items():
+            if isinstance(values, Expression):
+                wf = self.getWorkflow()
+                portal = wf._getPortalRoot()
+                context = createExprContext(StateChangeInfo(portal, wf))
+                criteria[key] = values(context)
+            else:
+                criteria[key] = [x % info for x in values]
+
+        criteria.update(kw)
+
+        return catalog.searchResults(**criteria)
+
+
 InitializeClass(WorklistDefinition)
 
 

Modified: Products.DCWorkflow/branches/jens_worklistcatalogmatches_tal/Products/DCWorkflow/dtml/worklist_properties.dtml
===================================================================
--- Products.DCWorkflow/branches/jens_worklistcatalogmatches_tal/Products/DCWorkflow/dtml/worklist_properties.dtml	2009-05-19 11:31:33 UTC (rev 100123)
+++ Products.DCWorkflow/branches/jens_worklistcatalogmatches_tal/Products/DCWorkflow/dtml/worklist_properties.dtml	2009-05-19 11:35:34 UTC (rev 100124)
@@ -19,7 +19,7 @@
 <tr>
 <th align="left" valign="top">
   <div class="form-label">
-  Cataloged variable matches (formatted)
+  Cataloged variable matches (formatted or expression)
   </div>
 </th>
 <td>

Added: Products.DCWorkflow/branches/jens_worklistcatalogmatches_tal/Products/DCWorkflow/tests/test_Worklist.py
===================================================================
--- Products.DCWorkflow/branches/jens_worklistcatalogmatches_tal/Products/DCWorkflow/tests/test_Worklist.py	                        (rev 0)
+++ Products.DCWorkflow/branches/jens_worklistcatalogmatches_tal/Products/DCWorkflow/tests/test_Worklist.py	2009-05-19 11:35:34 UTC (rev 100124)
@@ -0,0 +1,159 @@
+##############################################################################
+#
+# Copyright (c) 2009 Zope Corporation and Contributors. 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.
+#
+##############################################################################
+""" Unit tests for the DCWorkflow Worklists module.
+
+$Id$
+"""
+
+import unittest
+
+from Products.CMFCore.CatalogTool import CatalogTool
+from Products.CMFCore.testing import TraversingZCMLLayer
+from Products.CMFCore.tests.base.dummy import DummyContent
+from Products.CMFCore.tests.base.dummy import DummySite
+from Products.CMFCore.tests.base.dummy import DummyTool
+from Products.CMFCore.WorkflowTool import WorkflowTool
+
+
+class WorklistTests(unittest.TestCase):
+
+    layer = TraversingZCMLLayer
+
+    def setUp(self):
+        self.site = DummySite('site')
+        self.site._path = ''
+        self.site._setObject( 'portal_catalog', CatalogTool() )
+        self.site.portal_catalog.addIndex('state', 'KeywordIndex')
+        self.site._setObject( 'portal_types', DummyTool() )
+        self.site._setObject( 'portal_workflow', WorkflowTool() )
+        self.site._setObject( 'dummy', DummyContent('dummy') )
+        self.site.dummy.state = 'private'
+        self.site.portal_catalog.catalog_object(self.site.dummy)
+        self._constructDummyWorkflow()
+
+    def _constructDummyWorkflow(self):
+        from Products.DCWorkflow.DCWorkflow import DCWorkflowDefinition
+
+        wftool = self.site.portal_workflow
+        wftool._setObject('wf', DCWorkflowDefinition('wf'))
+        wftool.setDefaultChain('wf')
+        wf = wftool.wf
+        wf.worklists.addWorklist('reviewer_queue')
+
+    def _getDummyWorkflow(self):
+        wftool = self.site.portal_workflow
+        return wftool.wf
+
+    def _getDummyWorklist(self):
+        wf = self._getDummyWorkflow()
+        return wf.worklists.reviewer_queue
+
+    def test_defaults(self):
+        wl = self._getDummyWorklist()
+        self.assertEquals(wl.id, 'reviewer_queue')
+        self.assertEquals(wl.title, '')
+        self.assertEquals(wl.description, '')
+        self.assertEquals(wl.var_matches, None)
+        self.assertEquals(wl.actbox_name, '')
+        self.assertEquals(wl.actbox_url, '')
+        self.assertEquals(wl.actbox_icon, '')
+        self.assertEquals(wl.actbox_category, 'global')
+        self.assertEquals(wl.guard, None)
+        self.assertEquals(wl.getAvailableCatalogVars(), ['state'])
+        self.assertEquals(wl.getVarMatchKeys(), [])
+        self.failIf(wl.search())
+
+    def test_guard_default(self):
+        # Without any guard defined, an empty gard is returned
+        from AccessControl.SecurityManagement import getSecurityManager
+        guard = self._getDummyWorklist().getGuard()
+        self.assertEquals(guard.getSummary(), '')
+        self.failUnless( guard.check( getSecurityManager()
+                                    , self._getDummyWorkflow()
+                                    , self.site.dummy
+                                    ) )
+
+    def test_catalog_matches_formatted(self):
+        # Cataloged variable matches value as formatted string
+        wl = self._getDummyWorklist()
+        wl.setProperties('', props={'var_match_state': 'public; pending'})
+        self.assertEquals(wl.getVarMatchKeys(), ['state'])
+        self.assertEquals(wl.getVarMatch('state'), ('public', 'pending'))
+        self.assertEquals(wl.getVarMatchText('state'), 'public; pending')
+        self.failIf(wl.search())
+
+        wl.setProperties('', props={'var_match_state': 'private'})
+        self.assertEquals(wl.getVarMatchKeys(), ['state'])
+        self.assertEquals(wl.getVarMatch('state'), ('private',))
+        self.assertEquals(wl.getVarMatchText('state'), 'private')
+        self.assertEquals(len(wl.search()), 1)
+
+    def test_catalog_matches_tal_python(self):
+        # Cataloged variable matches value as formatted string
+        wl = self._getDummyWorklist()
+        props={'var_match_state': 'python:("public", "pending")'}
+        wl.setProperties('', props=props)
+        self.assertEquals(wl.getVarMatchKeys(), ['state'])
+        self.assertEquals( wl.getVarMatch('state').text
+                         , 'python:("public", "pending")'
+                         )
+        self.assertEquals( wl.getVarMatchText('state')
+                         , 'python:("public", "pending")'
+                         )
+        self.failIf(wl.search())
+
+        props={'var_match_state': 'python:"private"'}
+        wl.setProperties('', props=props)
+        self.assertEquals(wl.getVarMatchKeys(), ['state'])
+        self.assertEquals( wl.getVarMatch('state').text
+                         , 'python:"private"'
+                         )
+        self.assertEquals( wl.getVarMatchText('state')
+                         , 'python:"private"'
+                         )
+        self.assertEquals(len(wl.search()), 1)
+
+    def test_catalog_matches_tal_string(self):
+        # Cataloged variable matches value as formatted string
+        wl = self._getDummyWorklist()
+        props={'var_match_state': 'string:public'}
+        wl.setProperties('', props=props)
+        self.assertEquals(wl.getVarMatchKeys(), ['state'])
+        self.assertEquals( wl.getVarMatch('state').text
+                         , 'string:public'
+                         )
+        self.assertEquals( wl.getVarMatchText('state')
+                         , 'string:public'
+                         )
+        self.failIf(wl.search())
+
+        props={'var_match_state': 'string:private'}
+        wl.setProperties('', props=props)
+        self.assertEquals(wl.getVarMatchKeys(), ['state'])
+        self.assertEquals( wl.getVarMatch('state').text
+                         , 'string:private'
+                         )
+        self.assertEquals( wl.getVarMatchText('state')
+                         , 'string:private'
+                         )
+        self.assertEquals(len(wl.search()), 1)
+
+
+def test_suite():
+    return unittest.TestSuite((
+        unittest.makeSuite(WorklistTests),
+        ))
+
+if __name__ == '__main__':
+    from Products.CMFCore.testing import run
+    run(test_suite())


Property changes on: Products.DCWorkflow/branches/jens_worklistcatalogmatches_tal/Products/DCWorkflow/tests/test_Worklist.py
___________________________________________________________________
Added: svn:keywords
   + Id
Added: svn:eol-style
   + native



More information about the Checkins mailing list