[CMF-checkins] SVN: CMF/branches/yuppie-workflow_setup/GenericSetup/ - added IBody to support also non-XML im- and exports

Yvo Schubbe y.2005- at wcm-solutions.de
Tue Nov 22 08:21:48 EST 2005


Log message for revision 40314:
  - added IBody to support also non-XML im- and exports
  - added some utilities for body adapters
  - added PythonScripts adapter (will be useful for TypesTool and WorkflowTool handlers)

Changed:
  A   CMF/branches/yuppie-workflow_setup/GenericSetup/PythonScripts/
  A   CMF/branches/yuppie-workflow_setup/GenericSetup/PythonScripts/__init__.py
  A   CMF/branches/yuppie-workflow_setup/GenericSetup/PythonScripts/configure.zcml
  A   CMF/branches/yuppie-workflow_setup/GenericSetup/PythonScripts/exportimport.py
  A   CMF/branches/yuppie-workflow_setup/GenericSetup/PythonScripts/interfaces.py
  A   CMF/branches/yuppie-workflow_setup/GenericSetup/PythonScripts/tests/
  A   CMF/branches/yuppie-workflow_setup/GenericSetup/PythonScripts/tests/__init__.py
  A   CMF/branches/yuppie-workflow_setup/GenericSetup/PythonScripts/tests/test_exportimport.py
  U   CMF/branches/yuppie-workflow_setup/GenericSetup/configure.zcml
  U   CMF/branches/yuppie-workflow_setup/GenericSetup/interfaces.py
  U   CMF/branches/yuppie-workflow_setup/GenericSetup/testing.py
  U   CMF/branches/yuppie-workflow_setup/GenericSetup/tests/common.py
  U   CMF/branches/yuppie-workflow_setup/GenericSetup/utils.py

-=-
Added: CMF/branches/yuppie-workflow_setup/GenericSetup/PythonScripts/__init__.py
===================================================================
--- CMF/branches/yuppie-workflow_setup/GenericSetup/PythonScripts/__init__.py	2005-11-22 12:16:09 UTC (rev 40313)
+++ CMF/branches/yuppie-workflow_setup/GenericSetup/PythonScripts/__init__.py	2005-11-22 13:21:47 UTC (rev 40314)
@@ -0,0 +1,16 @@
+##############################################################################
+#
+# 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.
+#
+##############################################################################
+"""PythonScript support.
+
+$Id$
+"""


Property changes on: CMF/branches/yuppie-workflow_setup/GenericSetup/PythonScripts/__init__.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: CMF/branches/yuppie-workflow_setup/GenericSetup/PythonScripts/configure.zcml
===================================================================
--- CMF/branches/yuppie-workflow_setup/GenericSetup/PythonScripts/configure.zcml	2005-11-22 12:16:09 UTC (rev 40313)
+++ CMF/branches/yuppie-workflow_setup/GenericSetup/PythonScripts/configure.zcml	2005-11-22 13:21:47 UTC (rev 40314)
@@ -0,0 +1,18 @@
+<configure
+    xmlns="http://namespaces.zope.org/zope"
+    xmlns:five="http://namespaces.zope.org/five"
+    >
+
+  <adapter
+      factory=".exportimport.PythonScriptBodyAdapter"
+      provides="Products.GenericSetup.interfaces.IBody"
+      for=".interfaces.IPythonScript
+           Products.GenericSetup.interfaces.ISetupContext"
+      />
+
+  <five:implements
+      class="Products.PythonScripts.PythonScript.PythonScript"
+      interface=".interfaces.IPythonScript"
+      />
+
+</configure>


Property changes on: CMF/branches/yuppie-workflow_setup/GenericSetup/PythonScripts/configure.zcml
___________________________________________________________________
Name: svn:eol-style
   + native

Added: CMF/branches/yuppie-workflow_setup/GenericSetup/PythonScripts/exportimport.py
===================================================================
--- CMF/branches/yuppie-workflow_setup/GenericSetup/PythonScripts/exportimport.py	2005-11-22 12:16:09 UTC (rev 40313)
+++ CMF/branches/yuppie-workflow_setup/GenericSetup/PythonScripts/exportimport.py	2005-11-22 13:21:47 UTC (rev 40314)
@@ -0,0 +1,44 @@
+##############################################################################
+#
+# 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.
+#
+##############################################################################
+"""PythonScript export / import support.
+
+$Id$
+"""
+
+from Products.GenericSetup.utils import BodyAdapterBase
+
+from interfaces import IPythonScript
+
+
+class PythonScriptBodyAdapter(BodyAdapterBase):
+
+    """Body im- and exporter for PythonScript.
+    """
+
+    __used_for__ = IPythonScript
+
+    def _exportBody(self):
+        """Export the object as a file body.
+        """
+        return self.context.read()
+
+    def _importBody(self, body):
+        """Import the object from the file body.
+        """
+        self.context.write(body)
+
+    body = property(_exportBody, _importBody)
+
+    mime_type = 'text/plain'
+
+    suffix = '.py'


