[CMF-checkins] CVS: CMF/CMFSetup - actions.py:1.10 typeinfo.py:1.9
utils.py:1.10
Yvo Schubbe
y.2004_ at wcm-solutions.de
Mon Jul 19 14:12:06 EDT 2004
Update of /cvs-repository/CMF/CMFSetup
In directory cvs.zope.org:/tmp/cvs-serv10833/CMFSetup
Modified Files:
actions.py typeinfo.py utils.py
Log Message:
merged yuppie-actions-cleanup-branch:
- enforced usage of 'title' instead of 'name', 'url' instead of 'action'
- enforced boolean type of 'visible'
- refactored CMFSetup actions and type-info handling
- updated default profile
=== CMF/CMFSetup/actions.py 1.9 => 1.10 ===
--- CMF/CMFSetup/actions.py:1.9 Thu Jul 1 19:14:23 2004
+++ CMF/CMFSetup/actions.py Mon Jul 19 14:11:36 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.9 ===
--- CMF/CMFSetup/typeinfo.py:1.8 Thu Jul 1 19:14:23 2004
+++ CMF/CMFSetup/typeinfo.py Mon Jul 19 14:11:36 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,92 @@
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 _es( key, default=None ):
- return self._extract( attrs, key, default )
- def _eb( key, default=None ):
- return self._extractBoolean( attrs, key, default )
+def _extractTypeInfoNode(parent, encoding=None):
- if name == 'type-info':
+ result = []
- 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' )
+ ti_node = parent.getElementsByTagName('type-info')[0]
- elif kind == ScriptableTypeInformation.meta_type:
+ def _es(key):
+ return _getNodeAttribute(ti_node, key, encoding)
- info[ 'constructor_path' ] = _es( 'constructor_path' )
- info[ 'permission' ] = _es( 'permission' )
+ def _qs(key, default=None):
+ return _queryNodeAttribute(ti_node, key, default, encoding)
- self._info_list.append( info )
+ def _qb(key, default=None):
+ return _queryNodeAttributeBoolean(ti_node, key, default)
- elif name == 'aliases':
- pass
-
- elif name == 'alias':
-
- t_info = self._info_list[ -1 ]
- alias_from = _es( 'from' )
- alias_to = _es( 'to' )
+ 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 = _extractAllowedContentTypeNodes(ti_node, encoding)
+ allow_discussion = _qb('allow_discussion', False)
+ aliases = _extractAliasesNode(ti_node, encoding)
+ actions = _extractActionNodes(ti_node, encoding)
- t_info[ 'aliases' ][ alias_from ] = alias_to
+ 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 == 'action':
+ 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')
- t_info = self._info_list[ -1 ]
- permissions = tuple( _es( 'permissions' ).split( ',' ) )
+ result.append(info)
- 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' )
- }
+ return result
- t_info[ 'actions' ].append( a_info )
+def _extractAllowedContentTypeNodes(parent, encoding=None):
- elif name == 'description':
- self._description = ''
+ result = []
- else:
- raise ValueError, 'Unknown element %s' % name
+ for act_node in parent.getElementsByTagName('allowed_content_type'):
+ value = _coalesceTextNodeChildren(act_node, encoding)
+ result.append(value)
- security.declarePrivate('endElement')
- def endElement(self, name):
+ return tuple(result)
- if name == 'description':
+def _extractDescriptionNode(parent, encoding=None):
- info = self._info_list[ -1 ]
- info[ 'description' ] = _cleanDescription( self._description )
- self._description = None
+ d_node = parent.getElementsByTagName('description')[0]
+ return _coalesceTextNodeChildren(d_node, encoding)
- security.declarePrivate( 'characters' )
- def characters( self, chars ):
+def _extractAliasesNode(parent, encoding=None):
- if self._description is not None:
+ result = {}
- if self._encoding:
- chars = chars.encode( self._encoding )
+ aliases = parent.getElementsByTagName('aliases')[0]
+ for alias in aliases.getElementsByTagName('alias'):
- self._description += chars
+ alias_from = _getNodeAttribute(alias, 'from', encoding)
+ alias_to = _getNodeAttribute(alias, 'to', encoding)
+ result[alias_from] = alias_to
-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.10 ===
--- CMF/CMFSetup/utils.py:1.9 Tue Jun 8 20:36:47 2004
+++ CMF/CMFSetup/utils.py Mon Jul 19 14:11:36 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