[CMF-checkins] SVN: CMF/trunk/ Land changes from original repo for GenericSetup 0.11 and 0.12 (merge from tseaver-resync_GenericSetup branch).

Tres Seaver tseaver at palladion.com
Fri Nov 18 16:22:14 EST 2005


Log message for revision 40234:
  Land changes from original repo for GenericSetup 0.11 and 0.12 (merge from tseaver-resync_GenericSetup branch).

Changed:
  U   CMF/trunk/CMFCore/exportimport/content.py
  U   CMF/trunk/CMFCore/exportimport/tests/test_content.py
  U   CMF/trunk/GenericSetup/CHANGES.txt
  U   CMF/trunk/GenericSetup/content.py
  U   CMF/trunk/GenericSetup/context.py
  U   CMF/trunk/GenericSetup/interfaces.py
  U   CMF/trunk/GenericSetup/rolemap.py
  U   CMF/trunk/GenericSetup/tests/common.py
  U   CMF/trunk/GenericSetup/tests/test_content.py
  U   CMF/trunk/GenericSetup/tests/test_context.py
  U   CMF/trunk/GenericSetup/tests/test_tool.py
  U   CMF/trunk/GenericSetup/tool.py
  U   CMF/trunk/GenericSetup/version.txt
  U   CMF/trunk/GenericSetup/www/sutImportSteps.zpt

-=-
Modified: CMF/trunk/CMFCore/exportimport/content.py
===================================================================
--- CMF/trunk/CMFCore/exportimport/content.py	2005-11-18 19:31:10 UTC (rev 40233)
+++ CMF/trunk/CMFCore/exportimport/content.py	2005-11-18 21:22:13 UTC (rev 40234)
@@ -145,9 +145,9 @@
                 object = self._makeInstance(object_id, portal_type,
                                             subdir, import_context)
                 if object is None:
-                    message = "Couldn't make instance: %s/%s" % (subdir,
-                                                                 object_id)
-                    import_context.note('SFWA', message)
+                    logger = import_context.getLogger('SFWA')
+                    logger.warning("Couldn't make instance: %s/%s" %
+                                   (subdir, object_id))
                     continue
 
             wrapped = context._getOb(object_id)

Modified: CMF/trunk/CMFCore/exportimport/tests/test_content.py
===================================================================
--- CMF/trunk/CMFCore/exportimport/tests/test_content.py	2005-11-18 19:31:10 UTC (rev 40233)
+++ CMF/trunk/CMFCore/exportimport/tests/test_content.py	2005-11-18 21:22:13 UTC (rev 40234)
@@ -431,7 +431,7 @@
         after = site.objectIds()
         self.assertEqual(len(after), 0)
         self.assertEqual(len(context._notes), len(ITEM_IDS))
-        for component, message in context._notes:
+        for level, component, message in context._notes:
             self.assertEqual(component, 'SFWA')
             self.failUnless(message.startswith("Couldn't make"))
 

Modified: CMF/trunk/GenericSetup/CHANGES.txt
===================================================================
--- CMF/trunk/GenericSetup/CHANGES.txt	2005-11-18 19:31:10 UTC (rev 40233)
+++ CMF/trunk/GenericSetup/CHANGES.txt	2005-11-18 21:22:13 UTC (rev 40234)
@@ -1,5 +1,10 @@
 GenericSetup Product Changelog
 
+  After GenericSetup 1.0
+
+    - Forward ported changes from GenericSetup 0.11 and 0.12 (which were
+      created in a separate repository).
+
   GenericSetup 1.0 (2005/09/23)
 
     - CVS tag:  GenericSetup-1_0
@@ -11,6 +16,25 @@
 
     - Forward ported fix for tools with non unique IDs from CMFSetup.
 
