[CMF-checkins] SVN: CMF/trunk/CMFSetup/ - CMFSetup: added support for importing and exporting workflow script

Jens Vagelpohl jens at dataflake.org
Sat Oct 29 19:19:06 EDT 2005


Log message for revision 39720:
  - CMFSetup: added support for importing and exporting workflow script
    metadata for scripts that are External Methods. One very important
    difference to other scripts remains: Since the CMFSetup machinery
    cannot access the filesystem code for external methods it only
    saves the data needed to instantiate the ZODBi-based External Method 
    object. If, during an import, the filesystem-based code cannot be
    found, the import will fail. 
  

Changed:
  A   CMF/trunk/CMFSetup/Extensions/
  A   CMF/trunk/CMFSetup/Extensions/test_method.py
  U   CMF/trunk/CMFSetup/tests/test_workflow.py
  U   CMF/trunk/CMFSetup/utils.py
  U   CMF/trunk/CMFSetup/workflow.py
  U   CMF/trunk/CMFSetup/xml/wtcWorkflowExport.xml

-=-
Added: CMF/trunk/CMFSetup/Extensions/test_method.py
===================================================================
--- CMF/trunk/CMFSetup/Extensions/test_method.py	2005-10-29 20:35:51 UTC (rev 39719)
+++ CMF/trunk/CMFSetup/Extensions/test_method.py	2005-10-29 23:19:05 UTC (rev 39720)
@@ -0,0 +1,19 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+""" External method used for unit tests - do not remove
+
+$Id: test_method.py 37115 2005-07-07 15:50:07Z jens $
+""" 
+
+def test(self):
+    return None


Property changes on: CMF/trunk/CMFSetup/Extensions/test_method.py
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: CMF/trunk/CMFSetup/tests/test_workflow.py
===================================================================
--- CMF/trunk/CMFSetup/tests/test_workflow.py	2005-10-29 20:35:51 UTC (rev 39719)
+++ CMF/trunk/CMFSetup/tests/test_workflow.py	2005-10-29 23:19:05 UTC (rev 39720)
@@ -22,6 +22,7 @@
 
 from OFS.Folder import Folder
 from Products.PythonScripts.PythonScript import PythonScript
+from Products.ExternalMethod.ExternalMethod import ExternalMethod
 
 from Products.DCWorkflow.DCWorkflow import DCWorkflowDefinition
 from Products.DCWorkflow.Transitions import TRIGGER_USER_ACTION
@@ -219,6 +220,9 @@
                 script = PythonScript( k )
                 script.write( v[ 1 ] )
 
+            elif v[ 0 ] == ExternalMethod.meta_type:
+                script = ExternalMethod(k,'', v[3], v[4])
+
             else:
                 raise ValueError, 'Unknown script type: %s' % v[ 0 ]
 
@@ -722,9 +726,13 @@
 
             self.assertEqual( info[ 'meta_type' ], expected[ 0 ] )
             self.assertEqual( info[ 'body' ], expected[ 1 ] )
-            self.assertEqual( info[ 'filename' ]
-                            , expected[ 2 ] % WF_ID )
 
+            if info[ 'meta_type' ] == PythonScript.meta_type:
+                self.assertEqual( info[ 'filename' ]
+                                , expected[ 2 ] % WF_ID )
+            else:
+                self.assertEqual( info[ 'filename' ], expected[ 2 ] )
+
     def test_generateXML_empty( self ):
 
         WF_ID = 'empty'
@@ -1246,8 +1254,11 @@
 
             # Body is not kept as part of the workflow XML
 
-            self.assertEqual( script[ 'filename' ]
-                            , expected[ 2 ] % workflow_id )
+            if script[ 'meta_type' ] == PythonScript.meta_type:
+                self.assertEqual( script[ 'filename' ]
+                                , expected[ 2 ] % workflow_id )
+            else:
+                self.assertEqual( script[ 'filename' ], expected[ 2 ] )
 
 
 _WF_PERMISSIONS = \
@@ -1379,11 +1390,11 @@
              , 'Retire objects whose expiration is past.'
              , 'expired'
              , TRIGGER_AUTOMATIC
+             , 'before_expire'
              , ''
              , ''
              , ''
              , ''
-             , ''
              , { 'when_expired' : 'object/ZopeTime' }
              , ()
              , ()
