[CMF-checkins] SVN: CMF/trunk/GenericSetup/ Improved unicode handling by adding 'getEncoding' to all contexts, export as well as import.

Tres Seaver tseaver at palladion.com
Wed Sep 28 07:16:22 EDT 2005


Log message for revision 38662:
  Improved unicode handling by adding 'getEncoding' to all contexts, export as well as import.

Changed:
  U   CMF/trunk/GenericSetup/context.py
  U   CMF/trunk/GenericSetup/interfaces.py
  U   CMF/trunk/GenericSetup/tests/test_context.py

-=-
Modified: CMF/trunk/GenericSetup/context.py
===================================================================
--- CMF/trunk/GenericSetup/context.py	2005-09-28 10:35:29 UTC (rev 38661)
+++ CMF/trunk/GenericSetup/context.py	2005-09-28 11:16:22 UTC (rev 38662)
@@ -46,11 +46,12 @@
 
     security = ClassSecurityInfo()
 
-    def __init__( self, tool ):
+    def __init__( self, tool, encoding ):
 
         self._tool = tool
         self._site = aq_parent( aq_inner( tool ) )
         self._notes = []
+        self._encoding = encoding
 
     security.declareProtected( ManagePortal, 'getSite' )
     def getSite( self ):
@@ -66,6 +67,13 @@
         """
         return self._tool
 
+    security.declareProtected( ManagePortal, 'getEncoding' )
+    def getEncoding( self ):
+
+        """ See ISetupContext..
+        """
+        return self._encoding
+
     security.declareProtected( ManagePortal, 'notes' )
     def note( self, category, message ):
 
@@ -86,18 +94,10 @@
                 , encoding=None
                 ):
 
-        BaseContext.__init__( self, tool )
+        BaseContext.__init__( self, tool, encoding )
         self._profile_path = profile_path
         self._should_purge = bool( should_purge )
-        self._encoding = encoding
 
-    security.declareProtected( ManagePortal, 'getEncoding' )
-    def getEncoding( self ):
-
-        """ See IImportContext.
-        """
-        return self._encoding
-
     security.declareProtected( ManagePortal, 'readDataFile' )
     def readDataFile( self, filename, subdir=None ):
 
@@ -174,9 +174,9 @@
 
     security = ClassSecurityInfo()
 
-    def __init__( self, tool, profile_path ):
+    def __init__( self, tool, profile_path, encoding=None ):
 
-        BaseContext.__init__( self, tool )
+        BaseContext.__init__( self, tool, encoding )
         self._profile_path = profile_path
 
     security.declareProtected( ManagePortal, 'writeDataFile' )
@@ -211,20 +211,13 @@
 
     def __init__( self, tool, archive_bits, encoding=None, should_purge=False ):
 
-        BaseContext.__init__( self, tool )
+        BaseContext.__init__( self, tool, encoding )
         timestamp = time.gmtime()
         self._archive_stream = StringIO(archive_bits)
         self._archive = TarFile.open( 'foo.bar', 'r:gz'
                                     , self._archive_stream )
-        self._encoding = encoding
         self._should_purge = bool( should_purge )
 
-    def getEncoding( self ):
-
-        """ See IImportContext.
-        """
-        return self._encoding
-
     def readDataFile( self, filename, subdir=None ):
 
         """ See IImportContext.
@@ -300,9 +293,10 @@
 
     security = ClassSecurityInfo()
 
-    def __init__( self, tool ):
+    def __init__( self, tool, encoding=None ):
 
-        BaseContext.__init__( self, tool )
+        BaseContext.__init__( self, tool, encoding )
+
         timestamp = time.gmtime()
         archive_name = ( 'setup_tool-%4d%02d%02d%02d%02d%02d.tar.gz'
                        % timestamp[:6] )
@@ -350,9 +344,9 @@
 
     security = ClassSecurityInfo()
 
-    def __init__( self, tool, snapshot_id ):
+    def __init__( self, tool, snapshot_id, encoding=None ):
 
-        BaseContext.__init__( self, tool )
+        BaseContext.__init__( self, tool, encoding )
         self._snapshot_id = snapshot_id
 
     security.declareProtected( ManagePortal, 'writeDataFile' )
@@ -386,6 +380,13 @@
     security.declarePrivate( '_createObjectByType' )
     def _createObjectByType( self, name, body, content_type ):
 
+        if isinstance( body, unicode ):
+            encoding = self.getEncoding()
+            if encoding is None:
+                body = body.encode()
+            else:
+                body = body.encode( encoding )
+
         if name.endswith('.py'):
 
             ob = PythonScript( name )