+  GenericSetup-0.12 (2005/08/29)
+
+    - CVS tag:  GenericSetup-0_12
+
+    - Import requests now create reports (by default) which record any
+      status messages generated by the profile's steps.
+
+  GenericSetup-0.11 (2005/08/23)
+
+    - CVS tag:  GenericSetup-0_11
+
+    - Added report of messages generated by import to the "Import" tab.
+
+    - Consolidated ISetupContext implementation into base class,
+      'SetupContextBase'.
+
+    - Added 'note', 'listNotes', and 'clearNotes'  methods to ISetupContext,
+      to allow plugins to record information about the state of the operation.
+
   GenericSetup 0.10 (2005/08/11)
 
     - CVS tag:  GenericSetup-0_10

Modified: CMF/trunk/GenericSetup/content.py
===================================================================
--- CMF/trunk/GenericSetup/content.py	2005-11-18 19:31:10 UTC (rev 40233)
+++ CMF/trunk/GenericSetup/content.py	2005-11-18 21:22:13 UTC (rev 40234)
@@ -172,9 +172,9 @@
                 object = self._makeInstance(object_id, type_name,
                                             subdir, import_context)
                 if object is None:
-                    message = "Couldn't make instance: %s/%s" % (subdir,
-                                                                 object_id)
-                    import_context.note('SFWA', message)
+                    logger = import_context.getLogger('SFWA')
+                    logger.warning("Couldn't make instance: %s/%s" %
+                                   (subdir, object_id))
                     continue
 
             wrapped = context._getOb(object_id)
@@ -268,8 +268,8 @@
         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))
+            logger = import_context.getLogger('CSAFA')
+            logger.info('no .csv file for %s/%s' % (subdir, cid))
         else:
             stream = StringIO(data)
             self.context.put_csv(stream)
@@ -303,8 +303,8 @@
         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))
+            logger = import_context.getLogger('SGAIFA')
+            logger.info('no .ini file for %s/%s' % (subdir, cid))
         else:
             self.context.put_ini(data)
 
@@ -393,8 +393,8 @@
         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))
+            logger = import_context.getLogger('SGAIFA')
+            logger.info('no .ini file for %s/%s' % (subdir, cid))
         else:
             request = FauxDAVRequest(BODY=data, BODYFILE=StringIO(data))
             response = FauxDAVResponse()

Modified: CMF/trunk/GenericSetup/context.py
===================================================================
--- CMF/trunk/GenericSetup/context.py	2005-11-18 19:31:10 UTC (rev 40233)
+++ CMF/trunk/GenericSetup/context.py	2005-11-18 21:22:13 UTC (rev 40234)
@@ -17,6 +17,7 @@
 $Id$
 """
 
+import logging
 import os
 import time
 from StringIO import StringIO
@@ -40,8 +41,58 @@
 
 from interfaces import IExportContext
 from interfaces import IImportContext
+from interfaces import IWriteLogger
 from permissions import ManagePortal
 
+
+class Logger:
+
+    implements(IWriteLogger)
+
+    def __init__(self, id, messages):
+        """Initialize the logger with a name and an optional level.
+        """
+        self._id = id
+        self._messages = messages
+        self._logger = logging.getLogger('GenericSetup.%s' % id)
+
+    def debug(self, msg, *args, **kwargs):
+        """Log 'msg % args' with severity 'DEBUG'.
+        """
+        self.log(logging.DEBUG, msg, *args, **kwargs)
+
+    def info(self, msg, *args, **kwargs):
+        """Log 'msg % args' with severity 'INFO'.
+        """
+        self.log(logging.INFO, msg, *args, **kwargs)
+
+    def warning(self, msg, *args, **kwargs):
+        """Log 'msg % args' with severity 'WARNING'.
+        """
+        self.log(logging.WARNING, msg, *args, **kwargs)
+
+    def error(self, msg, *args, **kwargs):
+        """Log 'msg % args' with severity 'ERROR'.
+        """
+        self.log(logging.ERROR, msg, *args, **kwargs)
+
+    def exception(self, msg, *args):
+        """Convenience method for logging an ERROR with exception information.
+        """
+        self.error(msg, *args, **{'exc_info': 1})
+
+    def critical(self, msg, *args, **kwargs):
+        """Log 'msg % args' with severity 'CRITICAL'.
+        """
+        self.log(logging.CRITICAL, msg, *args, **kwargs)
+
+    def log(self, level, msg, *args, **kwargs):
+        """Log 'msg % args' with the integer severity 'level'.
+        """
+        self._messages.append((level, self._id, msg))
+        self._logger.log(level, msg, *args, **kwargs)
+
+
 class BaseContext( Implicit ):
 
     security = ClassSecurityInfo()
@@ -50,7 +101,8 @@
 
         self._tool = tool
         self._site = aq_parent( aq_inner( tool ) )
-        self._notes = []
+        self._loggers = {}
+        self._messages = []
         self._encoding = encoding
 
     security.declareProtected( ManagePortal, 'getSite' )
@@ -70,17 +122,31 @@
     security.declareProtected( ManagePortal, 'getEncoding' )
     def getEncoding( self ):
 
-        """ See ISetupContext..
+        """ See ISetupContext.
         """
         return self._encoding
 
