[CMF-checkins] CVS: CMF/CMFSetup - actions.py:1.9.2.1 typeinfo.py:1.8.2.1 utils.py:1.9.2.1

Yvo Schubbe y.2004_ at wcm-solutions.de
Sun Jul 18 18:20:44 EDT 2004


Update of /cvs-repository/CMF/CMFSetup
In directory cvs.zope.org:/tmp/cvs-serv20417/CMFSetup

Modified Files:
      Tag: yuppie-actions-cleanup-branch
	actions.py typeinfo.py utils.py 
Log Message:
- refactored xml import of actions-tool and type-info using minidom
- refactored xml export using the new getMapping method of Actions
- added permission subelement to action
- synced action handling


=== CMF/CMFSetup/actions.py 1.9 => 1.9.2.1 ===
--- CMF/CMFSetup/actions.py:1.9	Thu Jul  1 19:14:23 2004
+++ CMF/CMFSetup/actions.py	Sun Jul 18 18:20:44 2004
@@ -2,21 +2,24 @@
 
 $Id$
 """
-from xml.sax import parseString
+from xml.dom.minidom import parseString as domParseString
 
 from AccessControl import ClassSecurityInfo
 from Acquisition import Implicit
 from Globals import InitializeClass
 from Products.PageTemplates.PageTemplateFile import PageTemplateFile
 
+from Products.CMFCore.ActionInformation import ActionInformation
 from Products.CMFCore.ActionProviderBase import IActionProvider
 from Products.CMFCore.ActionProviderBase import IOldstyleActionProvider
-from Products.CMFCore.ActionInformation import getOAI
 from Products.CMFCore.utils import getToolByName
 
 from permissions import ManagePortal
-from utils import HandlerBase
+from utils import _coalesceTextNodeChildren
+from utils import _getNodeAttribute
+from utils import _getNodeAttributeBoolean
 from utils import _xmldir
+from utils import HandlerBase
 
 #
 #   Configurator entry points
@@ -42,7 +45,7 @@
                            )
 
     o Register via XML:
- 
+
       <setup-step id="importActionProviders"
                   version="20040524-01"
                   handler="Products.CMFSetup.actions.importActionProviders"
@@ -75,22 +78,11 @@
                 actions_tool.addActionProvider( p_info[ 'id' ] )
 
             provider = getToolByName( site, p_info[ 'id' ] )
-            provider._actions = ()
-
-            for a_info in p_info[ 'actions' ]:
-
-                provider.addAction( id=a_info[ 'action_id' ]
-                                  , name=a_info[ 'name' ]
-                                  , action=a_info[ 'action' ]
-                                  , condition=a_info[ 'condition' ]
-                                  , permission=a_info[ 'permission' ]
-                                  , category=a_info[ 'category' ]
-                                  , visible=a_info[ 'visible' ]
-                                  )
+            provider._actions = [ ActionInformation(**a_info)
+                                  for a_info in p_info['actions'] ]
 
     return 'Action providers imported.'
 
-
 def exportActionProviders( context ):
 
     """ Export action providers and their actions as an XML file
@@ -108,7 +100,7 @@
                            )
 
     o Register via XML:
- 
+
       <export-script id="exportActionProviders"
                      version="20040518-01"
                      handler="Products.CMFSetup.actions.exportActionProviders"
@@ -130,9 +122,9 @@
 
     """ Synthesize XML description of site's action providers.
     """
-    security = ClassSecurityInfo()   
+    security = ClassSecurityInfo()
     security.setDefaultAccess( 'allow' )
-    
+
     def __init__( self, site ):
         self._site = site
 
@@ -147,15 +139,12 @@
         """ Return a sequence of mappings for each action provider.
         """
         actions_tool = getToolByName( self._site, 'portal_actions' )
-        faux = _FauxContent( content=None, isAnonymous=1 )
-        info = getOAI( self._site, faux )
         result = []
 
         for provider_id in actions_tool.listActionProviders():
 
             provider_info = { 'id' : provider_id, 'actions' : [] }
             result.append( provider_info )
-            append = provider_info[ 'actions' ].append
 
             provider = getToolByName( self._site, provider_id )
 
@@ -165,27 +154,8 @@
             if IOldstyleActionProvider.isImplementedBy( provider ):
                 continue
 
