[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