[CMF-checkins] CVS: CMF/CMFCore - ActionProviderBase.py:1.3.2.1 ActionsTool.py:1.23.2.2 DirectoryView.py:1.17.4.2 Expression.py:1.2.10.1 FSPageTemplate.py:1.3.20.2 FSPythonScript.py:1.14.24.3 MembershipTool.py:1.17.10.1 RegistrationTool.py:1.9.4.1 SkinsTool.py:1.12.10.1 TypesTool.py:1.29.4.2
Shane Hathaway
shane@cvs.zope.org
Wed, 20 Feb 2002 15:15:21 -0500
Update of /cvs-repository/CMF/CMFCore
In directory cvs.zope.org:/tmp/cvs-serv27999/CMFCore
Modified Files:
Tag: cmf-pre-1_3-branch
ActionProviderBase.py ActionsTool.py DirectoryView.py
Expression.py FSPageTemplate.py FSPythonScript.py
MembershipTool.py RegistrationTool.py SkinsTool.py
TypesTool.py
Log Message:
Merged changes from head, with a small change: the types tool does not need
to be extended in such a complex way. I took out the type_type registry and
the __bobo_traverse__ hook and replaced it with the original code with only
minor mods that give you the same extensibility without all the hacking.
(If anyone actually wants to use the extensibility, which I suspect no one
is actually interested in doing, I will happily provide instructions and
will create a corrected unit test.)
=== CMF/CMFCore/ActionProviderBase.py 1.3 => 1.3.2.1 ===
security.declarePrivate('listActions')
- def listActions(self):
+ def listActions(self, info=None):
"""
Return all the actions defined by a tool
"""
=== CMF/CMFCore/ActionsTool.py 1.23.2.1 => 1.23.2.2 ===
# 'portal_actions' interface methods
#
+
+ def _listActions(self,append,object,info,ec):
+ a = object.listActions(info)
+ if a and type(a[0]) is not type({}):
+ for ai in a:
+ if ai.testCondition(ec):
+ append(ai.getAction(ec))
+ else:
+ for i in a:
+ append(i)
+
security.declarePublic('listFilteredActionsFor')
def listFilteredActionsFor(self, object=None):
'''Gets all actions available to the user and returns a mapping
@@ -177,23 +188,13 @@
else:
folder = aq_parent(aq_inner(folder))
ec = createExprContext(folder, portal, object)
- ai_objs = []
actions = []
+ append = actions.append
info = oai(self, folder, object)
# Include actions from specific tools.
for provider_name in self.listActionProviders():
provider = getattr(self, provider_name)
- a = provider.listActions(info)
- if a and type(a[0]) is not type({}):
- ai_objs.extend(list(a))
- else:
- for i in a:
- actions.append(i)
-
- if ai_objs:
- for ai in ai_objs:
- if ai.testCondition(ec):
- actions.append(ai.getAction(ec))
+ self._listActions(append,provider,info,ec)
# Include actions from object.
if object is not None:
@@ -218,11 +219,10 @@
'permissions': d['permissions'],
'category': d.get('category', 'object'),
'visible': d.get('visible', 1),
- })
+ })
if hasattr(base, 'listActions'):
- a = object.listActions(info)
- if a:
- actions.extend(list(a))
+ self._listActions(append,object,info,ec)
+
# Reorganize the actions by category,
# filtering out disallowed actions.
=== CMF/CMFCore/DirectoryView.py 1.17.4.1 => 1.17.4.2 ===
##############################################################################
"""Views of filesystem directories as folders."""
-__version__='$Revision$'[11:-2]
+__version__='$Revision$'[11:-2]
import Globals
from Globals import HTMLFile, Persistent, package_home, DTMLFile
@@ -30,6 +30,7 @@
from utils import expandpath, minimalpath
from zLOG import LOG, ERROR
from sys import exc_info
+from types import StringType
_dtmldir = os.path.join( package_home( globals() ), 'dtml' )
@@ -37,14 +38,22 @@
# Ignore version control subdirectories
# and special names.
+def _filter(name):
+ return name not in ('CVS', 'SVN', '.', '..')
+
def _filtered_listdir(path):
- n = filter(lambda name: name not in ('CVS', 'SVN', '.', '..'),
+ n = filter(_filter,
listdir(path))
return n
+def _walker (listdir, dirname, names):
+ names[:]=filter(_filter,names)
+ listdir.extend(names)
+
class DirectoryInformation:
data = None
_v_last_read = 0
+ _v_last_filelist = [] # Only used on Win32
def __init__(self, expanded_fp, minimal_fp):
self.filepath = minimal_fp
@@ -86,6 +95,7 @@
types[strip(obname)] = strip(meta_type)
return types
+
def _readProperties(self, fp):
"""Reads the properties file next to an object.
"""
@@ -104,15 +114,54 @@
props[strip(key)] = strip(value)
return props
- def getContents(self, registry):
- changed = 0
- if Globals.DevelopmentMode:
+
+ if Globals.DevelopmentMode and os.name=='nt':
+
+ def _changed(self):
+ mtime=0
+ filelist=[]
+ try:
+ fp = expandpath(self.filepath)
+ mtime = stat(fp)[8]
+ # some Windows directories don't change mtime
+ # when a file in them changes :-(
+ # So keep a list of files as well, and see if that
+ # changes
+ path.walk(fp,_walker,filelist)
+ filelist.sort()
+ except:
+ from zLOG import LOG, ERROR
+ import sys
+ LOG('DirectoryView',
+ ERROR,
+ 'Error checking for directory modification',
+ error=sys.exc_info())
+
+ if mtime != self._v_last_read or filelist != self._v_last_filelist:
+ self._v_last_read = mtime
+ self._v_last_filelist = filelist
+
+ return 1
+
+ return 0
+
+ elif Globals.DevelopmentMode:
+
+ def _changed(self):
try: mtime = stat(expandpath(self.filepath))[8]
except: mtime = 0
if mtime != self._v_last_read:
self._v_last_read = mtime
- changed = 1
+ return 1
+ return 0
+
+ else:
+ def _changed(self):
+ return 0
+
+ def getContents(self, registry):
+ changed = self._changed()
if self.data is None or changed:
try:
self.data, self.objects = self.prepareContents(registry,
@@ -180,6 +229,7 @@
t = registry.getTypeByMetaType(mt)
if t is None:
t = registry.getTypeByExtension(ext)
+
if t is not None:
properties = self._readProperties(
e_filepath + '.properties')
@@ -230,8 +280,10 @@
def getTypeByMetaType(self, mt):
return self._meta_types.get(mt, None)
- def registerDirectory(self, name, parent_globals, subdirs=1):
- filepath = path.join(package_home(parent_globals), name)
+ def registerDirectory(self, name, _prefix, subdirs=1):
+ if not isinstance(_prefix, StringType):
+ _prefix = package_home(_prefix)
+ filepath = path.join(_prefix, name)
self.registerDirectoryByPath(filepath, subdirs)
def registerDirectoryByPath(self, filepath, subdirs=1):
@@ -412,7 +464,7 @@
ob = DirectoryView(id, filepath)
parent._setObject(id, ob)
-def addDirectoryViews(ob, name, parent_globals):
+def addDirectoryViews(ob, name, _prefix):
'''
Adds a directory view for every subdirectory of the
given directory.
@@ -421,7 +473,9 @@
# Note that registerDirectory() still needs to be called
# by product initialization code to satisfy
# persistence demands.
- fp = path.join(package_home(parent_globals), name)
+ if not isinstance(_prefix, StringType):
+ _prefix = package_home(_prefix)
+ fp = path.join(_prefix, name)
filepath = minimalpath(fp)
info = _dirreg.getDirectoryInfo(filepath)
if info is None:
=== CMF/CMFCore/Expression.py 1.2 => 1.2.10.1 ===
from Products.PageTemplates.Expressions import getEngine
from Products.PageTemplates.TALES import SafeMapping
-from Products.PageTemplates.PageTemplate import ModuleImporter
-
+from Products.PageTemplates.Expressions import SecureModuleImporter
class Expression (Persistent):
text = ''
@@ -74,7 +73,7 @@
'portal': portal,
'nothing': None,
'request': getattr( object, 'REQUEST', None ),
- 'modules': ModuleImporter,
+ 'modules': SecureModuleImporter,
'member': member,
}
return getEngine().getContext(data)
=== CMF/CMFCore/FSPageTemplate.py 1.3.20.1 => 1.3.20.2 ===
def pt_render(self, source=0, extra_context={}):
- # Tie in on an opportunity to auto-reload
- self._updateFromFS()
- if Globals.DevelopmentMode:
- try:
- return FSPageTemplate.inheritedAttribute('pt_render')( self,
- source, extra_context )
- except RuntimeError:
+ self._updateFromFS() # Make sure the template has been loaded.
+ try:
+ return FSPageTemplate.inheritedAttribute('pt_render')(
+ self, source, extra_context )
+ except RuntimeError:
+ if Globals.DevelopmentMode:
err = FSPageTemplate.inheritedAttribute( 'pt_errors' )( self )
err_type = err[0]
err_msg = '<pre>%s</pre>' % replace( err[1], "\'", "'" )
msg = 'FS Page Template %s has errors: %s.<br>%s' % (
- self.id, err_type, err_msg )
+ self.id, err_type, html_quote(err_msg) )
raise RuntimeError, msg
- else:
- return FSPageTemplate.inheritedAttribute('pt_render')(self,
- source, extra_context )
-
+ else:
+ raise
+
+
# Copy over more mothods
security.declareProtected(FTPAccess, 'manage_FTPget')
security.declareProtected(View, 'get_size')
=== CMF/CMFCore/FSPythonScript.py 1.14.24.2 => 1.14.24.3 ===
def params(self): return self._params
def body(self): return self._body
- def get_size(self): return len(self._body)
+ def get_size(self): return len(self.read())
security.declareProtected(FTPAccess, 'manage_FTPget')
def manage_FTPget(self):
=== CMF/CMFCore/MembershipTool.py 1.17 => 1.17.10.1 ===
security.declarePrivate('listActions')
- def listActions(self):
+ def listActions(self, info=None):
return None
security.declarePublic('getHomeFolder')
=== CMF/CMFCore/RegistrationTool.py 1.9 => 1.9.4.1 ===
import re
- __ALLOWED_MEMBER_ID_PATTERN = re.compile( "[A-Za-z][A-Za-z0-9_]*" )
+ __ALLOWED_MEMBER_ID_PATTERN = re.compile( "^[A-Za-z][A-Za-z0-9_]*$" )
security.declareProtected(AddPortalMember, 'isMemberIdAllowed')
def isMemberIdAllowed(self, id):
'''Returns 1 if the ID is not in use and is not reserved.
=== CMF/CMFCore/SkinsTool.py 1.12 => 1.12.10.1 ===
from OFS.Image import Image
from OFS.DTMLMethod import DTMLMethod
+from OFS.ObjectManager import REPLACEABLE
from Products.PythonScripts.PythonScript import PythonScript
try:
@@ -167,6 +168,9 @@
return DTMLMethod( __name__=name )
return None
+
+ # Make the PUT_factory replaceable
+ PUT_factory__replaceable__ = REPLACEABLE
security.declarePrivate('testSkinPath')
=== CMF/CMFCore/TypesTool.py 1.29.4.1 => 1.29.4.2 ===
{'id':'immediate_view', 'type': 'string', 'mode':'w',
'label':'Initial view name'},
+ {'id':'global_allow', 'type': 'boolean', 'mode':'w',
+ 'label':'Implicitly addable?'},
{'id':'filter_content_types', 'type': 'boolean', 'mode':'w',
'label':'Filter content types?'},
{'id':'allowed_content_types'
@@ -92,6 +94,7 @@
filter_content_types = 1
allowed_content_types = ()
allow_discussion = 0
+ global_allow = 1
_actions = ()
def __init__(self, id, **kw):
@@ -165,7 +168,9 @@
type object we are?
"""
if not self.filter_content_types:
- return 1
+ ti = self.getTypeInfo( contentType )
+ return ti is None or ti.globalAllow() \
+ or contentType in self.allowed_content_types
return contentType in self.allowed_content_types
security.declarePublic('getId')
@@ -186,6 +191,13 @@
"""
# Private because this returns the actual structure.
return self._actions
+
+ security.declarePublic('globalAllow')
+ def globalAllow(self):
+ """
+ Should this type be implicitly addable anywhere?
+ """
+ return self.global_allow
security.declarePublic('getActionById')
def getActionById( self, id, default=_marker ):