[CMF-checkins] SVN: CMF/branches/1.6/CMFCore/ * merging Tres's
"refactor_content_export_import" changes back from
Rob Miller
ra at burningman.com
Sat Nov 19 15:59:13 EST 2005
Log message for revision 40261:
* merging Tres's "refactor_content_export_import" changes back from
CMF trunk
Changed:
U CMF/branches/1.6/CMFCore/exportimport/configure.zcml
U CMF/branches/1.6/CMFCore/exportimport/content.py
U CMF/branches/1.6/CMFCore/exportimport/tests/test_content.py
U CMF/branches/1.6/CMFCore/interfaces/__init__.py
D CMF/branches/1.6/CMFCore/interfaces/_exportimport.py
-=-
Modified: CMF/branches/1.6/CMFCore/exportimport/configure.zcml
===================================================================
--- CMF/branches/1.6/CMFCore/exportimport/configure.zcml 2005-11-19 20:57:29 UTC (rev 40260)
+++ CMF/branches/1.6/CMFCore/exportimport/configure.zcml 2005-11-19 20:59:12 UTC (rev 40261)
@@ -66,53 +66,17 @@
<adapter
factory=".content.StructureFolderWalkingAdapter"
- provides="Products.CMFCore.interfaces.IFilesystemExporter"
+ provides="Products.GenericSetup.interfaces.IFilesystemExporter"
for="Products.CMFCore.interfaces.IFolderish"
/>
<adapter
factory=".content.StructureFolderWalkingAdapter"
- provides="Products.CMFCore.interfaces.IFilesystemImporter"
+ provides="Products.GenericSetup.interfaces.IFilesystemImporter"
for="Products.CMFCore.interfaces.IFolderish"
/>
<adapter
- factory=".content.CSVAwareFileAdapter"
- provides="Products.CMFCore.interfaces.IFilesystemExporter"
- for="Products.CMFCore.interfaces.ICSVAware"
- />
-
- <adapter
- factory=".content.CSVAwareFileAdapter"
- provides="Products.CMFCore.interfaces.IFilesystemImporter"
- for="Products.CMFCore.interfaces.ICSVAware"
- />
-
- <adapter
- factory=".content.INIAwareFileAdapter"
- provides="Products.CMFCore.interfaces.IFilesystemExporter"
- for="Products.CMFCore.interfaces.IINIAware"
- />
-
- <adapter
- factory=".content.INIAwareFileAdapter"
- provides="Products.CMFCore.interfaces.IFilesystemImporter"
- for="Products.CMFCore.interfaces.IINIAware"
- />
-
- <adapter
- factory=".content.DAVAwareFileAdapter"
- provides="Products.CMFCore.interfaces.IFilesystemExporter"
- for="Products.CMFCore.interfaces.IDAVAware"
- />
-
- <adapter
- factory=".content.DAVAwareFileAdapter"
- provides="Products.CMFCore.interfaces.IFilesystemImporter"
- for="Products.CMFCore.interfaces.IDAVAware"
- />
-
- <adapter
factory=".contenttyperegistry.ContentTypeRegistryNodeAdapter"
provides="Products.GenericSetup.interfaces.INodeExporter"
for="Products.CMFCore.interfaces.IContentTypeRegistry"
Modified: CMF/branches/1.6/CMFCore/exportimport/content.py
===================================================================
--- CMF/branches/1.6/CMFCore/exportimport/content.py 2005-11-19 20:57:29 UTC (rev 40260)
+++ CMF/branches/1.6/CMFCore/exportimport/content.py 2005-11-19 20:59:12 UTC (rev 40261)
@@ -25,19 +25,19 @@
from zope.interface import implements
from zope.interface import directlyProvides
-from Products.CMFCore.interfaces import IFilesystemExporter
-from Products.CMFCore.interfaces import IFilesystemImporter
-from Products.CMFCore.interfaces import ISiteRoot
+from Products.GenericSetup.interfaces import IFilesystemExporter
+from Products.GenericSetup.interfaces import IFilesystemImporter
+from Products.GenericSetup.content import _globtest
from Products.CMFCore.utils import getToolByName
#
# setup_tool handlers
#
def exportSiteStructure(context):
- IFilesystemExporter(context.getSite()).export(context, 'structure')
+ IFilesystemExporter(context.getSite()).export(context, 'structure', True)
def importSiteStructure(context):
- IFilesystemImporter(context.getSite()).import_(context, 'structure')
+ IFilesystemImporter(context.getSite()).import_(context, 'structure', True)
#
@@ -65,7 +65,7 @@
def __init__(self, context):
self.context = context
- def export(self, export_context, subdir):
+ def export(self, export_context, subdir, root=False):
""" See IFilesystemExporter.
"""
# Enumerate exportable children
@@ -79,7 +79,7 @@
for object_id, object, ignored in exportable:
csv_writer.writerow((object_id, object.getPortalTypeName()))
- if not ISiteRoot.providedBy(self.context):
+ if not root:
subdir = '%s/%s' % (subdir, self.context.getId())
export_context.writeDataFile('.objects',
@@ -108,11 +108,11 @@
if adapter is not None:
adapter.export(export_context, subdir)
- def import_(self, import_context, subdir):
+ def import_(self, import_context, subdir, root=False):
""" See IFilesystemImporter.
"""
context = self.context
- if not ISiteRoot.providedBy(context):
+ if not root:
subdir = '%s/%s' % (subdir, context.getId())
preserve = import_context.readDataFile('.preserve', subdir)
@@ -183,142 +183,3 @@
return content
-
-def _globtest(globpattern, namelist):
- """ Filter names in 'namelist', returning those which match 'globpattern'.
- """
- import re
- pattern = globpattern.replace(".", r"\.") # mask dots
- pattern = pattern.replace("*", r".*") # change glob sequence
- pattern = pattern.replace("?", r".") # change glob char
- pattern = '|'.join(pattern.split()) # 'or' each line
-
- compiled = re.compile(pattern)
-
- return filter(compiled.match, namelist)
-
-
-class CSVAwareFileAdapter(object):
- """ Adapter for content whose "natural" representation is CSV.
- """
- implements(IFilesystemExporter, IFilesystemImporter)
-
- def __init__(self, context):
- self.context = context
-
- def export(self, export_context, subdir):
- """ See IFilesystemExporter.
- """
- export_context.writeDataFile('%s.csv' % self.context.getId(),
- self.context.as_csv(),
- 'text/comma-separated-values',
- subdir,
- )
-
- def listExportableItems(self):
- """ See IFilesystemExporter.
- """
- return ()
-
- def import_(self, import_context, subdir):
- """ See IFilesystemImporter.
- """
- cid = self.context.getId()
- data = import_context.readDataFile('%s.csv' % cid, subdir)
- if data is None:
- import_context.note('CSAFA',
- 'no .csv file for %s/%s' % (subdir, cid))
- else:
- stream = StringIO(data)
- self.context.put_csv(stream)
-
-class INIAwareFileAdapter(object):
- """ Exporter/importer for content whose "natural" representation is CSV.
- """
- implements(IFilesystemExporter, IFilesystemImporter)
-
- def __init__(self, context):
- self.context = context
-
- def export(self, export_context, subdir):
- """ See IFilesystemExporter.
- """
- export_context.writeDataFile('%s.ini' % self.context.getId(),
- self.context.as_ini(),
- 'text/plain',
- subdir,
- )
-
- def listExportableItems(self):
- """ See IFilesystemExporter.
- """
- return ()
-
- def import_(self, import_context, subdir):
- """ See IFilesystemImporter.
- """
- cid = self.context.getId()
- data = import_context.readDataFile('%s.ini' % cid, subdir)
- if data is None:
- import_context.note('SGAIFA',
- 'no .ini file for %s/%s' % (subdir, cid))
- else:
- self.context.put_ini(data)
-
-
-class FauxDAVRequest:
-
- def __init__(self, **kw):
- self._data = {}
- self._headers = {}
- self._data.update(kw)
-
- def __getitem__(self, key):
- return self._data[key]
-
- def get(self, key, default=None):
- return self._data.get(key, default)
-
- def get_header(self, key, default=None):
- return self._headers.get(key, default)
-
-class FauxDAVResponse:
- def setHeader(self, key, value, lock=False):
- pass # stub this out to mollify webdav.Resource
- def setStatus(self, value, reason=None):
- pass # stub this out to mollify webdav.Resource
-
-class DAVAwareFileAdapter(object):
- """ Exporter/importer for content who handle their own FTP / DAV PUTs.
- """
- implements(IFilesystemExporter, IFilesystemImporter)
-
- def __init__(self, context):
- self.context = context
-
- def export(self, export_context, subdir):
- """ See IFilesystemExporter.
- """
- export_context.writeDataFile('%s' % self.context.getId(),
- self.context.manage_FTPget(),
- 'text/plain',
- subdir,
- )
-
- def listExportableItems(self):
- """ See IFilesystemExporter.
- """
- return ()
-
- def import_(self, import_context, subdir):
- """ See IFilesystemImporter.
- """
- cid = self.context.getId()
- data = import_context.readDataFile('%s' % cid, subdir)
- if data is None:
- import_context.note('SGAIFA',
- 'no .ini file for %s/%s' % (subdir, cid))
- else:
- request = FauxDAVRequest(BODY=data, BODYFILE=StringIO(data))
- response = FauxDAVResponse()
- self.context.PUT(request, response)
Modified: CMF/branches/1.6/CMFCore/exportimport/tests/test_content.py
===================================================================
--- CMF/branches/1.6/CMFCore/exportimport/tests/test_content.py 2005-11-19 20:57:29 UTC (rev 40260)
+++ CMF/branches/1.6/CMFCore/exportimport/tests/test_content.py 2005-11-19 20:59:12 UTC (rev 40261)
@@ -50,17 +50,17 @@
from zope.app.tests import ztapi
#from OFS.Image import File
- from Products.CMFCore.interfaces import IFilesystemExporter
- from Products.CMFCore.interfaces import IFilesystemImporter
+ from Products.GenericSetup.interfaces import IFilesystemExporter
+ from Products.GenericSetup.interfaces import IFilesystemImporter
+ from Products.GenericSetup.interfaces import ICSVAware
+ from Products.GenericSetup.interfaces import IINIAware
from Products.CMFCore.interfaces import IFolderish
- from Products.CMFCore.interfaces import ICSVAware
- from Products.CMFCore.interfaces import IINIAware
from Products.CMFCore.exportimport.content import \
StructureFolderWalkingAdapter
- from Products.CMFCore.exportimport.content import \
+ from Products.GenericSetup.content import \
CSVAwareFileAdapter
- from Products.CMFCore.exportimport.content import \
+ from Products.GenericSetup.content import \
INIAwareFileAdapter
#from Products.CMFCore.exportimport.content import \
@@ -357,6 +357,8 @@
self.assertEqual(site.objectIds()[0], 'setup_tool')
def test_import_site_with_subfolders(self):
+ from Products.GenericSetup.tests.test_content \
+ import _PROPERTIES_TEMPLATE
self._setUpAdapters()
FOLDER_IDS = ('foo', 'bar', 'baz')
@@ -518,177 +520,6 @@
self.assertEqual(site.foo.objectIds()[1], 'baz')
-class Test_globpattern(unittest.TestCase):
-
- NAMELIST = ('foo', 'bar', 'baz', 'bam', 'qux', 'quxx', 'quxxx')
-
- def _checkResults(self, globpattern, namelist, expected):
- from Products.CMFCore.exportimport.content import _globtest
- found = _globtest(globpattern, namelist)
- self.assertEqual(len(found), len(expected))
- for found_item, expected_item in zip(found, expected):
- self.assertEqual(found_item, expected_item)
-
- def test_star(self):
- self._checkResults('*', self.NAMELIST, self.NAMELIST)
-
- def test_simple(self):
- self._checkResults('b*', self.NAMELIST,
- [x for x in self.NAMELIST if x.startswith('b')])
-
- def test_multiple(self):
- self._checkResults('b*\n*x', self.NAMELIST,
- [x for x in self.NAMELIST
- if x.startswith('b') or x.endswith('x')])
-
-
-class CSVAwareFileAdapterTests(unittest.TestCase,
- ConformsToIFilesystemExporter,
- ConformsToIFilesystemImporter,
- ):
-
- def _getTargetClass(self):
- from Products.CMFCore.exportimport.content import CSVAwareFileAdapter
- return CSVAwareFileAdapter
-
- def _makeOne(self, context, *args, **kw):
- return self._getTargetClass()(context, *args, **kw)
-
- def _makeCSVAware(self, sheet_id, csv=''):
- class Foo:
- def getId(self):
- return self._id
- def as_csv(self):
- return self.csv
- def put_csv(self, stream):
- self.new_csv = stream.getvalue()
-
- foo = Foo()
- foo._id = sheet_id
- foo.csv = csv
- foo.new_csv = None
-
- return foo
-
-
- def test_export_with_known_CSV(self):
- KNOWN_CSV = """\
-one,two,three
-four,five,six
-"""
- sheet = self._makeCSVAware('config', KNOWN_CSV)
-
- adapter = self._makeOne(sheet)
- context = DummyExportContext(None)
- adapter.export(context, 'subpath/to/sheet')
-
- self.assertEqual(len(context._wrote), 1)
- filename, text, content_type = context._wrote[0]
- self.assertEqual(filename, 'subpath/to/sheet/config.csv')
- self.assertEqual(content_type, 'text/comma-separated-values')
-
- self.assertEqual(text.strip(), KNOWN_CSV.strip())
-
- def test_import_with_known_CSV(self):
- ORIG_CSV = """\
-one,two,three
-four,five,six
-"""
- NEW_CSV = """\
-four,five,six
-one,two,three
-"""
- sheet = self._makeCSVAware('config', ORIG_CSV)
-
- adapter = self._makeOne(sheet)
- context = DummyImportContext(None)
- context._files['subpath/to/sheet/config.csv'] = NEW_CSV
- adapter.import_(context, 'subpath/to/sheet')
-
- self.assertEqual(sheet.new_csv.strip(), NEW_CSV.strip())
-
-
-_PROPERTIES_TEMPLATE = """
-[DEFAULT]
-Title = %s
-Description = This is a test
-"""
-
-class INIAwareFileAdapterTests(unittest.TestCase,
- ConformsToIFilesystemExporter,
- ConformsToIFilesystemImporter,
- ):
-
- def _getTargetClass(self):
- from Products.CMFCore.exportimport.content import INIAwareFileAdapter
- return INIAwareFileAdapter
-
- def _makeOne(self, context, *args, **kw):
- return self._getTargetClass()(context, *args, **kw)
-
- def test_export_ini_file(self):
- ini_file = _makeINIAware('ini_file.html')
- adapter = self._makeOne(ini_file)
- context = DummyExportContext(None)
- adapter.export(context, 'subpath/to')
-
- self.assertEqual(len(context._wrote), 1)
- filename, text, content_type = context._wrote[0]
- self.assertEqual(filename, 'subpath/to/ini_file.html.ini')
- self.assertEqual(content_type, 'text/plain')
-
- self.assertEqual(text.strip(), ini_file.as_ini().strip())
-
- def test_import_ini_file(self):
- ini_file = _makeINIAware('ini_file.html')
- adapter = self._makeOne(ini_file)
- context = DummyImportContext(None)
- context._files['subpath/to/ini_file.html.ini'] = (
- KNOWN_INI % ('Title: ini_file', 'abc'))
-
- adapter.import_(context, 'subpath/to')
- text = ini_file._was_put
- parser = ConfigParser()
- parser.readfp(StringIO(text))
- self.assertEqual(parser.get('DEFAULT', 'title'), 'Title: ini_file')
- self.assertEqual(parser.get('DEFAULT', 'description'), 'abc')
-
-
-class DAVAwareFileAdapterTests(unittest.TestCase,
- ConformsToIFilesystemExporter,
- ConformsToIFilesystemImporter,
- ):
-
- def _getTargetClass(self):
- from Products.CMFCore.exportimport.content import DAVAwareFileAdapter
- return DAVAwareFileAdapter
-
- def _makeOne(self, context, *args, **kw):
- return self._getTargetClass()(context, *args, **kw)
-
- def test_export_dav_file(self):
- dav_file = _makeDAVAware('dav_file.html')
- adapter = self._makeOne(dav_file)
- context = DummyExportContext(None)
- adapter.export(context, 'subpath/to')
-
- self.assertEqual(len(context._wrote), 1)
- filename, text, content_type = context._wrote[0]
- self.assertEqual(filename, 'subpath/to/dav_file.html')
- self.assertEqual(content_type, 'text/plain')
- self.assertEqual(text.strip(), dav_file.manage_FTPget().strip())
-
- def test_import_dav_file(self):
- VALUES = ('Title: dav_file', 'Description: abc', 'body goes here')
- dav_file = _makeDAVAware('dav_file.html')
- adapter = self._makeOne(dav_file)
- context = DummyImportContext(None)
- context._files['subpath/to/dav_file.html'] = KNOWN_DAV % VALUES
-
- adapter.import_(context, 'subpath/to')
- text = dav_file._was_put == KNOWN_DAV % VALUES
-
-
TEST_CSV_AWARE = 'Test CSV Aware'
KNOWN_CSV = """\
one,two,three
@@ -699,7 +530,7 @@
from OFS.SimpleItem import SimpleItem
from zope.interface import implements
from Products.CMFCore.interfaces import IDynamicType
- from Products.CMFCore.interfaces import ICSVAware
+ from Products.GenericSetup.interfaces import ICSVAware
class _TestCSVAware(SimpleItem):
implements(IDynamicType, ICSVAware)
@@ -732,7 +563,7 @@
from OFS.SimpleItem import SimpleItem
from zope.interface import implements
from Products.CMFCore.interfaces import IDynamicType
- from Products.CMFCore.interfaces import IINIAware
+ from Products.GenericSetup.interfaces import IINIAware
class _TestINIAware(SimpleItem):
implements(IDynamicType, IINIAware)
@@ -768,7 +599,7 @@
from OFS.SimpleItem import SimpleItem
from zope.interface import implements
from Products.CMFCore.interfaces import IDynamicType
- from Products.CMFCore.interfaces import IDAVAware
+ from Products.GenericSetup.interfaces import IDAVAware
class _TestDAVAware(SimpleItem):
implements(IDynamicType, IDAVAware)
@@ -818,10 +649,7 @@
TEST_FOLDER = 'Test Folder'
def _makeFolder(id, site_folder=False):
- from zope.interface import directlyProvides
- from zope.interface import providedBy
from Products.CMFCore.PortalFolder import PortalFolder
- from Products.CMFCore.interfaces import ISiteRoot
from Products.CMFCore.TypesTool import TypesTool
from Products.CMFCore.tests.base.dummy import DummyType
@@ -849,7 +677,6 @@
folder = PortalFolder(id)
folder.portal_type = TEST_FOLDER
if site_folder:
- directlyProvides(folder, ISiteRoot + providedBy(folder))
tool = folder.portal_types = TypesTool()
tool._setObject(TEST_CSV_AWARE, _TypeInfo(TEST_CSV_AWARE))
tool._setObject(TEST_INI_AWARE, _TypeInfo(TEST_INI_AWARE))
@@ -862,10 +689,6 @@
def test_suite():
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(SiteStructureExporterTests))
- suite.addTest(unittest.makeSuite(Test_globpattern))
- suite.addTest(unittest.makeSuite(CSVAwareFileAdapterTests))
- suite.addTest(unittest.makeSuite(INIAwareFileAdapterTests))
- suite.addTest(unittest.makeSuite(DAVAwareFileAdapterTests))
return suite
if __name__ == '__main__':
Modified: CMF/branches/1.6/CMFCore/interfaces/__init__.py
===================================================================
--- CMF/branches/1.6/CMFCore/interfaces/__init__.py 2005-11-19 20:57:29 UTC (rev 40260)
+++ CMF/branches/1.6/CMFCore/interfaces/__init__.py 2005-11-19 20:59:12 UTC (rev 40261)
@@ -17,7 +17,6 @@
from _content import *
from _tools import *
-from _exportimport import *
import CachingPolicyManager
import Contentish
Deleted: CMF/branches/1.6/CMFCore/interfaces/_exportimport.py
===================================================================
--- CMF/branches/1.6/CMFCore/interfaces/_exportimport.py 2005-11-19 20:57:29 UTC (rev 40260)
+++ CMF/branches/1.6/CMFCore/interfaces/_exportimport.py 2005-11-19 20:59:12 UTC (rev 40261)
@@ -1,96 +0,0 @@
-""" Interfaces for content import / export, based on GenericSetup
-
-$Id: _exportimport.py 39085 2005-10-12 08:07:25Z yuppie $
-"""
-from zope.interface import Interface
-from zope.interface import Attribute
-
-class IFilesystemExporter(Interface):
- """ Plugin interface for site structure export.
- """
- def export(export_context, subdir):
- """ Export our 'context' using the API of 'export_context'.
-
- o 'export_context' must implement
- Products.GenericSupport.interfaces.IExportContext.
-
- o 'subdir', if passed, is the relative subdirectory containing our
- context within the site.
- """
-
- def listExportableItems():
- """ Return a sequence of the child items to be exported.
-
- o Each item in the returned sequence will be a tuple,
- (id, object, adapter) where adapter must implement
- IFilesystemExporter.
- """
-
-class IFilesystemImporter(Interface):
- """ Plugin interface for site structure export.
- """
- def import_(import_context, subdir):
- """ Import our 'context' using the API of 'import_context'.
-
- o 'import_context' must implement
- Products.GenericSupport.interfaces.IImportContext.
-
- o 'subdir', if passed, is the relative subdirectory containing our
- context within the site.
- """
-
-class ICSVAware(Interface):
- """ Interface for objects which dump / load 'text/comma-separated-values'.
- """
- def getId():
- """ Return the Zope id of the object.
- """
-
- def as_csv():
- """ Return a string representing the object as CSV.
- """
-
- def put_csv(fd):
- """ Parse CSV and update the object.
-
- o 'fd' must be a file-like object whose 'read' method returns
- CSV text parseable by the 'csv.reader'.
- """
-
-class IINIAware(Interface):
- """ Interface for objects which dump / load INI-format files..
- """
- def getId():
- """ Return the Zope id of the object.
- """
-
- def as_ini():
- """ Return a string representing the object as INI.
- """
-
- def put_ini(stream_or_text):
- """ Parse INI-formatted text and update the object.
-
- o 'stream_or_text' must be either a string, or else a stream
- directly parseable by ConfigParser.
- """
-
-class IDAVAware(Interface):
- """ Interface for objects which handle their own FTP / DAV operations.
- """
- def getId():
- """ Return the Zope id of the object.
- """
-
- def manage_FTPget():
- """ Return a string representing the object as a file.
- """
-
- def PUT(REQUEST, RESPONSE):
- """ Parse file content and update the object.
-
- o 'REQUEST' will have a 'get' method, which will have the
- content object in its "BODY" key. It will also have 'get_header'
- method, whose headers (e.g., "Content-Type") may affect the
- processing of the body.
- """
More information about the CMF-checkins
mailing list