[Checkins] SVN: Products.CMFCore/trunk/ Fix content exportimport when Title or Description are unicode (merge from

Godefroid Chapelle gotcha at bubblenet.be
Thu Jan 13 11:47:46 EST 2011


Log message for revision 119569:
  Fix content exportimport when Title or Description are unicode (merge from
    2.2 branch).
  

Changed:
  _U  Products.CMFCore/trunk/
  U   Products.CMFCore/trunk/Products/CMFCore/CHANGES.txt
  U   Products.CMFCore/trunk/Products/CMFCore/exportimport/content.py
  U   Products.CMFCore/trunk/Products/CMFCore/exportimport/tests/test_content.py

-=-

Property changes on: Products.CMFCore/trunk
___________________________________________________________________
Modified: svn:ignore
   - *.pyc
build
dist
Products.CMFCore.egg-info
eggtestinfo-*.egg

   + *.pyc
build
dist
Products.CMFCore.egg-info
eggtestinfo-*.egg
develop-eggs
bin
parts
.installed.cfg


Modified: Products.CMFCore/trunk/Products/CMFCore/CHANGES.txt
===================================================================
--- Products.CMFCore/trunk/Products/CMFCore/CHANGES.txt	2011-01-13 16:40:47 UTC (rev 119568)
+++ Products.CMFCore/trunk/Products/CMFCore/CHANGES.txt	2011-01-13 16:47:46 UTC (rev 119569)
@@ -4,6 +4,9 @@
 2.3.0-alpha (unreleased)
 ------------------------
 
+- Fix content exportimport when Title or Description are unicode (merge from
+  2.2 branch).
+  
 - tests base: Tightened security for anonymous test user.
 
 - Load permissions.zcml from Products.Five in the test to fix tests

Modified: Products.CMFCore/trunk/Products/CMFCore/exportimport/content.py
===================================================================
--- Products.CMFCore/trunk/Products/CMFCore/exportimport/content.py	2011-01-13 16:40:47 UTC (rev 119568)
+++ Products.CMFCore/trunk/Products/CMFCore/exportimport/content.py	2011-01-13 16:47:46 UTC (rev 119569)
@@ -37,6 +37,16 @@
     IFilesystemImporter(context.getSite()).import_(context, 'structure', True)
 
 
+def encode_if_needed(text, encoding):
+    if isinstance(text, unicode):
+        result = text.encode(encoding)
+    else:
+        # no need to encode;
+        # let's avoid double encoding in case of encoded string
+        result = text
+    return result
+
+
 #
 #   Filesystem export/import adapters
 #
@@ -76,6 +86,8 @@
     def export(self, export_context, subdir, root=False):
         """ See IFilesystemExporter.
         """
+        self._encoding = self.context.getProperty('default_charset', 'utf-8')
+
         # Enumerate exportable children
         exportable = self.context.contentItems()
         exportable = [x + (IFilesystemExporter(x, None),) for x in exportable]
@@ -98,8 +110,14 @@
 
         parser = ConfigParser()
 
-        parser.set('DEFAULT', 'Title', self.context.Title())
-        parser.set('DEFAULT', 'Description', self.context.Description())
+        title = self.context.Title()
+        description = self.context.Description()
+        # encode if needed; ConfigParser does not support unicode !
+        title_str = encode_if_needed(title, self._encoding)
+        description_str = encode_if_needed(description, self._encoding)
+        parser.set('DEFAULT', 'Title', title_str)
+        parser.set('DEFAULT', 'Description', description_str)
+
         stream = StringIO()
         parser.write(stream)
 

Modified: Products.CMFCore/trunk/Products/CMFCore/exportimport/tests/test_content.py
===================================================================
--- Products.CMFCore/trunk/Products/CMFCore/exportimport/tests/test_content.py	2011-01-13 16:40:47 UTC (rev 119568)
+++ Products.CMFCore/trunk/Products/CMFCore/exportimport/tests/test_content.py	2011-01-13 16:47:46 UTC (rev 119569)
@@ -180,6 +180,54 @@
         self.assertEqual(parser.get('DEFAULT', 'title'), 'AAA')
         self.assertEqual(parser.get('DEFAULT', 'description'), 'DESCRIPTION')
 
+    def test_export_site_with_exportable_simple_items_encoded_string(self):
+        self._setUpAdapters()
+        ITEM_IDS = ('foo', 'bar', 'baz')
+
+        site = _makeFolder('site', site_folder=True)
+        site.title = 'AAA'
+        site.description = 'DESCRIPTION'
+        ITEMS_TITLE = u'Actualit\xe9'
+        ITEMS_DESCRIPTION = u'Actualit\xe9 r\xe9centes'
+        for id in ITEM_IDS:
+            site._setObject(id, _makeINIAware(id))
+            item = getattr(site, id)
+            item.setTitle(ITEMS_TITLE.encode('utf8'))
+            item.setDescription(ITEMS_DESCRIPTION.encode('utf8'))
+
+        context = DummyExportContext(site)
+        exporter = self._getExporter()
+        exporter(context)
+
+        self.assertEqual(len(context._wrote), 2 + len(ITEM_IDS))
+        filename, text, content_type = context._wrote[0]
+        self.assertEqual(filename, 'structure/.objects')
+        self.assertEqual(content_type, 'text/comma-separated-values')
+
+        objects = [x for x in reader(StringIO(text))]
+        self.assertEqual(len(objects), 3)
+        for index in range(len(ITEM_IDS)):
+            self.assertEqual(objects[index][0], ITEM_IDS[index])
+            self.assertEqual(objects[index][1], TEST_INI_AWARE)
+
+            filename, text, content_type = context._wrote[index+2]
+            self.assertEqual(filename, 'structure/%s.ini' % ITEM_IDS[index])
+            object = site._getOb(ITEM_IDS[index])
+            self.assertEqual(text.strip(),
+                             object.as_ini().strip())
+            self.assertEqual(content_type, 'text/plain')
+
+        filename, text, content_type = context._wrote[1]
+        self.assertEqual(filename, 'structure/.properties')
+        self.assertEqual(content_type, 'text/plain')
+        parser = ConfigParser()
+        parser.readfp(StringIO(text))
+
+        self.assertEqual(parser.get('DEFAULT', 'title'),
+            ITEMS_TITLE.encode('utf8'))
+        self.assertEqual(parser.get('DEFAULT', 'description'),
+            ITEMS_DESCRIPTION.encode('utf8'))
+
     def test_export_site_with_exportable_simple_items(self):
         self._setUpAdapters()
         ITEM_IDS = ('foo', 'bar', 'baz')
@@ -221,6 +269,103 @@
         self.assertEqual(parser.get('DEFAULT', 'title'), 'AAA')
         self.assertEqual(parser.get('DEFAULT', 'description'), 'DESCRIPTION')
 
+    def test_export_site_with_exportable_simple_items_unicode_default_charset(self):
+        self._setUpAdapters()
+        ITEM_IDS = ('foo', 'bar', 'baz')
+
+        site = _makeFolder('site', site_folder=True)
+        site.title = 'AAA'
+        site.description = 'DESCRIPTION'
+        ITEMS_TITLE = u'Actualit\xe9'
+        ITEMS_DESCRIPTION = u'Actualit\xe9 r\xe9centes'
+        for id in ITEM_IDS:
+            site._setObject(id, _makeINIAware(id))
+            item = getattr(site, id)
+            item.setTitle(ITEMS_TITLE)
+            item.setDescription(ITEMS_DESCRIPTION)
+
+        context = DummyExportContext(site)
+        exporter = self._getExporter()
+        exporter(context)
+
+        self.assertEqual(len(context._wrote), 2 + len(ITEM_IDS))
+        filename, text, content_type = context._wrote[0]
+        self.assertEqual(filename, 'structure/.objects')
+        self.assertEqual(content_type, 'text/comma-separated-values')
+
+        objects = [x for x in reader(StringIO(text))]
+        self.assertEqual(len(objects), 3)
+        for index in range(len(ITEM_IDS)):
+            self.assertEqual(objects[index][0], ITEM_IDS[index])
+            self.assertEqual(objects[index][1], TEST_INI_AWARE)
+
+            filename, text, content_type = context._wrote[index+2]
+            self.assertEqual(filename, 'structure/%s.ini' % ITEM_IDS[index])
+            object = site._getOb(ITEM_IDS[index])
+            self.assertEqual(text.strip(),
+                             object.as_ini().strip())
+            self.assertEqual(content_type, 'text/plain')
+
+        filename, text, content_type = context._wrote[1]
+        self.assertEqual(filename, 'structure/.properties')
+        self.assertEqual(content_type, 'text/plain')
+        parser = ConfigParser()
+        parser.readfp(StringIO(text))
+
+        self.assertEqual(parser.get('DEFAULT', 'title'),
+            ITEMS_TITLE.encode('utf8'))
+        self.assertEqual(parser.get('DEFAULT', 'description'),
+            ITEMS_DESCRIPTION.encode('utf8'))
+
+    def test_export_site_with_exportable_simple_items_unicode_latin1(self):
+        self._setUpAdapters()
+        ITEM_IDS = ('foo', 'bar', 'baz')
+
+        site = _makeFolder('site', site_folder=True)
+        site._setProperty('default_charset', 'iso-8859-1', 'string')
+        site.title = 'AAA'
+        site.description = 'DESCRIPTION'
+        ITEMS_TITLE = u'Actualit\xe9'
+        ITEMS_DESCRIPTION = u'Actualit\xe9 r\xe9centes'
+        for id in ITEM_IDS:
+            site._setObject(id, _makeINIAware(id))
+            item = getattr(site, id)
+            item.setTitle(ITEMS_TITLE)
+            item.setDescription(ITEMS_DESCRIPTION)
+
+        context = DummyExportContext(site)
+        exporter = self._getExporter()
+        exporter(context)
+
+        self.assertEqual(len(context._wrote), 2 + len(ITEM_IDS))
+        filename, text, content_type = context._wrote[0]
+        self.assertEqual(filename, 'structure/.objects')
+        self.assertEqual(content_type, 'text/comma-separated-values')
+
+        objects = [x for x in reader(StringIO(text))]
+        self.assertEqual(len(objects), 3)
+        for index in range(len(ITEM_IDS)):
+            self.assertEqual(objects[index][0], ITEM_IDS[index])
+            self.assertEqual(objects[index][1], TEST_INI_AWARE)
+
+            filename, text, content_type = context._wrote[index+2]
+            self.assertEqual(filename, 'structure/%s.ini' % ITEM_IDS[index])
+            object = site._getOb(ITEM_IDS[index])
+            self.assertEqual(text.strip(),
+                             object.as_ini().strip())
+            self.assertEqual(content_type, 'text/plain')
+
+        filename, text, content_type = context._wrote[1]
+        self.assertEqual(filename, 'structure/.properties')
+        self.assertEqual(content_type, 'text/plain')
+        parser = ConfigParser()
+        parser.readfp(StringIO(text))
+
+        self.assertEqual(parser.get('DEFAULT', 'title'),
+            ITEMS_TITLE.encode('latin1'))
+        self.assertEqual(parser.get('DEFAULT', 'description'),
+            ITEMS_DESCRIPTION.encode('latin1'))
+
     def test_export_site_with_subfolders(self):
         self._setUpAdapters()
         FOLDER_IDS = ('foo', 'bar', 'baz')



More information about the checkins mailing list