-    security.declareProtected( ManagePortal, 'notes' )
-    def note( self, category, message ):
+    security.declareProtected( ManagePortal, 'getLogger' )
+    def getLogger( self, name ):
+        """ See ISetupContext.
+        """
+        return self._loggers.setdefault(name, Logger(name, self._messages))
 
+    security.declareProtected( ManagePortal, 'listNotes' )
+    def listNotes(self):
+
         """ See ISetupContext.
         """
-        self._notes.append( ( category, message ) )
+        return self._messages[:]
 
+    security.declareProtected( ManagePortal, 'clearNotes' )
+    def clearNotes(self):
+
+        """ See ISetupContext.
+        """
+        self._messages[:] = []
+
+
 class DirectoryImportContext( BaseContext ):
 
     implements(IImportContext)

Modified: CMF/trunk/GenericSetup/interfaces.py
===================================================================
--- CMF/trunk/GenericSetup/interfaces.py	2005-11-18 19:31:10 UTC (rev 40233)
+++ CMF/trunk/GenericSetup/interfaces.py	2005-11-18 21:22:13 UTC (rev 40234)
@@ -48,16 +48,18 @@
         o Return None if the data should not be encoded.
         """
 
-    def note(category, message):
+    def getLogger(name):
+        """ Get a logger with the specified name, creating it if necessary.
+        """
 
-        """ Record a logging message from within a handler.
+    def listNotes():
+        """ Return notes recorded by this context.
+        
+        o Result a sequence of (component, message) tuples
+        """
 
-        o 'category' is a string defining the source of the message.
-
-        o 'message' is the text of the message itself.
-
-        o XXX This API may disappear soon, to be replaced by a more
-          general annotation.
+    def clearNotes():
+        """ Clear all notes recorded by this context.
         """
 
 class IImportContext( ISetupContext ):
@@ -526,6 +528,40 @@
         """
 
 
+class IWriteLogger(Interface):
+
+    """Write methods used by the python logging Logger.
+    """
+
+    def debug(msg, *args, **kwargs):
+        """Log 'msg % args' with severity 'DEBUG'.
+        """
+
+    def info(msg, *args, **kwargs):
+        """Log 'msg % args' with severity 'INFO'.
+        """
+
+    def warning(msg, *args, **kwargs):
+        """Log 'msg % args' with severity 'WARNING'.
+        """
+
+    def error(msg, *args, **kwargs):
+        """Log 'msg % args' with severity 'ERROR'.
+        """
+
+    def exception(msg, *args):
+        """Convenience method for logging an ERROR with exception information.
+        """
+
+    def critical(msg, *args, **kwargs):
+        """Log 'msg % args' with severity 'CRITICAL'.
+        """
+
+    def log(level, msg, *args, **kwargs):
+        """Log 'msg % args' with the integer severity 'level'.
+        """
+
+
 class INodeExporter(Interface):
 
     """Node exporter.