-            actions = provider.listActions( info=info ) or []
-            
-            for action in actions:
-
-                ainfo = {}
-                ainfo[ 'id'] = action.getId()
-                ainfo[ 'name'] = action.Title()
-
-                p = action.getPermissions()
-
-                if p:
-                    ainfo[ 'permission'] = p[ 0 ]
-                else:
-                    ainfo[ 'permission'] = ''
-
-                ainfo[ 'category'] = action.getCategory() or 'object'
-                ainfo[ 'visible'] = action.getVisibility()
-                ainfo[ 'action'] = action.getActionExpression()
-                ainfo[ 'condition'] = action.getCondition()
-
-                append( ainfo )
+            actions = provider.listActions()
+            provider_info['actions'] = [ ai.getMapping() for ai in actions ]
 
         return result
 
@@ -201,82 +171,67 @@
 
         """ Pseudo API.
         """
-        result = []
         reader = getattr( text, 'read', None )
 
         if reader is not None:
             text = reader()
 
-        parser = _ActionProviderParser( encoding )
-        parseString( text, parser )
-
-        for provider_id in parser._provider_ids:
-
-            p_info = { 'id' : provider_id, 'actions' : [] }
-
-            for a_info in parser._provider_info.get( provider_id, () ):
-
-                p_info[ 'actions' ].append( a_info )
+        dom = domParseString(text)
 
-            result.append( p_info )
-
-        return result
+        root = dom.getElementsByTagName('actions-tool')[0]
+        return _extractActionProviderNodes(root, encoding)
 
 InitializeClass( ActionProvidersConfigurator )
 
-class _FauxContent:
-
-    # Dummy object for passing to listActions
 
-    def __init__( self, **kw ):
-        self.__dict__.update( kw )
+def _extractActionProviderNodes(parent, encoding=None):
 
-    def absolute_url( self ):
-        return 'http://localhost/faux_content'
+    result = []
 
-class _ActionProviderParser( HandlerBase ):
-
-    security = ClassSecurityInfo()
-    security.declareObjectPrivate()
-    security.setDefaultAccess( 'deny' )
+    for ap_node in parent.getElementsByTagName('action-provider'):
 
-    def __init__( self, encoding ):
+        id = _getNodeAttribute(ap_node, 'id', encoding)
+        actions = _extractActionNodes(ap_node, encoding)
 
-        self._encoding = encoding
-        self._provider_info = {}
-        self._provider_ids = []
+        result.append( { 'id': id, 'actions': actions } )
 
-    def startElement( self, name, attrs ):
+    return result
 
-        if name == 'actions-tool':
-            pass
+def _extractActionNodes(parent, encoding=None):
 
-        elif name == 'action-provider':
+    result = []
 
-            id = self._extract( attrs, 'id' )
+    for a_node in parent.getElementsByTagName('action'):
 
-            if id not in self._provider_ids:
-                self._provider_ids.append( id )
+        def _es(key):
+            return _getNodeAttribute(a_node, key, encoding)
 
-        elif name == 'action':
+        action_id      = _es('action_id')
+        title          = _es('title')
+        category       = _es('category')
+        condition_expr = _es('condition_expr')
+        permissions    = _extractPermissionNodes(a_node, encoding)
+        category       = _es('category')
+        visible        = _getNodeAttributeBoolean(a_node, 'visible')
+        url_expr       = _es('url_expr')
 
-            provider_id = self._provider_ids[ -1 ]
-            actions = self._provider_info.setdefault( provider_id, [] )
+        result.append( { 'id': action_id,
+                         'title': title,
+#                         'description': description,
+                         'category': category,
+                         'condition': condition_expr,
+                         'permissions': permissions,
+                         'visible': visible,
+                         'action': url_expr } )
 
-            info = { 'action_id' : self._extract( attrs, 'action_id' )
-                   , 'category' : self._extract( attrs, 'category' )
-                   , 'name' : self._extract( attrs, 'title' )
-                   , 'action' : self._extract( attrs, 'action_expr' )
-                   , 'condition' : self._extract( attrs, 'condition_expr' )
-                   , 'permission' : self._extract( attrs, 'permission' )
-                   , 'category' : self._extract( attrs, 'category' )
-                   , 'visible' : self._extract( attrs, 'visible' )
-                   }
+    return result
 
