[Checkins] SVN: CMF/branches/1.6/CMFCore/exportimport/ * adding support for '.delete' file to allow content import to delete content

Rob Miller ra at burningman.com
Sun Apr 2 00:58:07 EST 2006


Log message for revision 66292:
  * adding support for '.delete' file to allow content import to delete content
    that is not in the 'structure' hierarchy and thus will not be recreated
  
  

Changed:
  U   CMF/branches/1.6/CMFCore/exportimport/content.py
  U   CMF/branches/1.6/CMFCore/exportimport/tests/test_content.py

-=-
Modified: CMF/branches/1.6/CMFCore/exportimport/content.py
===================================================================
--- CMF/branches/1.6/CMFCore/exportimport/content.py	2006-04-02 03:31:54 UTC (rev 66291)
+++ CMF/branches/1.6/CMFCore/exportimport/content.py	2006-04-02 05:58:06 UTC (rev 66292)
@@ -14,6 +14,10 @@
 
 $Id: content.py 39878 2005-11-03 23:07:34Z tseaver $
 """
+try:
+    set = set
+except NameError:
+    from sets import Set as set
 
 from csv import reader
 from csv import register_dialect
@@ -58,6 +62,18 @@
 
     Subobjects themselves are represented as individual files or
     subdirectories within the parent's directory.
+
+    If the import step finds that any objects specified to be created by the
+    'structure' directory setup already exist, these objects will be deleted
+    and then recreated by the profile.  The existence of a '.preserve' file
+    within the 'structure' hierarchy allows specification of objects that
+    should not be deleted.  '.preserve' files should contain one preserve
+    rule per line, with shell-style globbing supported (i.e. 'b*' will match
+    all objects w/ id starting w/ 'b'.
+
+    Similarly, a '.delete' file can be used to specify the deletion of any
+    objects that exist in the site but are NOT in the 'structure' hierarchy,
+    and thus will not be recreated during the import process.
     """
 
     implements(IFilesystemExporter, IFilesystemImporter)
@@ -124,20 +140,31 @@
         stream = StringIO(objects)
         rowiter = reader(stream, dialect)
         ours = tuple(rowiter)
-        our_ids = [item[0] for item in ours]
+        our_ids = set([item[0] for item in ours])
 
+        prior = set(context.contentIds())
+
         preserve = import_context.readDataFile('.preserve', subdir)
-        prior = context.contentIds()
-
         if not preserve:
-            preserve = []
+            preserve = set()
         else:
-            preserve = _globtest(preserve, prior)
+            preservable = prior.intersection(our_ids)
+            preserve = set(_globtest(preserve, preservable))
 
-        for id in prior:
-            if id in our_ids and id not in preserve:
-                context._delObject(id)
+        delete = import_context.readDataFile('.delete', subdir)
+        if not delete:
+            delete= set()
+        else:
+            deletable = prior.difference(our_ids)
+            delete = set(_globtest(delete, deletable))
 
+        # if it's in our_ids and NOT in preserve, or if it's not in
+        # our_ids but IS in delete, we're gonna delete it
+        delete = our_ids.difference(preserve).union(delete)
+
+        for id in prior.intersection(delete):
+            context._delObject(id)
+
         existing = context.objectIds()
 
         for object_id, portal_type in ours:

Modified: CMF/branches/1.6/CMFCore/exportimport/tests/test_content.py
===================================================================
--- CMF/branches/1.6/CMFCore/exportimport/tests/test_content.py	2006-04-02 03:31:54 UTC (rev 66291)
+++ CMF/branches/1.6/CMFCore/exportimport/tests/test_content.py	2006-04-02 05:58:06 UTC (rev 66292)
@@ -539,6 +539,36 @@
             else:
                 self.assertEqual(getattr(obj, 'before', None), None)
 
+    def test_reimport_with_structure_partial_preserve_and_delete(self):
+        self._setUpAdapters()
+        ITEM_IDS = ('foo', 'bar', 'baz')
+
+        site = _makeFolder('site', site_folder=True)
+        for id in ITEM_IDS:
+            site._setObject(id, _makeINIAware(id))
+            site._getOb(id).before = True
+
+        context = DummyImportContext(site)
+        context._files['structure/.objects'] = '\n'.join(
+            ['%s,%s' % (x, TEST_INI_AWARE) for x in ITEM_IDS[:-1]])
+        for index in range(len(ITEM_IDS)):
+            id = ITEM_IDS[index]
+            context._files[
+                    'structure/%s.ini' % id] = KNOWN_INI % ('Title: %s' % id,
+                                                            'xyzzy',
+                                                           )
+        context._files['structure/.preserve'] = 'foo'
+        context._files['structure/.delete'] = 'baz'
+
+        importer = self._getImporter()
+        importer(context)
+
+        after = site.objectIds()
+        self.assertEqual(len(after), len(ITEM_IDS) - 1)
+        self.failIf('baz' in after)
+        self.assertEqual(getattr(site.foo, 'before', None), True)
+        self.failIf(hasattr(site.bar, 'before'))
+
     def test_import_site_with_subfolders_and_preserve(self):
         self._setUpAdapters()
 



More information about the Checkins mailing list