@@ -398,7 +399,7 @@
 
         elif content_type in ('text/html', 'text/xml' ):
 
-            ob = ZopePageTemplate( name, str( body )
+            ob = ZopePageTemplate( name, body
                                  , content_type=content_type )
 
         elif content_type[:6]=='image/':
@@ -448,20 +449,11 @@
                 , encoding=None
                 ):
 
-        BaseContext.__init__( self, tool )
+        BaseContext.__init__( self, tool, encoding )
         self._snapshot_id = snapshot_id
         self._encoding = encoding
         self._should_purge = bool( should_purge )
 
-    security.declareProtected( ManagePortal, 'getEncoding' )
-    def getEncoding( self ):
-
-        """ Return the encoding used in data files.
-
-        o Return None if the data should not be encoded.
-        """
-        return self._encoding
-
     security.declareProtected( ManagePortal, 'readDataFile' )
     def readDataFile( self, filename, subdir=None ):
 

Modified: CMF/trunk/GenericSetup/interfaces.py
===================================================================
--- CMF/trunk/GenericSetup/interfaces.py	2005-09-28 10:35:29 UTC (rev 38661)
+++ CMF/trunk/GenericSetup/interfaces.py	2005-09-28 11:16:22 UTC (rev 38662)
@@ -40,6 +40,13 @@
         """ Return the site object being configured / dumped.
         """
 
+    def getEncoding():
+
+        """ Get the encoding used for configuration data within the site.
+
+        o Return None if the data should not be encoded.
+        """
+
     def note(category, message):
 
         """ Record a logging message from within a handler.
@@ -54,13 +61,6 @@
 
 class IImportContext( ISetupContext ):
 
-    def getEncoding():
-
-        """ Get the encoding used for configuration data within the site.
-
-        o Return None if the data should not be encoded.
-        """
-
     def readDataFile( filename, subdir=None ):
 
         """ Search the current configuration for the requested file.

Modified: CMF/trunk/GenericSetup/tests/test_context.py
===================================================================
--- CMF/trunk/GenericSetup/tests/test_context.py	2005-09-28 10:35:29 UTC (rev 38661)
+++ CMF/trunk/GenericSetup/tests/test_context.py	2005-09-28 11:16:22 UTC (rev 38662)
@@ -758,7 +758,7 @@
 
         from OFS.Image import Image
         FILENAME = 'simple.txt'
-        _CONTENT_TYPE = 'image/png'
+        CONTENT_TYPE = 'image/png'
         png_filename = os.path.join( os.path.split( __file__ )[0]
                                    , 'simple.png' )
         png_file = open( png_filename, 'rb' )
@@ -770,7 +770,7 @@
         tool = site.setup_tool
         ctx = self._makeOne( tool, 'simple' )
 
-        ctx.writeDataFile( FILENAME, png_data, _CONTENT_TYPE )
+        ctx.writeDataFile( FILENAME, png_data, CONTENT_TYPE )
 
         snapshot = tool.snapshots._getOb( 'simple' )
 
@@ -781,7 +781,7 @@
 
         self.assertEqual( fileobj.getId(), FILENAME )
         self.assertEqual( fileobj.meta_type, Image.meta_type )
-        self.assertEqual( fileobj.getContentType(), _CONTENT_TYPE )
+        self.assertEqual( fileobj.getContentType(), CONTENT_TYPE )
         self.assertEqual( fileobj.data, png_data )
 
     def test_writeDataFile_simple_plain_text( self ):
@@ -789,14 +789,14 @@
         from string import digits
         from OFS.Image import File
         FILENAME = 'simple.txt'
-        _CONTENT_TYPE = 'text/plain'
+        CONTENT_TYPE = 'text/plain'
 
         site = DummySite( 'site' ).__of__( self.root )
         site.setup_tool = DummyTool( 'setup_tool' )
         tool = site.setup_tool
         ctx = self._makeOne( tool, 'simple' )
 
-        ctx.writeDataFile( FILENAME, digits, _CONTENT_TYPE )
+        ctx.writeDataFile( FILENAME, digits, CONTENT_TYPE )
 
         snapshot = tool.snapshots._getOb( 'simple' )
 
@@ -807,14 +807,42 @@
 
         self.assertEqual( fileobj.getId(), FILENAME )
         self.assertEqual( fileobj.meta_type, File.meta_type )
-        self.assertEqual( fileobj.getContentType(), _CONTENT_TYPE )
+        self.assertEqual( fileobj.getContentType(), CONTENT_TYPE )
         self.assertEqual( str( fileobj ), digits )
 