@@ -1460,15 +1471,27 @@
 { 'before_open':    ( PythonScript.meta_type
                     , _BEFORE_OPEN_SCRIPT
                     , 'workflows/%s/scripts/before_open.py'
+                    , None
+                    , None
                     )
 , 'after_close':    ( PythonScript.meta_type
                     , _AFTER_CLOSE_SCRIPT
                     , 'workflows/%s/scripts/after_close.py'
+                    , None
+                    , None
                     )
 , 'after_kill':     ( PythonScript.meta_type
                     , _AFTER_KILL_SCRIPT
                     , 'workflows/%s/scripts/after_kill.py'
+                    , None
+                    , None
                     )
+, 'before_expire': ( ExternalMethod.meta_type
+                   , ''
+                   , ''
+                   , 'CMFSetup.test_method'
+                   , 'test'
+                   )
 }
 
 _EMPTY_TOOL_EXPORT = """\
@@ -1682,7 +1705,7 @@
     title="Expire"
     trigger="AUTOMATIC"
     new_state="expired"
-    before_script=""
+    before_script="before_expire"
     after_script="">
   <description>Retire objects whose expiration is past.</description>
   <guard>
@@ -1795,16 +1818,29 @@
     script_id="after_close"
     type="Script (Python)"
     filename="workflows/%(workflow_filename)s/after_close.py"
+    module=""
+    function=""
     />
  <script
     script_id="after_kill"
     type="Script (Python)"
     filename="workflows/%(workflow_filename)s/after_kill.py"
+    module=""
+    function=""
     />
  <script
+    script_id="before_expire"
+    type="External Method"
+    filename=""
+    module="CMFSetup.test_method"
+    function="test"
+    />
+ <script
     script_id="before_open"
     type="Script (Python)"
     filename="workflows/%(workflow_filename)s/before_open.py"
+    module=""
+    function=""
     />
 </dc-workflow>
 """
@@ -1912,7 +1948,7 @@
     title="Expire"
     trigger="AUTOMATIC"
     new_state="expired"
-    before_script=""
+    before_script="before_expire"
     after_script="">
   <description>Retire objects whose expiration is past.</description>
   <guard>
@@ -2025,16 +2061,29 @@
     script_id="after_close"
     type="Script (Python)"
     filename="workflows/%(workflow_filename)s/scripts/after_close.py"
+    module=""
+    function=""
     />
  <script
     script_id="after_kill"
     type="Script (Python)"
     filename="workflows/%(workflow_filename)s/scripts/after_kill.py"
+    module=""
+    function=""
     />
  <script
+    script_id="before_expire"
+    type="External Method"
+    filename=""
+    module="CMFSetup.test_method"
+    function="test"
+    />
+ <script
     script_id="before_open"
     type="Script (Python)"
     filename="workflows/%(workflow_filename)s/scripts/before_open.py"
+    module=""
+    function=""
     />
 </dc-workflow>
 """
@@ -2586,8 +2635,10 @@
             expected = _WF_SCRIPTS[ script_id ]
 
             self.assertEqual( script.meta_type, expected[ 0 ] )
-            self.assertEqual( script.manage_FTPget(), expected[ 1 ] )
 
+            if script.meta_type == PythonScript.meta_type:
+                self.assertEqual( script.manage_FTPget(), expected[ 1 ] )
+
     def test_from_empty_dcworkflow_workflow_scripts( self ):
 
         WF_ID = 'dcworkflow_scripts'
@@ -2608,8 +2659,10 @@
             expected = _WF_SCRIPTS[ script_id ]
 
             self.assertEqual( script.meta_type, expected[ 0 ] )
-            self.assertEqual( script.manage_FTPget(), expected[ 1 ] )
 
+            if script.meta_type == PythonScript.meta_type:
+                self.assertEqual( script.manage_FTPget(), expected[ 1 ] )
+
 def test_suite():
     return unittest.TestSuite((
         unittest.makeSuite( WorkflowToolConfiguratorTests ),

Modified: CMF/trunk/CMFSetup/utils.py
===================================================================
--- CMF/trunk/CMFSetup/utils.py	2005-10-29 20:35:51 UTC (rev 39719)
+++ CMF/trunk/CMFSetup/utils.py	2005-10-29 23:19:05 UTC (rev 39720)
@@ -361,7 +361,7 @@
     value = _queryNodeAttribute( node, attr_name, _marker, encoding )
 
     if value is _marker:
-        raise ValueError, 'Invaid attribute: %s' % attr_name
+        raise ValueError, 'Invalid attribute: %s' % attr_name
 
     return value
 

Modified: CMF/trunk/CMFSetup/workflow.py
===================================================================
--- CMF/trunk/CMFSetup/workflow.py	2005-10-29 20:35:51 UTC (rev 39719)
+++ CMF/trunk/CMFSetup/workflow.py	2005-10-29 23:19:05 UTC (rev 39720)
@@ -196,9 +196,10 @@
                                  , 'workflows/%s' % wf_dirname
                                  )
             for script_info in wf_scripts:
-                context.writeDataFile(script_info['filename'],
-                                      script_info['body'],
-                                      'text/plain')
+                if script_info['filename']:
+                    context.writeDataFile(script_info['filename'],
+                                          script_info['body'],
+                                          'text/plain')
 
     return 'Workflows exported.'
 
@@ -365,7 +366,7 @@
 
     security.declareProtected( ManagePortal, 'generateWorkflowScripts' )
     def getWorkflowScripts( self, workflow_id ):
-        """ Get workflow scripts inforation
+        """ Get workflow scripts information
         """
         workflow_tool = getToolByName( self._site, 'portal_workflow' )
         workflow = workflow_tool.getWorkflowById( workflow_id )