Property changes on: CMF/branches/yuppie-workflow_setup/GenericSetup/PythonScripts/exportimport.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: CMF/branches/yuppie-workflow_setup/GenericSetup/PythonScripts/interfaces.py
===================================================================
--- CMF/branches/yuppie-workflow_setup/GenericSetup/PythonScripts/interfaces.py	2005-11-22 12:16:09 UTC (rev 40313)
+++ CMF/branches/yuppie-workflow_setup/GenericSetup/PythonScripts/interfaces.py	2005-11-22 13:21:47 UTC (rev 40314)
@@ -0,0 +1,38 @@
+##############################################################################
+#
+# 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.
+#
+##############################################################################
+"""PythonScripts interfaces.
+
+$Id$
+"""
+
+from zope.interface import Interface
+
+
+class IPythonScript(Interface):
+
+    """Web-callable scripts written in a safe subset of Python.
+
+    The function may include standard python code, so long as it does not
+    attempt to use the "exec" statement or certain restricted builtins.
+    """
+
+    def read():
+        """Generate a text representation of the Script source.
+
+        Includes specially formatted comment lines for parameters, bindings
+        and the title.
+        """
+
+    def write(text):
+        """Change the Script by parsing a read()-style source text.
+        """


Property changes on: CMF/branches/yuppie-workflow_setup/GenericSetup/PythonScripts/interfaces.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: CMF/branches/yuppie-workflow_setup/GenericSetup/PythonScripts/tests/__init__.py
===================================================================
--- CMF/branches/yuppie-workflow_setup/GenericSetup/PythonScripts/tests/__init__.py	2005-11-22 12:16:09 UTC (rev 40313)
+++ CMF/branches/yuppie-workflow_setup/GenericSetup/PythonScripts/tests/__init__.py	2005-11-22 13:21:47 UTC (rev 40314)
@@ -0,0 +1,16 @@
+##############################################################################
+#
+# 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.
+#
+##############################################################################
+"""PythonScript support tests.
+
+$Id$
+"""


Property changes on: CMF/branches/yuppie-workflow_setup/GenericSetup/PythonScripts/tests/__init__.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: CMF/branches/yuppie-workflow_setup/GenericSetup/PythonScripts/tests/test_exportimport.py
===================================================================
--- CMF/branches/yuppie-workflow_setup/GenericSetup/PythonScripts/tests/test_exportimport.py	2005-11-22 12:16:09 UTC (rev 40313)
+++ CMF/branches/yuppie-workflow_setup/GenericSetup/PythonScripts/tests/test_exportimport.py	2005-11-22 13:21:47 UTC (rev 40314)
@@ -0,0 +1,65 @@
+##############################################################################
+#
+# 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.
+#
+##############################################################################
+"""PythonScript export / import support unit tests.
+
+$Id$
+"""
+
+import unittest
+import Testing
+
+from Products.Five import zcml
+
+from Products.GenericSetup.testing import BodyAdapterTestCase
+
+
+_PYTHONSCRIPT_BODY = """\
+## Script (Python) "foo_script"
+##bind container=container
+##bind context=context
+##bind namespace=
+##bind script=script
+##bind subpath=traverse_subpath
+##parameters=
+##title=
+##
+"""
+
+
+class PythonScriptBodyAdapterTests(BodyAdapterTestCase):
+
+    def _getTargetClass(self):
+        from Products.GenericSetup.PythonScripts.exportimport \
+                import PythonScriptBodyAdapter
+
+        return PythonScriptBodyAdapter
+
+    def setUp(self):
+        import Products.GenericSetup.PythonScripts
+        from Products.PythonScripts.PythonScript import PythonScript
+
+        BodyAdapterTestCase.setUp(self)
+        zcml.load_config('configure.zcml',
+                         Products.GenericSetup.PythonScripts)
+
+        self._obj = PythonScript('foo_script')
+        self._BODY = _PYTHONSCRIPT_BODY
+
+
+def test_suite():
+    return unittest.TestSuite((
+        unittest.makeSuite(PythonScriptBodyAdapterTests),
+        ))
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='test_suite')


Property changes on: CMF/branches/yuppie-workflow_setup/GenericSetup/PythonScripts/tests/test_exportimport.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Modified: CMF/branches/yuppie-workflow_setup/GenericSetup/configure.zcml
===================================================================
--- CMF/branches/yuppie-workflow_setup/GenericSetup/configure.zcml	2005-11-22 12:16:09 UTC (rev 40313)
+++ CMF/branches/yuppie-workflow_setup/GenericSetup/configure.zcml	2005-11-22 13:21:47 UTC (rev 40314)
@@ -6,6 +6,8 @@
 
   <include package=".PluginIndexes"/>
 
