[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