@@ -449,7 +450,7 @@
             worklists tracked by the workflow (see '_extractWorklists').
 
           'script_info' -- a list of mappings describing the scripts which
-            provide added business logic (wee '_extractScripts').
+            provide added business logic (see '_extractScripts').
         """
         workflow_info[ 'filename' ] = _getWorkflowFilename( workflow.getId() )
         workflow_info[ 'state_variable' ] = workflow.state_var
@@ -789,10 +790,17 @@
 
           'meta_type' -- the title of the worklist
 
-          'body' -- the text of the script
+          'body' -- the text of the script (only applicable to scripts
+            of type Script (Python))
 
+          'module' -- The module from where to load the function (only
+            applicable to External Method scripts)
+
+          'function' -- The function to load from the 'module' given
+            (Only applicable to External Method scripts)
+
           'filename' -- the name of the file to / from which the script
-            is stored / loaded
+            is stored / loaded (Script (Python) only)
         """
         result = []
 
@@ -802,10 +810,22 @@
         for k, v in items:
 
             filename = _getScriptFilename( workflow.getId(), k, v.meta_type )
+            body = ''
+            module = ''
+            function = ''
 
+            if v.meta_type == 'Script (Python)':
+                body = v.read()
+
+            if v.meta_type == 'External Method':
+                module = v.module()
+                function = v.function()
+
             info = { 'id'                   : k
                    , 'meta_type'            : v.meta_type
-                   , 'body'                 : v.read()
+                   , 'body'                 : body
+                   , 'module'               : module
+                   , 'function'             : function
                    , 'filename'             : filename
                    }
 
@@ -827,7 +847,11 @@
     """ Return the name of the file which holds the script.
     """
     wf_dir = workflow_id.replace( ' ', '_' )
-    suffix = _METATYPE_SUFFIXES[ meta_type ]
+    suffix = _METATYPE_SUFFIXES.get(meta_type, None)
+
+    if suffix is None:
+        return ''
+
     return 'workflows/%s/scripts/%s.%s' % ( wf_dir, script_id, suffix )
 
 def _extractStateNodes( root, encoding=None ):
@@ -975,9 +999,20 @@
 
     for s_node in root.getElementsByTagName( 'script' ):
 
+        try:
+            function = _getNodeAttribute( s_node, 'function' )
+        except ValueError:
+            function = ''
 
+        try:
+            module = _getNodeAttribute( s_node, 'module' )
+        except ValueError:
+            module = ''
+
         info = { 'script_id' : _getNodeAttribute( s_node, 'script_id' )
                , 'meta_type' : _getNodeAttribute( s_node, 'type' , encoding )
+               , 'function'  : function
+               , 'module'    : module
                }
 
         filename = _queryNodeAttribute( s_node, 'filename' , None, encoding )
@@ -1150,7 +1185,6 @@
 
 _METATYPE_SUFFIXES = \
 { PythonScript.meta_type : 'py'
-, ExternalMethod.meta_type : 'em'
 , DTMLMethod.meta_type : 'dtml'
 }
 
@@ -1337,15 +1371,21 @@
         id = str( s_info[ 'script_id' ] ) # no unicode!
         meta_type = s_info[ 'meta_type' ]
         filename = s_info[ 'filename' ]
+        file = ''
 
-        file = context.readDataFile( filename )
+        if filename:
+            file = context.readDataFile( filename )
 
         if meta_type == PythonScript.meta_type:
             script = PythonScript( id )
             script.write( file )
 
-        #elif meta_type == ExternalMethod.meta_type:
-        #    script = ExternalMethod( id, title, module, function )
+        elif meta_type == ExternalMethod.meta_type:
+            script = ExternalMethod( id
+                                   , ''
+                                   , s_info['module']
+                                   , s_info['function']
+                                   )
 
         elif meta_type == DTMLMethod.meta_type:
             script = DTMLMethod( file, __name__=id )

Modified: CMF/trunk/CMFSetup/xml/wtcWorkflowExport.xml
===================================================================
--- CMF/trunk/CMFSetup/xml/wtcWorkflowExport.xml	2005-10-29 20:35:51 UTC (rev 39719)
+++ CMF/trunk/CMFSetup/xml/wtcWorkflowExport.xml	2005-10-29 23:19:05 UTC (rev 39720)
@@ -200,10 +200,14 @@
         script_id="SCRIPT_ID"
         type="Script (Python)"
         filename="/path/to/SCRIPT_ID.py"
+        module=""
+        function=""
         tal:repeat="script info/script_info"
         tal:attributes="script_id script/id;
                         type script/meta_type;
                         filename script/filename;
+                        module script/module;
+                        function script/function
                        "
         />
 </dc-workflow>



More information about the CMF-checkins mailing list