+  <include package=".PythonScripts"/>
+
   <include package=".ZCatalog"/>
 
   <include package=".ZCTextIndex"/>

Modified: CMF/branches/yuppie-workflow_setup/GenericSetup/interfaces.py
===================================================================
--- CMF/branches/yuppie-workflow_setup/GenericSetup/interfaces.py	2005-11-22 12:16:09 UTC (rev 40313)
+++ CMF/branches/yuppie-workflow_setup/GenericSetup/interfaces.py	2005-11-22 13:21:47 UTC (rev 40314)
@@ -16,8 +16,9 @@
 """
 
 from zope.interface import Interface
+from zope.schema import Text
+from zope.schema import TextLine
 
-
 BASE, EXTENSION = range(1, 3)
 PURGE, UPDATE = range(1, 3)
 
@@ -562,6 +563,18 @@
         """
 
 
+class IBody(Interface):
+
+    """Body im- and exporter.
+    """
+
+    body = Text(description=u'Im- and export the object as a file body.')
+
+    mime_type = TextLine(description=u'MIME type of the file body.')
+
+    suffix = TextLine(description=u'Suffix for the file.')
+
+
 class INodeExporter(Interface):
 
     """Node exporter.
@@ -581,6 +594,7 @@
         """Import the object from the DOM node.
         """
 
+
 class IFilesystemExporter(Interface):
     """ Plugin interface for site structure export.
     """

Modified: CMF/branches/yuppie-workflow_setup/GenericSetup/testing.py
===================================================================
--- CMF/branches/yuppie-workflow_setup/GenericSetup/testing.py	2005-11-22 12:16:09 UTC (rev 40313)
+++ CMF/branches/yuppie-workflow_setup/GenericSetup/testing.py	2005-11-22 13:21:47 UTC (rev 40314)
@@ -18,10 +18,16 @@
 import unittest
 from xml.dom.minidom import parseString
 
+import Products.Five
+from Products.Five import zcml
+from zope.app import zapi
 from zope.interface.verify import verifyClass
 
+from interfaces import IBody
 from interfaces import INodeExporter
 from interfaces import INodeImporter
+from tests.common import DummyExportContext
+from tests.common import DummyImportContext
 from utils import PrettyDocument
 
 try:
@@ -30,6 +36,37 @@
     from zope.app.tests.placelesssetup import PlacelessSetup
 
 
+class BodyAdapterTestCase(PlacelessSetup, unittest.TestCase):
+
+    def _populate(self, obj):
+        pass
+
+    def _verifyImport(self, obj):
+        pass
+
+    def setUp(self):
+        PlacelessSetup.setUp(self)
+        zcml.load_config('meta.zcml', Products.Five)
+
+    def test_z3interfaces(self):
+        verifyClass(IBody, self._getTargetClass())
+
+    def test_body_get(self):
+        self._populate(self._obj)
+        context = DummyExportContext(None)
+        exporter = zapi.getMultiAdapter((self._obj, context), IBody)
+        self.assertEqual(exporter.body, self._BODY)
+
+    def test_body_set(self):
+        context = DummyImportContext(None)
+        importer = zapi.getMultiAdapter((self._obj, context), IBody)
+        importer.body = self._BODY
+        self._verifyImport(self._obj)
+        context = DummyExportContext(None)
+        exporter = zapi.getMultiAdapter((self._obj, context), IBody)
+        self.assertEqual(exporter.body, self._BODY)
+
+
 class NodeAdapterTestCase(unittest.TestCase):
 
     def _populate(self, obj):

Modified: CMF/branches/yuppie-workflow_setup/GenericSetup/tests/common.py
===================================================================
--- CMF/branches/yuppie-workflow_setup/GenericSetup/tests/common.py	2005-11-22 12:16:09 UTC (rev 40313)
+++ CMF/branches/yuppie-workflow_setup/GenericSetup/tests/common.py	2005-11-22 13:21:47 UTC (rev 40314)
@@ -21,7 +21,12 @@
 
 from Acquisition import Implicit
 from Testing.ZopeTestCase import ZopeTestCase
+from zope.interface import implements
 
+from Products.GenericSetup.interfaces import IExportContext
+from Products.GenericSetup.interfaces import IImportContext
+
+
 class OmnipotentUser(Implicit):
     """ Omnipotent User for unit testing purposes.
     """
@@ -189,6 +194,8 @@
 
 class DummyExportContext:
 
+    implements(IExportContext)
+
     def __init__( self, site, tool=None ):
         self._site = site
         self._tool = tool
@@ -212,6 +219,8 @@
 
 class DummyImportContext:
 
+    implements(IImportContext)
+
     def __init__( self, site, purge=True, encoding=None, tool=None ):
         self._site = site
         self._tool = tool

Modified: CMF/branches/yuppie-workflow_setup/GenericSetup/utils.py
===================================================================
--- CMF/branches/yuppie-workflow_setup/GenericSetup/utils.py	2005-11-22 12:16:09 UTC (rev 40313)
+++ CMF/branches/yuppie-workflow_setup/GenericSetup/utils.py	2005-11-22 13:21:47 UTC (rev 40314)
@@ -21,7 +21,7 @@
 from xml.dom.minidom import Document
 from xml.dom.minidom import Element
 from xml.dom.minidom import Node
-from xml.dom.minidom import parseString as domParseString
+from xml.dom.minidom import parseString
 from xml.sax.handler import ContentHandler
 
 import Products
@@ -30,12 +30,14 @@
 from Globals import InitializeClass
 from Globals import package_home
 from TAL.TALDefs import attrEscape
+from zope.app import zapi
 from zope.interface import implements
 
 from exceptions import BadRequest
+from interfaces import IBody
 from interfaces import INodeExporter
 from interfaces import INodeImporter
-from interfaces import PURGE
+from interfaces import PURGE, UPDATE
 from permissions import ManagePortal
 
 
@@ -161,7 +163,7 @@
         if reader is not None:
             xml = reader()
 
-        dom = domParseString(xml)
+        dom = parseString(xml)
         root = dom.documentElement
 
         return self._extractNode(root)
@@ -394,6 +396,36 @@
             node.writexml(writer, indent, addindent, newl)
 
 
+class BodyAdapterBase(object):
+
+    """Body im- and exporter base.
+    """
+
+    implements(IBody)
+
+    _LOGGER_ID = ''
+
+    def __init__(self, context, environ):
+        self.context = context
+        self.environ = environ
+        self._logger = environ.getLogger(self._LOGGER_ID)
+
+    def _exportBody(self):
+        """Export the object as a file body.
+        """
+        return ''
+
+    def _importBody(self, body):
+        """Import the object from the file body.
+        """
+
+    body = property(_exportBody, _importBody)
+
+    mime_type = 'text/plain'
+
+    suffix = ''
+
+
 class NodeAdapterBase(object):
 
     """Node im- and exporter base.
