[CMF-checkins]
SVN: CMF/branches/tseaver-resync_GenericSetup/GenericSetup/
Land changes from original repo for GenericSetup 0.11 and 0.12.
Tres Seaver
tseaver at palladion.com
Wed Nov 16 08:10:06 EST 2005
Log message for revision 40155:
Land changes from original repo for GenericSetup 0.11 and 0.12.
Changed:
U CMF/branches/tseaver-resync_GenericSetup/GenericSetup/CHANGES.txt
U CMF/branches/tseaver-resync_GenericSetup/GenericSetup/context.py
U CMF/branches/tseaver-resync_GenericSetup/GenericSetup/interfaces.py
U CMF/branches/tseaver-resync_GenericSetup/GenericSetup/tests/common.py
U CMF/branches/tseaver-resync_GenericSetup/GenericSetup/tests/test_context.py
U CMF/branches/tseaver-resync_GenericSetup/GenericSetup/tool.py
U CMF/branches/tseaver-resync_GenericSetup/GenericSetup/version.txt
U CMF/branches/tseaver-resync_GenericSetup/GenericSetup/www/sutImportSteps.zpt
-=-
Modified: CMF/branches/tseaver-resync_GenericSetup/GenericSetup/CHANGES.txt
===================================================================
--- CMF/branches/tseaver-resync_GenericSetup/GenericSetup/CHANGES.txt 2005-11-16 13:08:57 UTC (rev 40154)
+++ CMF/branches/tseaver-resync_GenericSetup/GenericSetup/CHANGES.txt 2005-11-16 13:10:06 UTC (rev 40155)
@@ -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/branches/tseaver-resync_GenericSetup/GenericSetup/context.py
===================================================================
--- CMF/branches/tseaver-resync_GenericSetup/GenericSetup/context.py 2005-11-16 13:08:57 UTC (rev 40154)
+++ CMF/branches/tseaver-resync_GenericSetup/GenericSetup/context.py 2005-11-16 13:10:06 UTC (rev 40155)
@@ -50,7 +50,7 @@
self._tool = tool
self._site = aq_parent( aq_inner( tool ) )
- self._notes = []
+ self._messages = []
self._encoding = encoding
security.declareProtected( ManagePortal, 'getSite' )
@@ -75,12 +75,28 @@
return self._encoding
security.declareProtected( ManagePortal, 'notes' )
- def note( self, category, message ):
+ def note( self, component, message ):
""" See ISetupContext.
"""
- self._notes.append( ( category, message ) )
+ import zLOG
+ zLOG.LOG('GenericSetup', zLOG.INFO, '%s: %s' % (component, message))
+ self._messages.append((component, message))
+ security.declareProtected( ManagePortal, 'listNotes' )
+ def listNotes(self):
+
+ """ See ISetupContext.
+ """
+ return self._messages[:]
+
+ security.declareProtected( ManagePortal, 'clearNotes' )
+ def clearNotes(self):
+
+ """ See ISetupContext.
+ """
+ self._messages[:] = []
+
class DirectoryImportContext( BaseContext ):
implements(IImportContext)
Modified: CMF/branches/tseaver-resync_GenericSetup/GenericSetup/interfaces.py
===================================================================
--- CMF/branches/tseaver-resync_GenericSetup/GenericSetup/interfaces.py 2005-11-16 13:08:57 UTC (rev 40154)
+++ CMF/branches/tseaver-resync_GenericSetup/GenericSetup/interfaces.py 2005-11-16 13:10:06 UTC (rev 40155)
@@ -60,6 +60,26 @@
general annotation.
"""
+ def note(component, message):
+
+ """ Record a message about the state of the operation.
+
+ o 'component' is a string identifying the subcomponent recording
+ the message.
+
+ o 'message' is the message text.
+ """
+
+ def listNotes():
+ """ Return notes recorded by this context.
+
+ o Result a sequence of (component, message) tuples
+ """
+
+ def clearNotes():
+ """ Clear all notes recorded by this context.
+ """
+
class IImportContext( ISetupContext ):
def readDataFile( filename, subdir=None ):
Modified: CMF/branches/tseaver-resync_GenericSetup/GenericSetup/tests/common.py
===================================================================
--- CMF/branches/tseaver-resync_GenericSetup/GenericSetup/tests/common.py 2005-11-16 13:08:57 UTC (rev 40154)
+++ CMF/branches/tseaver-resync_GenericSetup/GenericSetup/tests/common.py 2005-11-16 13:10:06 UTC (rev 40155)
@@ -180,6 +180,7 @@
self._site = site
self._tool = tool
self._wrote = []
+ self._notes = []
def getSite( self ):
return self._site
@@ -192,6 +193,10 @@
filename = '%s/%s' % ( subdir, filename )
self._wrote.append( ( filename, text, content_type ) )
+ def note( self, component, message ):
+
+ self._notes.append( ( component, message ) )
+
class DummyImportContext:
def __init__( self, site, purge=True, encoding=None, tool=None ):
Modified: CMF/branches/tseaver-resync_GenericSetup/GenericSetup/tests/test_context.py
===================================================================
--- CMF/branches/tseaver-resync_GenericSetup/GenericSetup/tests/test_context.py 2005-11-16 13:08:57 UTC (rev 40154)
+++ CMF/branches/tseaver-resync_GenericSetup/GenericSetup/tests/test_context.py 2005-11-16 13:10:06 UTC (rev 40155)
@@ -46,7 +46,7 @@
class DummyTool( Folder ):
pass
-
+
class DirectoryImportContextTests( FilesystemTestBase
, ConformsToISetupContext
, ConformsToIImportContext
@@ -59,6 +59,22 @@
from Products.GenericSetup.context import DirectoryImportContext
return DirectoryImportContext
+ def test_note( self ):
+
+ site = DummySite( 'site' ).__of__( self.root )
+ ctx = self._makeOne( site, self._PROFILE_PATH )
+ self.assertEqual( len( ctx.listNotes() ), 0 )
+
+ ctx.note( 'foo', 'bar' )
+
+ self.assertEqual( len( ctx.listNotes() ), 1 )
+ component, message = ctx.listNotes()[0]
+ self.assertEqual( component, 'foo' )
+ self.assertEqual( message, 'bar' )
+
+ ctx.clearNotes()
+ self.assertEqual( len( ctx.listNotes() ), 0 )
+
def test_readDataFile_nonesuch( self ):
FILENAME = 'nonesuch.txt'
@@ -326,6 +342,22 @@
from Products.GenericSetup.context import DirectoryExportContext
return DirectoryExportContext
+ def test_note( self ):
+
+ site = DummySite( 'site' ).__of__( self.root )
+ ctx = self._makeOne( site, self._PROFILE_PATH )
+ self.assertEqual( len( ctx.listNotes() ), 0 )
+
+ ctx.note( 'foo', 'bar' )
+
+ self.assertEqual( len( ctx.listNotes() ), 1 )
+ component, message = ctx.listNotes()[0]
+ 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 +470,21 @@
return site, tool, ctx.__of__( tool )
+ def test_note( self ):
+
+ site, tool, ctx = self._makeOne()
+ self.assertEqual( len( ctx.listNotes() ), 0 )
+
+ ctx.note( 'foo', 'bar' )
+
+ self.assertEqual( len( ctx.listNotes() ), 1 )
+ component, message = ctx.listNotes()[0]
+ 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 +737,23 @@
from Products.GenericSetup.context import TarballExportContext
return TarballExportContext
+ def test_note( self ):
+
+ site = DummySite( 'site' ).__of__( self.root )
+ ctx = self._getTargetClass()( site )
+
+ self.assertEqual( len( ctx.listNotes() ), 0 )
+
+ ctx.note( 'foo', 'bar' )
+
+ self.assertEqual( len( ctx.listNotes() ), 1 )
+ component, message = ctx.listNotes()[0]
+ 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 +818,25 @@
return self._getTargetClass()( *args, **kw )
+ def test_note( 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 )
+
+ ctx.note( 'foo', 'bar' )
+
+ self.assertEqual( len( ctx.listNotes() ), 1 )
+ component, message = ctx.listNotes()[0]
+ 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 +1107,23 @@
return folder._getOb( filename )
+ def test_note( self ):
+
+ SNAPSHOT_ID = 'note'
+ site, tool, ctx = self._makeOne( SNAPSHOT_ID )
+
+ self.assertEqual( len( ctx.listNotes() ), 0 )
+
+ ctx.note( 'foo', 'bar' )
+
+ self.assertEqual( len( ctx.listNotes() ), 1 )
+ component, message = ctx.listNotes()[0]
+ 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/branches/tseaver-resync_GenericSetup/GenericSetup/tool.py
===================================================================
--- CMF/branches/tseaver-resync_GenericSetup/GenericSetup/tool.py 2005-11-16 13:08:57 UTC (rev 40154)
+++ CMF/branches/tseaver-resync_GenericSetup/GenericSetup/tool.py 2005-11-16 13:10:06 UTC (rev 40155)
@@ -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
@@ -219,7 +220,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 for x in context.listNotes()] )
+ messages[step_id] = '\n'.join(message_list)
steps.append(step_id)
return { 'steps' : steps, 'messages' : messages }
@@ -236,7 +239,10 @@
for step in steps:
message = self._doRunImportStep(step, context)
- messages[step] = message
+ message_list = filter(None, [message])
+ message_list.extend( ['%s: %s' % x for x in context.listNotes()] )
+ messages[step] = '\n'.join(message_list)
+ context.clearNotes()
return { 'steps' : steps, 'messages' : messages }
@@ -389,34 +395,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 +534,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 +729,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/branches/tseaver-resync_GenericSetup/GenericSetup/version.txt
===================================================================
--- CMF/branches/tseaver-resync_GenericSetup/GenericSetup/version.txt 2005-11-16 13:08:57 UTC (rev 40154)
+++ CMF/branches/tseaver-resync_GenericSetup/GenericSetup/version.txt 2005-11-16 13:10:06 UTC (rev 40155)
@@ -1 +1 @@
-GenericSetup-1.0
+GenericSetup-1.0+
Modified: CMF/branches/tseaver-resync_GenericSetup/GenericSetup/www/sutImportSteps.zpt
===================================================================
--- CMF/branches/tseaver-resync_GenericSetup/GenericSetup/www/sutImportSteps.zpt 2005-11-16 13:08:57 UTC (rev 40154)
+++ CMF/branches/tseaver-resync_GenericSetup/GenericSetup/www/sutImportSteps.zpt 2005-11-16 13:10:06 UTC (rev 40155)
@@ -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