-            actions.append( info )
+def _extractPermissionNodes(parent, encoding=None):
 
-        else:
-            raise ValueError, 'Unknown element %s' % name
+    result = []
 
+    for p_node in parent.getElementsByTagName('permission'):
+        value = _coalesceTextNodeChildren(p_node, encoding)
+        result.append(value)
 
-InitializeClass( _ActionProviderParser )
+    return tuple(result)


=== CMF/CMFSetup/typeinfo.py 1.8 => 1.8.2.1 ===
--- CMF/CMFSetup/typeinfo.py:1.8	Thu Jul  1 19:14:23 2004
+++ CMF/CMFSetup/typeinfo.py	Sun Jul 18 18:20:44 2004
@@ -2,6 +2,7 @@
 
 $Id$
 """
+from xml.dom.minidom import parseString as domParseString
 from xml.sax import parseString
 
 from AccessControl import ClassSecurityInfo
@@ -14,9 +15,14 @@
 from Products.CMFCore.TypesTool import typeClasses
 from Products.CMFCore.utils import getToolByName
 
+from actions import _extractActionNodes
 from permissions import ManagePortal
-from utils import HandlerBase
+from utils import _coalesceTextNodeChildren
+from utils import _getNodeAttribute
+from utils import _queryNodeAttribute
+from utils import _queryNodeAttributeBoolean
 from utils import _xmldir
+from utils import HandlerBase
 
 #
 #   Entry points
@@ -91,7 +97,7 @@
 
 class TypeInfoConfigurator( Implicit ):
 
-    security = ClassSecurityInfo()   
+    security = ClassSecurityInfo()
     security.setDefaultAccess('allow')
 
     def __init__( self, site ):
@@ -163,11 +169,9 @@
 
         """ Pseudo API.
         """
-        tool = getToolByName( self._site, 'portal_types' )
-        parser = _TypeInfoParser( encoding )
-        parseString( xml, parser )
+        dom = domParseString(xml)
 
-        return parser._info_list
+        return _extractTypeInfoNode(dom, encoding)
 
     #
     #   Helper methods
@@ -191,14 +195,14 @@
         """
         result = { 'id'                     : ti.getId()
                  , 'title'                  : ti.Title()
-                 , 'description'            : ti.Description()
+                 , 'description'            : ti.Description().strip()
                  , 'meta_type'              : ti.Metatype()
-                 , 'icon'                   : ti.getIcon() 
+                 , 'icon'                   : ti.getIcon()
                  , 'immediate_view'         : ti.immediate_view
-                 , 'global_allow'           : ti.global_allow
-                 , 'filter_content_types'   : ti.filter_content_types
+                 , 'global_allow'           : bool(ti.global_allow)
+                 , 'filter_content_types'   : bool(ti.filter_content_types)
                  , 'allowed_content_types'  : ti.allowed_content_types
-                 , 'allow_discussion'       : ti.allow_discussion
+                 , 'allow_discussion'       : bool(ti.allow_discussion)
                  , 'aliases'                : ti.getMethodAliases()
                  }
 
@@ -218,25 +222,11 @@
             result[ 'permission' ]       = ti.permission
             result[ 'constructor_path' ] = ti.constructor_path
 
-        result[ 'actions' ] = [ self._makeActionMapping( x )
-                                    for x in ti.listActions() ]
+        actions = ti.listActions()
+        result['actions'] = [ ai.getMapping() for ai in actions ]
 
         return result
 
-    security.declarePrivate( '_makeActionMapping' )
-    def _makeActionMapping( self, ai ):
-
-        """ Convert an ActionInformation object into a mapping.
-        """
-        return { 'id'             : ai.getId()
-               , 'title'          : ai.Title()
-               , 'description'    : ai.Description()
-               , 'action'         : ai.getActionExpression()
-               , 'condition'      : ai.getCondition()
-               , 'permissions'    : ai.getPermissions()
-               , 'category'       : ai.getCategory()
-               , 'visible'        : bool( ai.getVisibility() )
-               }
 
 InitializeClass( TypeInfoConfigurator )
 
@@ -259,7 +249,7 @@
 
             id = self._extract( attrs, 'id' )
             filename = self._extract( attrs, 'filename', id )
-            
+
             if filename == id:
                 filename = _getTypeFilename( filename )
 
