[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