Modified: CMF/trunk/GenericSetup/rolemap.py
===================================================================
--- CMF/trunk/GenericSetup/rolemap.py	2005-11-18 19:31:10 UTC (rev 40233)
+++ CMF/trunk/GenericSetup/rolemap.py	2005-11-18 21:22:13 UTC (rev 40234)
@@ -60,6 +60,7 @@
     """
     site = context.getSite()
     encoding = context.getEncoding()
+    logger = context.getLogger('rolemap')
 
     if context.shouldPurge():
 
@@ -102,7 +103,7 @@
                                   , permission[ 'acquire' ]
                                   )
 
-    return 'Role / permission map imported.'
+    logger.info('Role / permission map imported.')
 
 
 def exportRolemap( context ):
@@ -131,12 +132,14 @@
 
     """
     site = context.getSite()
+    logger = context.getLogger('rolemap')
+
     rc = RolemapConfigurator( site ).__of__( site )
     text = rc.generateXML()
 
     context.writeDataFile( _FILENAME, text, 'text/xml' )
 
-    return 'Role / permission map exported.'
+    logger.info('Role / permission map exported.')
 
 
 class RolemapConfigurator(ConfiguratorBase):

Modified: CMF/trunk/GenericSetup/tests/common.py
===================================================================
--- CMF/trunk/GenericSetup/tests/common.py	2005-11-18 19:31:10 UTC (rev 40233)
+++ CMF/trunk/GenericSetup/tests/common.py	2005-11-18 21:22:13 UTC (rev 40234)
@@ -174,12 +174,26 @@
         self._compareDOM( found, data )
 
 
+class DummyLogger:
+
+    def __init__(self, id, messages):
+        self._id = id
+        self._messages = messages
+
+    def info(self, msg, *args, **kwargs):
+        self._messages.append((20, self._id, msg))
+
+    def warning(self, msg, *args, **kwargs):
+        self._messages.append((30, self._id, msg))
+
+
 class DummyExportContext:
 
     def __init__( self, site, tool=None ):
         self._site = site
         self._tool = tool
         self._wrote = []
+        self._notes = []
 
     def getSite( self ):
         return self._site
@@ -187,11 +201,15 @@
     def getSetupTool( self ):
         return self._tool
 
+    def getLogger(self, name):
+        return DummyLogger(name, self._notes)
+
     def writeDataFile( self, filename, text, content_type, subdir=None ):
         if subdir is not None:
             filename = '%s/%s' % ( subdir, filename )
         self._wrote.append( ( filename, text, content_type ) )
 
+
 class DummyImportContext:
 
     def __init__( self, site, purge=True, encoding=None, tool=None ):
@@ -211,6 +229,9 @@
     def getEncoding( self ):
         return self._encoding
 
+    def getLogger(self, name):
+        return DummyLogger(name, self._notes)
+
     def readDataFile( self, filename, subdir=None ):
 
         if subdir is not None:
@@ -222,10 +243,7 @@
 
         return self._purge
 
-    def note( self, component, message ):
 
-        self._notes.append( ( component, message ) )
-
 def dummy_handler( context ):
 
     pass

Modified: CMF/trunk/GenericSetup/tests/test_content.py
===================================================================
--- CMF/trunk/GenericSetup/tests/test_content.py	2005-11-18 19:31:10 UTC (rev 40233)
+++ CMF/trunk/GenericSetup/tests/test_content.py	2005-11-18 21:22:13 UTC (rev 40234)
@@ -17,6 +17,8 @@
 
 import unittest
 import Testing
+import Zope2
+Zope2.startup()
 
 from csv import reader
 from ConfigParser import ConfigParser
@@ -576,7 +578,7 @@
         after = site.objectIds()
         self.assertEqual(len(after), 0)
         self.assertEqual(len(context._notes), len(ITEM_IDS))
-        for component, message in context._notes:
+        for level, component, message in context._notes:
             self.assertEqual(component, 'SFWA')
             self.failUnless(message.startswith("Couldn't make"))
 

Modified: CMF/trunk/GenericSetup/tests/test_context.py
===================================================================
--- CMF/trunk/GenericSetup/tests/test_context.py	2005-11-18 19:31:10 UTC (rev 40233)
+++ CMF/trunk/GenericSetup/tests/test_context.py	2005-11-18 21:22:13 UTC (rev 40234)
@@ -17,9 +17,8 @@
 
 import unittest
 import Testing