@@ -267,130 +257,87 @@
 
 InitializeClass( _TypesToolParser )
 
-_TYPE_INTS = ['global_allow', 'filter_content_types', 'allow_discussion']
-
-class _TypeInfoParser( HandlerBase ):
-
-    security = ClassSecurityInfo()
-
-    def __init__( self, encoding ):
-
-        self._encoding = encoding
-        self._info_list = []
-        self._description = None
 
-    security.declarePrivate( 'startElement' )
-    def startElement( self, name, attrs ):
+def _extractTypeInfoNode(parent, encoding=None):
 
-        def _es( key, default=None ):
-            return self._extract( attrs, key, default )
+    result = []
 
-        def _eb( key, default=None ):
-            return self._extractBoolean( attrs, key, default )
+    ti_node = parent.getElementsByTagName('type-info')[0]
 
-        if name == 'type-info':
+    def _es(key):
+        return _getNodeAttribute(ti_node, key, encoding)
 
-            type_id                 = _es( 'id' )
-            kind                    = _es( 'kind' )
-            title                   = _es( 'title', type_id )
-            meta_type               = _es( 'meta_type', type_id )
-            icon                    = _es( 'icon', '%s.png' % type_id )
-            immediate_view          = _es( 'icon', '%s_edit' % type_id )
-            global_allow            = _eb( 'global_allow', True )
-            filter_content_types    = _eb( 'filter_content_types', False )
-            allowed_content_types   = _es( 'allowed_content_types', '' )
-            allowed_content_types   = allowed_content_types.split( ',' )
-            allow_discussion        = _eb( 'allow_discussion', False )
-
-            info = { 'id'                    : type_id
-                   , 'kind'                  : kind
-                   , 'title'                 : title
-                   , 'description'           : ''
-                   , 'meta_type'             : meta_type
-                   , 'icon'                  : icon
-                   , 'immediate_view'        : immediate_view
-                   , 'global_allow'          : global_allow
-                   , 'filter_content_types'  : filter_content_types
-                   , 'allowed_content_types' : allowed_content_types
-                   , 'allow_discussion'      : allow_discussion
-                   , 'aliases'               : {}
-                   , 'actions'               : []
-                   }
-
-            if kind == FactoryTypeInformation.meta_type:
-
-                info[ 'product' ]           = _es( 'product' )
-                info[ 'factory' ]           = _es( 'factory' )
+    def _qs(key, default=None):
+        return _queryNodeAttribute(ti_node, key, default, encoding)
 
-            elif kind == ScriptableTypeInformation.meta_type:
+    def _qb(key, default=None):
+        return _queryNodeAttributeBoolean(ti_node, key, default)
 
-                info[ 'constructor_path' ]  = _es( 'constructor_path' )
-                info[ 'permission' ]        = _es( 'permission' )
+    type_id               = _es('id')
+    kind                  = _es('kind')
+    title                 = _qs('title', type_id)
+    description           = _extractDescriptionNode(ti_node, encoding)
+    meta_type             = _qs('meta_type', type_id)
+    icon                  = _qs('icon', '%s.png' % type_id)
+    immediate_view        = _qs('immediate_view', '%s_edit' % type_id)
+    global_allow          = _qb('global_allow', True)
+    filter_content_types  = _qb('filter_content_types', False)
+    allowed_content_types = _extractAllowedContentTypesNode(ti_node, encoding)
+    allow_discussion      = _qb('allow_discussion', False)
+    aliases               = _extractAliasesNode(ti_node, encoding)
+    actions               = _extractActionNodes(ti_node, encoding)
 
-            self._info_list.append( info )
+    info = { 'id': type_id,
+             'kind': kind,
+             'title': title,
+             'description': description,
+             'meta_type': meta_type,
+             'icon': icon,
+             'immediate_view': immediate_view,
+             'global_allow': global_allow,
+             'filter_content_types': filter_content_types,
+             'allowed_content_types': allowed_content_types,
+             'allow_discussion': allow_discussion,
+             'aliases': aliases,
+             'actions': actions }
 
-        elif name == 'aliases':
-            pass
+    if kind == FactoryTypeInformation.meta_type:
+        info['product'] = _es('product')
+        info['factory'] = _es('factory')
+    elif kind == ScriptableTypeInformation.meta_type:
+        info['constructor_path'] = _es('constructor_path')
+        info['permission'] = _es('permission')
 