@@ -436,6 +468,32 @@
     def _convertToBoolean(self, val):
         return val.lower() in ('true', 'yes', '1')
 
+
+class XMLAdapterBase(BodyAdapterBase, NodeAdapterBase):
+
+    """XML im- and exporter base.
+    """
+
+    def _exportBody(self):
+        """Export the object as a file body.
+        """
+        doc = PrettyDocument()
+        doc.appendChild(self.exportNode(doc))
+        return doc.toprettyxml(' ')
+
+    def _importBody(self, body):
+        """Import the object from the file body.
+        """
+        mode = self.environ.shouldPurge() and PURGE or UPDATE
+        self.importNode(parseString(body).documentElement, mode=mode)
+
+    body = property(_exportBody, _importBody)
+
+    mime_type = 'text/xml'
+
+    suffix = '.xml'
+
+
 class ObjectManagerHelpers(object):
 
     """ObjectManager im- and export helpers.
@@ -494,7 +552,9 @@
                         pass
 
             obj = getattr(self.context, obj_id)
-            INodeImporter(obj).importNode(child, mode)
+            importer = INodeImporter(obj, None)
+            if importer:
+                importer.importNode(child, mode)
 
 
 class PropertyManagerHelpers(object):
@@ -588,3 +648,34 @@
                 prop_value = self._getNodeText(child).encode('utf-8')
 
             obj._updateProperty(prop_id, prop_value)
+
+
+def exportObjects(parent, parent_path, context):
+    """ Export subobjects recursively.
+    """
+    for obj in parent.objectValues():
+        path = '%s/%s' % (parent_path, obj.getId().replace(' ', '_'))
+
+        exporter = zapi.queryMultiAdapter((obj, context), IBody)
+        if exporter:
+            filename = '%s%s' % (path, exporter.suffix)
+            context.writeDataFile(filename, exporter.body, exporter.mime_type)
+
+        if getattr(obj, 'objectValues', False):
+            exportObjects(obj, path, context)
+
+def importObjects(parent, parent_path, context):
+    """ Import subobjects recursively.
+    """
+    for obj in parent.objectValues():
+        path = '%s/%s' % (parent_path, obj.getId().replace(' ', '_'))
+
+        importer = zapi.queryMultiAdapter((obj, context), IBody)
+        if importer:
+            filename = '%s%s' % (path, importer.suffix)
+            body = context.readDataFile(filename)
+            if body:
+                importer.body = body
+
+        if getattr(obj, 'objectValues', False):
+            importObjects(obj, path, context)



More information about the CMF-checkins mailing list