-import Zope2
-Zope2.startup()
 
+import logging
 import os
 import time
 from StringIO import StringIO
@@ -47,6 +46,7 @@
 
     pass
 
+
 class DirectoryImportContextTests( FilesystemTestBase
                                  , ConformsToISetupContext
                                  , ConformsToIImportContext
@@ -59,6 +59,24 @@
         from Products.GenericSetup.context import DirectoryImportContext
         return DirectoryImportContext
 
+    def test_getLogger( self ):
+
+        site = DummySite( 'site' ).__of__( self.root )
+        ctx = self._makeOne( site, self._PROFILE_PATH )
+        self.assertEqual( len( ctx.listNotes() ), 0 )
+
+        logger = ctx.getLogger('foo')
+        logger.info('bar')
+
+        self.assertEqual( len( ctx.listNotes() ), 1 )
+        level, component, message = ctx.listNotes()[0]
+        self.assertEqual( level, logging.INFO )
+        self.assertEqual( component, 'foo' )
+        self.assertEqual( message, 'bar' )
+
+        ctx.clearNotes()
+        self.assertEqual( len( ctx.listNotes() ), 0 )
+
     def test_readDataFile_nonesuch( self ):
 
         FILENAME = 'nonesuch.txt'
@@ -314,6 +332,7 @@
         self.failUnless( 'CVS' in names )
         self.failUnless( '.svn' in names )
 
+
 class DirectoryExportContextTests( FilesystemTestBase
                                  , ConformsToISetupContext
                                  , ConformsToIExportContext
@@ -326,6 +345,24 @@
         from Products.GenericSetup.context import DirectoryExportContext
         return DirectoryExportContext
 
+    def test_getLogger( self ):
+
+        site = DummySite( 'site' ).__of__( self.root )
+        ctx = self._makeOne( site, self._PROFILE_PATH )
+        self.assertEqual( len( ctx.listNotes() ), 0 )
+
+        logger = ctx.getLogger('foo')
+        logger.info('bar')
+
+        self.assertEqual( len( ctx.listNotes() ), 1 )
+        level, component, message = ctx.listNotes()[0]
+        self.assertEqual( level, logging.INFO )
+        self.assertEqual( component, 'foo' )
+        self.assertEqual( message, 'bar' )
+
+        ctx.clearNotes()
+        self.assertEqual( len( ctx.listNotes() ), 0 )
+
     def test_writeDataFile_simple( self ):
 
         from string import printable, digits
@@ -438,6 +475,23 @@
 
         return site, tool, ctx.__of__( tool )
 
+    def test_getLogger( self ):
+
+        site, tool, ctx = self._makeOne()
+        self.assertEqual( len( ctx.listNotes() ), 0 )
+
+        logger = ctx.getLogger('foo')
+        logger.info('bar')
+
+        self.assertEqual( len( ctx.listNotes() ), 1 )
+        level, component, message = ctx.listNotes()[0]
+        self.assertEqual( level, logging.INFO )
+        self.assertEqual( component, 'foo' )
+        self.assertEqual( message, 'bar' )
+
+        ctx.clearNotes()
+        self.assertEqual( len( ctx.listNotes() ), 0 )
+
     def test_ctorparms( self ):
 
         ENCODING = 'latin-1'
@@ -690,6 +744,25 @@
         from Products.GenericSetup.context import TarballExportContext
         return TarballExportContext
 
+    def test_getLogger( self ):
+
+        site = DummySite( 'site' ).__of__( self.root )
+        ctx = self._getTargetClass()( site )
+
+        self.assertEqual( len( ctx.listNotes() ), 0 )
+
+        logger = ctx.getLogger('foo')
+        logger.info('bar')
+
+        self.assertEqual( len( ctx.listNotes() ), 1 )
+        level, component, message = ctx.listNotes()[0]
+        self.assertEqual( level, logging.INFO )
+        self.assertEqual( component, 'foo' )
+        self.assertEqual( message, 'bar' )
+
+        ctx.clearNotes()
+        self.assertEqual( len( ctx.listNotes() ), 0 )
+
     def test_writeDataFile_simple( self ):
 
         from string import printable
@@ -754,6 +827,27 @@
 
         return self._getTargetClass()( *args, **kw )
 
+    def test_getLogger( self ):
+
+        site = DummySite( 'site' ).__of__( self.root )
+        site.setup_tool = DummyTool( 'setup_tool' )
+        tool = site.setup_tool
+        ctx = self._makeOne( tool, 'simple' )
+
+        self.assertEqual( len( ctx.listNotes() ), 0 )
+
+        logger = ctx.getLogger('foo')
+        logger.info('bar')
+
+        self.assertEqual( len( ctx.listNotes() ), 1 )
+        level, component, message = ctx.listNotes()[0]
+        self.assertEqual( level, logging.INFO )
+        self.assertEqual( component, 'foo' )
+        self.assertEqual( message, 'bar' )
+
+        ctx.clearNotes()
+        self.assertEqual( len( ctx.listNotes() ), 0 )
+
     def test_writeDataFile_simple_image( self ):
 
         from OFS.Image import Image
@@ -1024,6 +1118,25 @@
 
         return folder._getOb( filename )
 
+    def test_getLogger( self ):
+
+        SNAPSHOT_ID = 'note'
+        site, tool, ctx = self._makeOne( SNAPSHOT_ID )
+
+        self.assertEqual( len( ctx.listNotes() ), 0 )
+
+        logger = ctx.getLogger('foo')
+        logger.info('bar')
+
+        self.assertEqual( len( ctx.listNotes() ), 1 )
+        level, component, message = ctx.listNotes()[0]
+        self.assertEqual( level, logging.INFO )
+        self.assertEqual( component, 'foo' )
+        self.assertEqual( message, 'bar' )
+
+        ctx.clearNotes()
+        self.assertEqual( len( ctx.listNotes() ), 0 )
+
     def test_ctorparms( self ):
 
         SNAPSHOT_ID = 'ctorparms'

Modified: CMF/trunk/GenericSetup/tests/test_tool.py
===================================================================
--- CMF/trunk/GenericSetup/tests/test_tool.py	2005-11-18 19:31:10 UTC (rev 40233)
+++ CMF/trunk/GenericSetup/tests/test_tool.py	2005-11-18 21:22:13 UTC (rev 40234)
@@ -448,7 +448,7 @@
         self.assertEqual( len( result[ 'steps' ] ), 1 )
         self.assertEqual( result[ 'steps' ][ 0 ], 'step_registries' )
         self.assertEqual( result[ 'messages' ][ 'step_registries' ]
-                        , 'Step registries exported'
+                        , None
                         )
         fileish = StringIO( result[ 'tarball' ] )
 
@@ -473,7 +473,7 @@
         self.assertEqual( len( result[ 'steps' ] ), 1 )
         self.assertEqual( result[ 'steps' ][ 0 ], 'step_registries' )
         self.assertEqual( result[ 'messages' ][ 'step_registries' ]
-                        , 'Step registries exported'
+                        , None
                         )
         fileish = StringIO( result[ 'tarball' ] )
 
@@ -516,7 +516,7 @@
 
         self.failUnless( 'step_registries' in result[ 'steps' ] )
         self.assertEqual( result[ 'messages' ][ 'step_registries' ]
-                        , 'Step registries exported'
+                        , None
                         )
 
         fileish = StringIO( result[ 'tarball' ] )
@@ -553,7 +553,7 @@
         self.assertEqual( len( result[ 'steps' ] ), 1 )
         self.assertEqual( result[ 'steps' ][ 0 ], 'step_registries' )
         self.assertEqual( result[ 'messages' ][ 'step_registries' ]
-                        , 'Step registries exported'
+                        , None
                         )
 
         snapshot = result[ 'snapshot' ]

Modified: CMF/trunk/GenericSetup/tool.py
===================================================================
--- CMF/trunk/GenericSetup/tool.py	2005-11-18 19:31:10 UTC (rev 40233)
+++ CMF/trunk/GenericSetup/tool.py	2005-11-18 21:22:13 UTC (rev 40234)
@@ -23,6 +23,7 @@
 from Acquisition import aq_base
 from Globals import InitializeClass
 from OFS.Folder import Folder
+from OFS.Image import File
 from Products.PageTemplates.PageTemplateFile import PageTemplateFile
 from zope.interface import implements
 from zope.interface import implementedBy
@@ -52,6 +53,7 @@
     """ Built-in handler for exporting import / export step registries.
     """
     setup_tool = context.getSetupTool()
+    logger = context.getLogger('registries')
 
     import_steps_xml = setup_tool.getImportStepRegistry().generateXML()
     context.writeDataFile('import_steps.xml', import_steps_xml, 'text/xml')
@@ -59,7 +61,7 @@
     export_steps_xml = setup_tool.getExportStepRegistry().generateXML()
     context.writeDataFile('export_steps.xml', export_steps_xml, 'text/xml')
 
-    return 'Step registries exported'
+    logger.info('Step registries exported.')
 
 def importToolset(context):
 
@@ -67,10 +69,12 @@
     """
     site = context.getSite()
     encoding = context.getEncoding()
+    logger = context.getLogger('toolset')
 
     xml = context.readDataFile(TOOLSET_XML)
     if xml is None:
-        return 'Toolset: Nothing to import.'
+        logger.info('Nothing to import.')
+        return
 
     setup_tool = context.getSetupTool()
     toolset = setup_tool.getToolsetRegistry()
@@ -107,7 +111,7 @@
                 site._delObject(tool_id)
                 site._setObject(tool_id, tool_class())
 
-    return 'Toolset imported.'
+    logger.info('Toolset imported.')
 
 def exportToolset(context):
 
@@ -115,11 +119,12 @@
     """
     setup_tool = context.getSetupTool()
     toolset = setup_tool.getToolsetRegistry()
+    logger = context.getLogger('toolset')
 
     xml = toolset.generateXML()
     context.writeDataFile(TOOLSET_XML, xml, 'text/xml')
 
-    return 'Toolset exported.'
+    logger.info('Toolset exported.')
 
 
 class SetupTool(Folder):
@@ -219,7 +224,9 @@
                     steps.append(dependency)
 
         message = self._doRunImportStep(step_id, context)
-        messages[step_id] = message
+        message_list = filter(None, [message])
+        message_list.extend( ['%s: %s' % x[1:] for x in context.listNotes()] )
+        messages[step_id] = '\n'.join(message_list)
         steps.append(step_id)
 
         return { 'steps' : steps, 'messages' : messages }
@@ -236,7 +243,11 @@
 
         for step in steps:
             message = self._doRunImportStep(step, context)
-            messages[step] = message
+            message_list = filter(None, [message])
+            message_list.extend( ['%s: %s' % x[1:]
+                                  for x in context.listNotes()] )
+            messages[step] = '\n'.join(message_list)
+            context.clearNotes()
 
         return { 'steps' : steps, 'messages' : messages }
 
@@ -389,34 +400,45 @@
                                    ids,
                                    run_dependencies,
                                    RESPONSE,
+                                   create_report=True,
                                   ):
         """ Import the steps selected by the user.
         """
         if not ids:
-            message = 'No+steps+selected.'
+            summary = 'No+steps+selected.'
 
         else:
             steps_run = []
+            messages = {}
             for step_id in ids:
                 result = self.runImportStep(step_id, run_dependencies)
                 steps_run.extend(result['steps'])
+                messages.update(result['messages'])
 
-            message = 'Steps+run:%s' % '+,'.join(steps_run)
+            summary = 'Steps+run:%s' % '+,'.join(steps_run)
 
-        RESPONSE.redirect('%s/manage_importSteps?manage_tabs_message=%s'
-                         % (self.absolute_url(), message))
+        if create_report:
+            name = self._mangleTimestampName('import-selected', 'log')
+            self._createReport(name, result['steps'], result['messages'])
 
+        return self.manage_importSteps(manage_tabs_message=summary,
+                                       messages=messages)
+
     security.declareProtected(ManagePortal, 'manage_importSelectedSteps')
-    def manage_importAllSteps(self, RESPONSE):
+    def manage_importAllSteps(self, RESPONSE, create_report=True):
 
         """ Import all steps.
         """
         result = self.runAllImportSteps()
-        message = 'Steps+run:%s' % '+,'.join(result['steps'])
+        steps_run = 'Steps+run:%s' % '+,'.join(result['steps'])
 
-        RESPONSE.redirect('%s/manage_importSteps?manage_tabs_message=%s'
-                         % (self.absolute_url(), message))
+        if create_report:
+            name = self._mangleTimestampName('import-all', 'log')
+            self._createReport(name, result['steps'], result['messages'])
 
+        return self.manage_importSteps(manage_tabs_message=steps_run,
+                                       messages=result['messages'])
+
     security.declareProtected(ManagePortal, 'manage_exportSteps')
     manage_exportSteps = PageTemplateFile('sutExportSteps', _wwwdir)
 
@@ -517,8 +539,7 @@
         o If no ID is passed, generate one.
         """
         if snapshot_id is None:
-            timestamp = time.gmtime()
-            snapshot_id = 'snapshot-%4d%02d%02d%02d%02d%02d' % timestamp[:6]
+            snapshot_id = self._mangleTimestampName('snapshot')
 
         self.createSnapshot(snapshot_id)
 
@@ -713,6 +734,48 @@
                , 'filename' : context.getArchiveFilename()
                }
 
+    security.declarePrivate('_mangleTimestampName')
+    def _mangleTimestampName(self, prefix, ext=None):
+
+        """ Create a mangled ID using a timestamp.
+        """
+        timestamp = time.gmtime()
+        items = (prefix,) + timestamp[:6]
+
+        if ext is None:
+            fmt = '%s-%4d%02d%02d%02d%02d%02d'
+        else:
+            fmt = '%s-%4d%02d%02d%02d%02d%02d.%s'
+            items += (ext,)
+
+        return fmt % items
+
+    security.declarePrivate('_createReport')
+    def _createReport(self, name, steps, messages):
+
+        """ Record the results of a run.
+        """
+        lines = []
+        # Create report
+        for step in steps:
+            lines.append('=' * 65)
+            lines.append('Step: %s' % step)
+            lines.append('=' * 65)
+            msg = messages[step]
+            lines.extend(msg.split('\n'))
+            lines.append('')
+
+        report = '\n'.join(lines)
+        if isinstance(report, unicode):
+            report = report.encode('latin-1')
+
+        file = File(id=name,
+                    title='',
+                    file=report,
+                    content_type='text/plain'
+                   )
+        self._setObject(name, file)
+
 InitializeClass(SetupTool)
 
 _PLAINTEXT_DIFF_HEADER ="""\

Modified: CMF/trunk/GenericSetup/version.txt
===================================================================
--- CMF/trunk/GenericSetup/version.txt	2005-11-18 19:31:10 UTC (rev 40233)
+++ CMF/trunk/GenericSetup/version.txt	2005-11-18 21:22:13 UTC (rev 40234)
@@ -1 +1 @@
-GenericSetup-1.0
+GenericSetup-1.0+

Modified: CMF/trunk/GenericSetup/www/sutImportSteps.zpt
===================================================================
--- CMF/trunk/GenericSetup/www/sutImportSteps.zpt	2005-11-18 19:31:10 UTC (rev 40233)
+++ CMF/trunk/GenericSetup/www/sutImportSteps.zpt	2005-11-18 21:22:13 UTC (rev 40234)
@@ -73,6 +73,19 @@
   </tr>
  </tbody>
 
+ <tbody tal:condition="options/messages | nothing">
+  <tr class="list-header">
+   <td colspan="4">Message Log</td>
+  </tr>
+  <tr valign="top"
+      tal:repeat="item options/messages/items">
+   <td tal:content="python: item[0]">STEP</td>
+   <td colspan="3"
+       tal:content="structure python: item[1].replace('\n', '<br />')"
+       >MESSAGE</td>
+  </tr>
+ </tbody>
+
 </table>
 </form>
 



More information about the CMF-checkins mailing list