[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