-        elif name == 'alias':
+    result.append(info)
 
-            t_info = self._info_list[ -1 ]
-            alias_from  = _es( 'from' )
-            alias_to    = _es( 'to' )
+    return result
 
-            t_info[ 'aliases' ][ alias_from ] = alias_to
+def _extractAllowedContentTypesNode(parent, encoding=None):
 
-        elif name == 'action':
+    act = _queryNodeAttribute(parent, 'allowed_content_types', '', encoding)
+    return act.split(',')
 
-            t_info = self._info_list[ -1 ]
-            permissions = tuple( _es( 'permissions' ).split( ',' ) )
+def _extractDescriptionNode(parent, encoding=None):
 
-            a_info = { 'id'             : _es( 'action_id' )
-                     , 'title'          : _es( 'title' )
-                     , 'name'           : _es( 'title' )
-                     , 'action'         : _es( 'action_expr' )
-                     , 'condition'      : _es( 'condition' )
-                     , 'permissions'    : permissions
-                     , 'category'       : _es( 'category' )
-                     , 'visible'        : _eb( 'visible' )
-                     }
+    d_node = parent.getElementsByTagName('description')[0]
+    return _coalesceTextNodeChildren(d_node, encoding)
 
-            t_info[ 'actions' ].append( a_info )
-
-        elif name == 'description':
-            self._description = ''
-
-        else:
-            raise ValueError, 'Unknown element %s' % name
+def _extractAliasesNode(parent, encoding=None):
 
-    security.declarePrivate('endElement')
-    def endElement(self, name):
+    result = {}
 
-        if name == 'description':
+    aliases = parent.getElementsByTagName('aliases')[0]
+    for alias in aliases.getElementsByTagName('alias'):
 
-            info = self._info_list[ -1 ]
-            info[ 'description' ] = _cleanDescription( self._description )
-            self._description = None
+        alias_from = _getNodeAttribute(alias, 'from', encoding)
+        alias_to = _getNodeAttribute(alias, 'to', encoding)
 
-    security.declarePrivate( 'characters' )
-    def characters( self, chars ):
+        result[alias_from] = alias_to
 
-        if self._description is not None:
-
-            if self._encoding:
-                chars = chars.encode( self._encoding )
-
-            self._description += chars
-
-
-InitializeClass( _TypeInfoParser )
+    return result
 
 def _getTypeFilename( type_id ):
 
     """ Return the name of the file which holds info for a given type.
     """
     return 'types/%s.xml' % type_id.replace( ' ', '_' )
-
-def _cleanDescription( desc ):
-
-    return ''.join( map( lambda x: x.lstrip(), desc.splitlines( 1 ) ) )


=== CMF/CMFSetup/utils.py 1.9 => 1.9.2.1 ===
--- CMF/CMFSetup/utils.py:1.9	Tue Jun  8 20:36:47 2004
+++ CMF/CMFSetup/utils.py	Sun Jul 18 18:20:44 2004
@@ -4,7 +4,6 @@
 """
 import os
 from inspect import getdoc
-from types import StringTypes, InstanceType
 from xml.sax.handler import ContentHandler
 
 from Globals import package_home
@@ -16,7 +15,7 @@
 
 def _getDottedName( named ):
 
-    if isinstance( named, StringTypes ):
+    if isinstance( named, basestring ):
         return str( named )
 
     try:
@@ -141,6 +140,21 @@
 
     return value
 
+def _queryNodeAttributeBoolean( node, attr_name, default ):
+
+    """ Extract a string-valued attribute from node.
+
+    o Return 'default' if the attribute is not present.
+    """
+    attr_node = node.attributes.get( attr_name, _marker )
+
+    if attr_node is _marker:
+        return default
+
+    value = node.attributes[ attr_name ].nodeValue.lower()
+
+    return value in ( 'true', 'yes', '1' )
+
 def _getNodeAttributeBoolean( node, attr_name ):
 
     """ Extract a string-valued attribute from node.
@@ -170,4 +184,4 @@
     if encoding is not None:
         joined = joined.encode( encoding )
 
-    return joined
+    return ''.join( [ line.lstrip() for line in joined.splitlines(True) ] )



More information about the CMF-checkins mailing list