+    def test_writeDataFile_simple_plain_text_unicode( self ):
+
+        from string import digits
+        from OFS.Image import File
+        FILENAME = 'simple.txt'
+        CONTENT_TYPE = 'text/plain'
+        CONTENT = u'Unicode, with non-ASCII: %s.' % unichr(150)
+
+        site = DummySite( 'site' ).__of__( self.root )
+        site.setup_tool = DummyTool( 'setup_tool' )
+        tool = site.setup_tool
+        ctx = self._makeOne( tool, 'simple', 'latin_1' )
+
+        ctx.writeDataFile( FILENAME, CONTENT, CONTENT_TYPE )
+
+        snapshot = tool.snapshots._getOb( 'simple' )
+
+        self.assertEqual( len( snapshot.objectIds() ), 1 )
+        self.failUnless( FILENAME in snapshot.objectIds() )
+
+        fileobj = snapshot._getOb( FILENAME )
+
+        self.assertEqual( fileobj.getId(), FILENAME )
+        self.assertEqual( fileobj.meta_type, File.meta_type )
+        self.assertEqual( fileobj.getContentType(), CONTENT_TYPE )
+        saved = fileobj.manage_FTPget().decode('latin_1')
+        self.assertEqual( saved, CONTENT )
+
     def test_writeDataFile_simple_xml( self ):
 
         from Products.PageTemplates.ZopePageTemplate import ZopePageTemplate
         FILENAME = 'simple.xml'
-        _CONTENT_TYPE = 'text/xml'
+        CONTENT_TYPE = 'text/xml'
         _XML = """<?xml version="1.0"?><simple />"""
 
         site = DummySite( 'site' ).__of__( self.root )
@@ -822,7 +850,7 @@
         tool = site.setup_tool
         ctx = self._makeOne( tool, 'simple' )
 
-        ctx.writeDataFile( FILENAME, _XML, _CONTENT_TYPE )
+        ctx.writeDataFile( FILENAME, _XML, CONTENT_TYPE )
 
         snapshot = tool.snapshots._getOb( 'simple' )
 
@@ -840,7 +868,7 @@
 
         from Products.PageTemplates.ZopePageTemplate import ZopePageTemplate
         FILENAME = 'simple.xml'
-        _CONTENT_TYPE = 'text/xml'
+        CONTENT_TYPE = 'text/xml'
         _XML = u"""<?xml version="1.0"?><simple />"""
 
         site = DummySite( 'site' ).__of__( self.root )
@@ -848,7 +876,7 @@
         tool = site.setup_tool
         ctx = self._makeOne( tool, 'simple' )
 
-        ctx.writeDataFile( FILENAME, _XML, _CONTENT_TYPE )
+        ctx.writeDataFile( FILENAME, _XML, CONTENT_TYPE )
 
         snapshot = tool.snapshots._getOb( 'simple' )
 
@@ -866,7 +894,7 @@
 
         from OFS.DTMLDocument import DTMLDocument
         FILENAME = 'simple.dtml'
-        _CONTENT_TYPE = 'text/html'
+        CONTENT_TYPE = 'text/html'
         _HTML = """<html><body><h1>HTML</h1></body></html>"""
 
         site = DummySite( 'site' ).__of__( self.root )
@@ -874,7 +902,7 @@
         tool = site.setup_tool
         ctx = self._makeOne( tool, 'simple' )
 
-        ctx.writeDataFile( FILENAME, _HTML, _CONTENT_TYPE, 'sub1' )
+        ctx.writeDataFile( FILENAME, _HTML, CONTENT_TYPE, 'sub1' )
 
         snapshot = tool.snapshots._getOb( 'simple' )
         sub1 = snapshot._getOb( 'sub1' )
@@ -892,7 +920,7 @@
 
         from Products.PageTemplates.ZopePageTemplate import ZopePageTemplate
         FILENAME = 'simple.html'
-        _CONTENT_TYPE = 'text/html'
+        CONTENT_TYPE = 'text/html'
         _HTML = """<html><body><h1>HTML</h1></body></html>"""
 
         site = DummySite( 'site' ).__of__( self.root )
@@ -900,7 +928,7 @@
         tool = site.setup_tool
         ctx = self._makeOne( tool, 'simple' )
 
-        ctx.writeDataFile( FILENAME, _HTML, _CONTENT_TYPE, 'sub1/sub2' )
+        ctx.writeDataFile( FILENAME, _HTML, CONTENT_TYPE, 'sub1/sub2' )
 
         snapshot = tool.snapshots._getOb( 'simple' )
         sub1 = snapshot._getOb( 'sub1' )



More information about the CMF-checkins mailing list