[Checkins] SVN: CMF/trunk/C merged yuppie-collector467 branch:
Yvo Schubbe
y.2007- at wcm-solutions.de
Fri Feb 23 12:29:53 EST 2007
Log message for revision 72785:
merged yuppie-collector467 branch:
- refactored path and registry key handling based on wichert's cmf-dirview-keying-2 patch
- updated profiles
Changed:
U CMF/trunk/CHANGES.txt
U CMF/trunk/CMFActionIcons/profiles/actionicons/skins.xml
U CMF/trunk/CMFCalendar/profiles/default/skins.xml
U CMF/trunk/CMFCore/DirectoryView.py
U CMF/trunk/CMFCore/exportimport/tests/test_skins.py
U CMF/trunk/CMFCore/tests/__init__.py
U CMF/trunk/CMFCore/tests/base/testcase.py
U CMF/trunk/CMFCore/tests/test_DirectoryView.py
U CMF/trunk/CMFCore/tests/test_utils.py
U CMF/trunk/CMFCore/utils.py
U CMF/trunk/CMFDefault/profiles/default/skins.xml
U CMF/trunk/CMFTopic/profiles/default/skins.xml
-=-
Modified: CMF/trunk/CHANGES.txt
===================================================================
--- CMF/trunk/CHANGES.txt 2007-02-23 17:11:17 UTC (rev 72784)
+++ CMF/trunk/CHANGES.txt 2007-02-23 17:29:52 UTC (rev 72785)
@@ -2,6 +2,11 @@
New Features
+ - DirectoryView: Added support for non-product packages.
+ This introduces new registry keys. Old registry keys stored in
+ persistent DirectoryView objects are updated on the fly.
+ (http://www.zope.org/Collectors/CMF/467)
+
- Document: Added two new methods for safety belt handling.
- setup handlers: Improved properties handler.
@@ -34,6 +39,8 @@
Others
+ - CMFCore utils: Marked 'minimalpath' and 'expandpath' as deprecated.
+
- The CMF now depends on Zope 2.10.2 or higher.
Modified: CMF/trunk/CMFActionIcons/profiles/actionicons/skins.xml
===================================================================
--- CMF/trunk/CMFActionIcons/profiles/actionicons/skins.xml 2007-02-23 17:11:17 UTC (rev 72784)
+++ CMF/trunk/CMFActionIcons/profiles/actionicons/skins.xml 2007-02-23 17:29:52 UTC (rev 72785)
@@ -1,7 +1,7 @@
<?xml version="1.0"?>
<object name="portal_skins" meta_type="CMF Skins Tool">
<object name="actionicons" meta_type="Filesystem Directory View"
- directory="CMFActionIcons/skins/actionicons"/>
+ directory="Products.CMFActionIcons:skins/actionicons"/>
<skin-path name="*">
<layer name="actionicons" insert-before="zpt_content"/>
</skin-path>
Modified: CMF/trunk/CMFCalendar/profiles/default/skins.xml
===================================================================
--- CMF/trunk/CMFCalendar/profiles/default/skins.xml 2007-02-23 17:11:17 UTC (rev 72784)
+++ CMF/trunk/CMFCalendar/profiles/default/skins.xml 2007-02-23 17:29:52 UTC (rev 72785)
@@ -1,7 +1,7 @@
<?xml version="1.0"?>
<object name="portal_skins" meta_type="CMF Skins Tool">
<object name="zpt_calendar" meta_type="Filesystem Directory View"
- directory="CMFCalendar/skins/zpt_calendar"/>
+ directory="Products.CMFCalendar:skins/zpt_calendar"/>
<skin-path name="*">
<layer name="zpt_calendar" insert-before="zpt_content"/>
</skin-path>
Modified: CMF/trunk/CMFCore/DirectoryView.py
===================================================================
--- CMF/trunk/CMFCore/DirectoryView.py 2007-02-23 17:11:17 UTC (rev 72784)
+++ CMF/trunk/CMFCore/DirectoryView.py 2007-02-23 17:29:52 UTC (rev 72785)
@@ -18,6 +18,7 @@
import logging
import re
from os import path, listdir, stat
+from os.path import abspath
from sys import platform
from warnings import warn
@@ -27,7 +28,6 @@
from Globals import DTMLFile
from Globals import HTMLFile
from Globals import InitializeClass
-from Globals import package_home
from Globals import Persistent
from OFS.Folder import Folder
from OFS.ObjectManager import bad_id
@@ -39,8 +39,10 @@
from permissions import AccessContentsInformation
from permissions import ManagePortal
from utils import _dtmldir
-from utils import minimalpath
from utils import normalize
+from utils import getPackageName
+from utils import getPackageLocation
+from utils import ProductsPath
logger = logging.getLogger('CMFCore.DirectoryView')
@@ -76,14 +78,40 @@
for name in names ]
listdir.extend(results)
+
+def _generateKey(package, subdir):
+ """Generate a key for a path inside a package.
+
+ The key has the quality that keys for subdirectories can be derived by
+ simply appending to the key.
+ """
+ return ':'.join((package, subdir.replace('\\', '/')))
+
+def _findProductForPath(path, subdir=None):
+ # like minimalpath, but raises an error if path is not inside a product
+ p = abspath(path)
+ for ppath in ProductsPath:
+ if p.startswith(ppath):
+ dirpath = p[len(ppath)+1:]
+ parts = dirpath.replace('\\', '/').split('/', 1)
+ parts.append('')
+ if subdir:
+ subdir = '/'.join((parts[1], subdir))
+ else:
+ subdir = parts[1]
+ return ('Products.' + parts[0], subdir)
+
+ raise ValueError('Path is not inside a product')
+
+
class DirectoryInformation:
data = None
_v_last_read = 0
_v_last_filelist = [] # Only used on Win32
- def __init__(self, filepath, minimal_fp, ignore=ignore):
+ def __init__(self, filepath, reg_key, ignore=ignore):
self._filepath = filepath
- self._minimal_fp = minimal_fp
+ self._reg_key = reg_key
self.ignore=base_ignore + tuple(ignore)
if platform == 'win32':
self._walker = _walker(self.ignore)
@@ -182,12 +210,13 @@
if path.isdir(entry_filepath):
# Add a subdirectory only if it was previously registered,
# unless register_subdirs is set.
- entry_minimal_fp = '/'.join( (self._minimal_fp, entry) )
- info = registry.getDirectoryInfo(entry_minimal_fp)
+ entry_reg_key = '/'.join((self._reg_key, entry))
+ info = registry.getDirectoryInfo(entry_reg_key)
if info is None and register_subdirs:
# Register unknown subdirs
- registry.registerDirectoryByPath(entry_filepath)
- info = registry.getDirectoryInfo(entry_minimal_fp)
+ registry.registerDirectoryByKey(entry_filepath,
+ entry_reg_key)
+ info = registry.getDirectoryInfo(entry_reg_key)
if info is not None:
# Folders on the file system have no extension or
# meta_type, as a crutch to enable customizing what gets
@@ -203,7 +232,7 @@
metadata = FSMetadata(entry_filepath)
metadata.read()
ob = t( entry
- , entry_minimal_fp
+ , entry_reg_key
, properties=metadata.getProperties()
)
ob_id = ob.getId()
@@ -303,44 +332,91 @@
# This what is actually called to register a
# file system directory to become a FSDV.
if not isinstance(_prefix, basestring):
- _prefix = package_home(_prefix)
- filepath = path.join(_prefix, name)
- self.registerDirectoryByPath(filepath, subdirs, ignore=ignore)
+ package = getPackageName(_prefix)
+ filepath = path.join(getPackageLocation(package), name)
+ else:
+ warn('registerDirectory() called with a path; should be called '
+ 'with globals', DeprecationWarning, stacklevel=2)
+ filepath = path.join(_prefix, name)
+ (package, name) = _findProductForPath(_prefix, name)
+ reg_key = _generateKey(package, name)
+ self.registerDirectoryByKey(filepath, reg_key, subdirs, ignore)
- def registerDirectoryByPath(self, filepath, subdirs=1, ignore=ignore):
- # This is indirectly called during registration of
- # a directory. As you can see, minimalpath is called
- # on the supplied path at this point.
- # The idea is that the registry will only contain
- # small paths that are likely to work across platforms
- # and SOFTWARE_HOME, INSTANCE_HOME and PRODUCTS_PATH setups
- minimal_fp = minimalpath(filepath)
- info = DirectoryInformation(filepath, minimal_fp, ignore=ignore)
- self._directories[minimal_fp] = info
+ def registerDirectoryByKey(self, filepath, reg_key, subdirs=1,
+ ignore=ignore):
+ info = DirectoryInformation(filepath, reg_key, ignore)
+ self._directories[reg_key] = info
if subdirs:
for entry in info.getSubdirs():
entry_filepath = path.join(filepath, entry)
- self.registerDirectoryByPath( entry_filepath
- , subdirs
- , ignore=ignore
- )
+ entry_reg_key = '/'.join((reg_key, entry))
+ self.registerDirectoryByKey(entry_filepath, entry_reg_key,
+ subdirs, ignore)
- def reloadDirectory(self, minimal_fp):
- info = self.getDirectoryInfo(minimal_fp)
+ def registerDirectoryByPath(self, filepath, subdirs=1, ignore=ignore):
+ warn('registerDirectoryByPath() is deprecated and will be removed in '
+ 'CMF 2.3. Please use registerDirectoryByKey() instead.',
+ DeprecationWarning, stacklevel=2)
+ (package, subdir) = _findProductForPath(filepath)
+ reg_key = _generateKey(package, subdir)
+ self.registerDirectoryByKey(filepath, reg_key, subdirs, ignore)
+
+ def reloadDirectory(self, reg_key):
+ info = self.getDirectoryInfo(reg_key)
if info is not None:
info.reload()
- def getDirectoryInfo(self, minimal_fp):
+ def getDirectoryInfo(self, reg_key):
# This is called when we need to get hold of the information
# for a minimal path. Can return None.
- return self._directories.get(minimal_fp, None)
+ return self._directories.get(reg_key, None)
def listDirectories(self):
dirs = self._directories.keys()
dirs.sort()
return dirs
+ def getCurrentKeyFormat(self, reg_key):
+ # BBB: method will be removed in CMF 2.3
+ if reg_key in self._directories:
+ return reg_key
+
+ # for DirectoryViews created with CMF versions before 2.1
+ # a path relative to Products/ was used
+ dirpath = reg_key.replace('\\', '/')
+ if dirpath.startswith('Products/'):
+ dirpath = dirpath[9:]
+ product = ['Products']
+ dirparts = dirpath.split('/')
+ while dirparts:
+ product.append(dirparts[0])
+ dirparts = dirparts[1:]
+ possible_key = _generateKey('.'.join(product), '/'.join(dirparts))
+ if possible_key in self._directories:
+ return possible_key
+
+ # for DirectoryViews created with CMF versions before 1.5
+ # this is basically the old minimalpath() code
+ dirpath = normalize(reg_key)
+ index = dirpath.rfind('Products')
+ if index == -1:
+ index = dirpath.rfind('products')
+ if index != -1:
+ dirpath = dirpath[index+len('products/'):]
+ product = ['Products']
+ dirparts = dirpath.split('/')
+ while dirparts:
+ product.append(dirparts[0])
+ dirparts = dirparts[1:]
+ possible_key = _generateKey('.'.join(product),
+ '/'.join(dirparts))
+ if possible_key in self._directories:
+ return possible_key
+
+ raise ValueError('Unsupported key given: %s' % reg_key)
+
+
_dirreg = DirectoryRegistry()
registerDirectory = _dirreg.registerDirectory
registerFileExtension = _dirreg.registerFileExtension
@@ -393,35 +469,29 @@
_properties = None
_objects = ()
- def __init__(self, id, dirpath='', fullname=None, properties=None):
+ def __init__(self, id, reg_key='', fullname=None, properties=None):
if properties:
# Since props come from the filesystem, this should be
# safe.
self.__dict__.update(properties)
self.id = id
- self._dirpath = dirpath
+ self._dirpath = reg_key
self._properties = properties
def __of__(self, parent):
- dirpath = self._dirpath
- info = _dirreg.getDirectoryInfo(dirpath)
+ reg_key = self._dirpath
+ info = _dirreg.getDirectoryInfo(reg_key)
if info is None:
- # for DirectoryViews created with CMF versions before 1.5
- # this is basically the old minimalpath() code
- dirpath = normalize(dirpath)
- index = dirpath.rfind('Products')
- if index == -1:
- index = dirpath.rfind('products')
- if index != -1:
- dirpath = dirpath[index+len('products/'):]
- info = _dirreg.getDirectoryInfo(dirpath)
- if info is not None:
- # update the directory view with a corrected path
- self._dirpath = dirpath
- elif self._dirpath:
- warn('DirectoryView %s refers to a non-existing path %s'
- % (self.id, dirpath), UserWarning)
+ try:
+ reg_key = self._dirpath = _dirreg.getCurrentKeyFormat(reg_key)
+ info = _dirreg.getDirectoryInfo(reg_key)
+ except ValueError:
+ # During GenericSetup a view will be created with an empty
+ # reg_key. This is expected behaviour, so do not warn about it.
+ if reg_key:
+ warn('DirectoryView %s refers to a non-existing path %r' %
+ (self.id, reg_key), UserWarning)
if info is None:
data = {}
objects = ()
@@ -471,10 +541,10 @@
manage_propertiesForm = DTMLFile( 'dirview_properties', _dtmldir )
security.declareProtected(ManagePortal, 'manage_properties')
- def manage_properties( self, dirpath, REQUEST=None ):
+ def manage_properties(self, reg_key, REQUEST=None):
""" Update the directory path of the DirectoryView.
"""
- self.__dict__['_real']._dirpath = dirpath
+ self.__dict__['_real']._dirpath = reg_key
if REQUEST is not None:
REQUEST['RESPONSE'].redirect( '%s/manage_propertiesForm'
% self.absolute_url() )
@@ -509,17 +579,17 @@
manage_addDirectoryViewForm = HTMLFile('dtml/addFSDirView', globals())
-def createDirectoryView(parent, minimal_fp, id=None):
+def createDirectoryView(parent, reg_key, id=None):
""" Add either a DirectoryView or a derivative object.
"""
- info = _dirreg.getDirectoryInfo(minimal_fp)
+ info = _dirreg.getDirectoryInfo(reg_key)
if info is None:
- raise ValueError('Not a registered directory: %s' % minimal_fp)
+ raise ValueError('Not a registered directory: %s' % reg_key)
if not id:
- id = minimal_fp.split('/')[-1]
+ id = reg_key.split('/')[-1]
else:
id = str(id)
- ob = DirectoryView(id, minimal_fp)
+ ob = DirectoryView(id, reg_key)
parent._setObject(id, ob)
def addDirectoryViews(ob, name, _prefix):
@@ -530,20 +600,23 @@
persistence demands.
"""
if not isinstance(_prefix, basestring):
- _prefix = package_home(_prefix)
- filepath = path.join(_prefix, name)
- minimal_fp = minimalpath(filepath)
- info = _dirreg.getDirectoryInfo(minimal_fp)
+ package = getPackageName(_prefix)
+ else:
+ warn('addDirectoryViews() called with a path; should be called with '
+ 'globals', DeprecationWarning, stacklevel=2)
+ (package, name) = _findProductForPath(_prefix, name)
+ reg_key = _generateKey(package, name)
+ info = _dirreg.getDirectoryInfo(reg_key)
if info is None:
- raise ValueError('Not a registered directory: %s' % minimal_fp)
+ raise ValueError('Not a registered directory: %s' % reg_key)
for entry in info.getSubdirs():
- entry_minimal_fp = '/'.join( (minimal_fp, entry) )
- createDirectoryView(ob, entry_minimal_fp, entry)
+ entry_reg_key = '/'.join((reg_key, entry))
+ createDirectoryView(ob, entry_reg_key, entry)
-def manage_addDirectoryView(self, dirpath, id=None, REQUEST=None):
+def manage_addDirectoryView(self, reg_key, id=None, REQUEST=None):
""" Add either a DirectoryView or a derivative object.
"""
- createDirectoryView(self, dirpath, id)
+ createDirectoryView(self, reg_key, id)
if REQUEST is not None:
return self.manage_main(self, REQUEST)
Modified: CMF/trunk/CMFCore/exportimport/tests/test_skins.py
===================================================================
--- CMF/trunk/CMFCore/exportimport/tests/test_skins.py 2007-02-23 17:11:17 UTC (rev 72784)
+++ CMF/trunk/CMFCore/exportimport/tests/test_skins.py 2007-02-23 17:29:52 UTC (rev 72785)
@@ -45,7 +45,7 @@
<object name="portal_skins" meta_type="CMF Skins Tool" allow_any="False"
cookie_persistence="False" default_skin="" request_varname="portal_skin">
<object name="foo_directoryview" meta_type="Filesystem Directory View"
- directory="CMFCore/exportimport/tests/one"/>
+ directory="Products.CMFCore.exportimport.tests:one"/>
<skin-path name="foo_path">
<layer name="one"/>
</skin-path>
@@ -64,11 +64,11 @@
<object name="portal_skins" meta_type="Dummy Skins Tool" allow_any="True"
cookie_persistence="True" default_skin="basic" request_varname="skin_var">
<object name="one" meta_type="Filesystem Directory View"
- directory="CMFCore/exportimport/tests/one"/>
+ directory="Products.CMFCore.exportimport.tests:one"/>
<object name="three" meta_type="Filesystem Directory View"
- directory="CMFCore/exportimport/tests/three"/>
+ directory="Products.CMFCore.exportimport.tests:three"/>
<object name="two" meta_type="Filesystem Directory View"
- directory="CMFCore/exportimport/tests/two"/>
+ directory="Products.CMFCore.exportimport.tests:two"/>
<skin-path name="basic">
<layer name="one"/>
</skin-path>
@@ -84,7 +84,7 @@
<?xml version="1.0"?>
<object name="portal_skins" meta_type="Dummy Skins Tool">
<object name="three" meta_type="Filesystem Directory View"
- directory="CMFCore/exportimport/tests/three"/>
+ package="Products.CMFCore" path="exportimport/tests/three"/>
<skin-path name="*">
<layer name="three" insert-before="two"/>
</skin-path>
@@ -95,7 +95,7 @@
<?xml version="1.0"?>
<object name="portal_skins" meta_type="Dummy Skins Tool">
<object name="four" meta_type="Filesystem Directory View"
- directory="CMFCore/exportimport/tests/four"/>
+ directory="Products.CMFCore.exportimport.tests:four"/>
<skin-path name="*">
<layer name="four" insert-after="three"/>
</skin-path>
@@ -189,10 +189,10 @@
self._olddirreg = DirectoryView._dirreg
DirectoryView._dirreg = DirectoryView.DirectoryRegistry()
self._dirreg = DirectoryView._dirreg
- self._dirreg.registerDirectory('one', _TESTS_PATH)
- self._dirreg.registerDirectory('two', _TESTS_PATH)
- self._dirreg.registerDirectory('three', _TESTS_PATH)
- self._dirreg.registerDirectory('four', _TESTS_PATH)
+ self._dirreg.registerDirectory('one', globals())
+ self._dirreg.registerDirectory('two', globals())
+ self._dirreg.registerDirectory('three', globals())
+ self._dirreg.registerDirectory('four', globals())
def tearDown(self):
from Products.CMFCore import DirectoryView
@@ -576,6 +576,16 @@
def test_suite():
+ # reimport to make sure tests are run from Products
+ from Products.CMFCore.exportimport.tests.test_skins \
+ import DirectoryViewAdapterTests
+ from Products.CMFCore.exportimport.tests.test_skins \
+ import exportSkinsToolTests
+ from Products.CMFCore.exportimport.tests.test_skins \
+ import importSkinsToolTests
+ from Products.CMFCore.exportimport.tests.test_skins \
+ import SkinsToolXMLAdapterTests
+
return unittest.TestSuite((
unittest.makeSuite(DirectoryViewAdapterTests),
unittest.makeSuite(SkinsToolXMLAdapterTests),
Modified: CMF/trunk/CMFCore/tests/__init__.py
===================================================================
--- CMF/trunk/CMFCore/tests/__init__.py 2007-02-23 17:11:17 UTC (rev 72784)
+++ CMF/trunk/CMFCore/tests/__init__.py 2007-02-23 17:29:52 UTC (rev 72785)
@@ -4,3 +4,5 @@
As test suites are added, they should be added to the
mega-test-suite in Products.CMFCore.tests.test_all.py
"""
+
+_globals = globals()
Modified: CMF/trunk/CMFCore/tests/base/testcase.py
===================================================================
--- CMF/trunk/CMFCore/tests/base/testcase.py 2007-02-23 17:11:17 UTC (rev 72784)
+++ CMF/trunk/CMFCore/tests/base/testcase.py 2007-02-23 17:29:52 UTC (rev 72785)
@@ -18,6 +18,7 @@
from dummy import DummyFolder
from security import AnonymousUser
from security import PermissiveSecurityPolicy
+from Products.CMFCore.utils import getPackageLocation
class LogInterceptor:
@@ -208,7 +209,7 @@
def setUp(self):
# store the place where the skin copy will be created
- self.tempname = mktemp()
+ self.tempname = mktemp(dir=getPackageLocation('Products.CMFCore.tests'))
# create the temporary folder
mkdir(self.tempname)
# copy the source fake skin to the new location
Modified: CMF/trunk/CMFCore/tests/test_DirectoryView.py
===================================================================
--- CMF/trunk/CMFCore/tests/test_DirectoryView.py 2007-02-23 17:11:17 UTC (rev 72784)
+++ CMF/trunk/CMFCore/tests/test_DirectoryView.py 2007-02-23 17:29:52 UTC (rev 72785)
@@ -1,14 +1,15 @@
import unittest
import Testing
+import sys
from os import remove, mkdir, rmdir
from os.path import join
from tempfile import mktemp
from Globals import DevelopmentMode
+from Products.CMFCore.tests import _globals
from Products.CMFCore.tests.base.dummy import DummyFolder
-from Products.CMFCore.tests.base.testcase import _prefix
from Products.CMFCore.tests.base.testcase import FSDVTest
from Products.CMFCore.tests.base.testcase import WarningInterceptor
from Products.CMFCore.tests.base.testcase import WritableFSDVTest
@@ -36,16 +37,36 @@
self._trap_warning_output()
from Products.CMFCore.DirectoryView import registerDirectory
from Products.CMFCore.DirectoryView import addDirectoryViews
- registerDirectory('fake_skins', _prefix)
+ registerDirectory('fake_skins', _globals)
self.ob = DummyFolder()
- addDirectoryViews(self.ob, 'fake_skins', _prefix)
+ addDirectoryViews(self.ob, 'fake_skins', _globals)
def tearDown(self):
self._free_warning_output()
+ def test__generateKey(self):
+ from Products.CMFCore.DirectoryView import _generateKey
+
+ key = _generateKey('Products.CMFCore', 'tests')
+ self.assertEqual(key.split(':')[0], 'Products.CMFCore')
+
+ subkey = _generateKey('Products.CMFCore', 'tests\foo')
+ self.failUnless(subkey.startswith(key))
+
+ def test__findProductForPath(self):
+ from Products.CMFCore.DirectoryView import _findProductForPath
+
+ cmfpath = sys.modules['Products.CMFCore'].__path__[0]
+ self.assertEqual(_findProductForPath(cmfpath),
+ ('Products.CMFCore', ''))
+
+ cmfpath = join(cmfpath, 'tests')
+ self.assertEqual(_findProductForPath(cmfpath),
+ ('Products.CMFCore', 'tests'))
+
def test_getDirectoryInfo(self):
skin = self.ob.fake_skin
- skin.manage_properties('CMFCore/tests/fake_skins/fake_skin')
+ skin.manage_properties('Products.CMFCore.tests:fake_skins/fake_skin')
self.failUnless( hasattr(self.ob.fake_skin, 'test1'),
self.ob.fake_skin.getDirPath() )
@@ -106,6 +127,14 @@
self.failUnless( hasattr(self.ob.fake_skin, 'test1'),
self.ob.fake_skin.getDirPath() )
+ # Test pre CMF 2.1 backwards compatibility code in DirectoryView's __of__
+ # method.
+ def test_getDirectoryInfo8(self):
+ skin = self.ob.fake_skin
+ skin.manage_properties('CMFCore/tests/fake_skins/fake_skin')
+ self.failUnless( hasattr(self.ob.fake_skin, 'test1'),
+ self.ob.fake_skin.getDirPath() )
+
# Test we do nothing if given a really wacky path
def test_UnhandleableExpandPath( self ):
from tempfile import mktemp
@@ -116,8 +145,7 @@
# Check that a warning was raised.
from Products.CMFCore import DirectoryView
warnings = [t[0] for t in DirectoryView.__warningregistry__]
- text = 'DirectoryView fake_skin refers to a non-existing path %s' % file
- text = text.replace('\\','/')
+ text = 'DirectoryView fake_skin refers to a non-existing path %r' % file
self.assert_(text in warnings)
self.failUnless(text in self._our_stderr_stream.getvalue())
@@ -129,16 +157,14 @@
# normalize in this unit test.
self.assertEqual( normalize(weirdpath), minimalpath(weirdpath) )
- # this test tests that registerDirectory calls minimalpath correctly
- # the only way to test this works under SOFTWARE_HOME,INSTANCE_HOME and
- # PRODUCTS_PATH setups is to run the test in those environments
- def test_registerDirectoryMinimalPath(self):
+ # this test tests that registerDirectory creates keys in the right format.
+ def test_registerDirectoryKeys(self):
from Products.CMFCore.DirectoryView import _dirreg
dirs = _dirreg._directories
- self.failUnless( dirs.has_key('CMFCore/tests/fake_skins/fake_skin'),
+ self.failUnless( dirs.has_key('Products.CMFCore.tests:fake_skins/fake_skin'),
dirs.keys() )
self.assertEqual( self.ob.fake_skin.getDirPath(),
- 'CMFCore/tests/fake_skins/fake_skin' )
+ 'Products.CMFCore.tests:fake_skins/fake_skin' )
class DirectoryViewTests( FSDVTest ):
Modified: CMF/trunk/CMFCore/tests/test_utils.py
===================================================================
--- CMF/trunk/CMFCore/tests/test_utils.py 2007-02-23 17:11:17 UTC (rev 72784)
+++ CMF/trunk/CMFCore/tests/test_utils.py 2007-02-23 17:29:52 UTC (rev 72785)
@@ -61,7 +61,24 @@
self.assertEqual( contributorsplitter({'Contributors': x}),
['foo', 'bar', 'baz'] )
+ def test_getPackageName(self):
+ from Products.CMFCore.utils import getPackageName
+ from Products.CMFCore.utils import _globals
+ self.assertEqual(getPackageName(globals()), 'Products.CMFCore.tests')
+ self.assertEqual(getPackageName(_globals), 'Products.CMFCore')
+
+ def test_getContainingPackage(self):
+ from Products.CMFCore.utils import getContainingPackage
+
+ self.assertEqual(getContainingPackage('Products.CMFCore.exceptions'),
+ 'Products.CMFCore')
+ self.assertEqual(getContainingPackage('Products.CMFCore'),
+ 'Products.CMFCore')
+ self.assertEqual(getContainingPackage('zope.interface.verify'),
+ 'zope.interface')
+
+
class CoreUtilsSecurityTests(SecurityTest):
def _makeSite(self):
@@ -130,6 +147,9 @@
def test_suite():
+ # reimport to make sure tests are run from Products
+ from Products.CMFCore.tests.test_utils import CoreUtilsTests
+
return unittest.TestSuite((
unittest.makeSuite(CoreUtilsTests),
unittest.makeSuite(CoreUtilsSecurityTests),
Modified: CMF/trunk/CMFCore/utils.py
===================================================================
--- CMF/trunk/CMFCore/utils.py 2007-02-23 17:11:17 UTC (rev 72784)
+++ CMF/trunk/CMFCore/utils.py 2007-02-23 17:29:52 UTC (rev 72785)
@@ -20,6 +20,7 @@
from os import path as os_path
from os.path import abspath
from warnings import warn
+import sys
from AccessControl import ClassSecurityInfo
from AccessControl import getSecurityManager
@@ -55,6 +56,7 @@
security = ModuleSecurityInfo( 'Products.CMFCore.utils' )
+_globals = globals()
_dtmldir = os_path.join( package_home( globals() ), 'dtml' )
_wwwdir = os_path.join( package_home( globals() ), 'www' )
@@ -263,7 +265,6 @@
result.append(value)
return apply(parse_etags,(text[l:],result))
-
def _checkConditionalGET(obj, extra_context):
"""A conditional GET is done using one or both of the request
headers:
@@ -272,7 +273,7 @@
If-None-Match: list ETags (comma delimited, sometimes quoted)
If both conditions are present, both must be satisfied.
-
+
This method checks the caching policy manager to see if
a content object's Last-modified date and ETag satisfy
the conditional GET headers.
@@ -310,14 +311,14 @@
ret = manager.getModTimeAndETag(aq_parent(obj), obj.getId(), extra_context)
if ret is None:
# no appropriate policy or 304s not enabled
- return False
+ return False
(content_mod_time, content_etag, set_last_modified_header) = ret
if content_mod_time:
mod_time_secs = long(content_mod_time.timeTime())
else:
mod_time_secs = None
-
+
if if_modified_since:
# from CMFCore/FSFile.py:
if_modified_since = if_modified_since.split(';')[0]
@@ -331,7 +332,7 @@
if_modified_since=long(DateTime(if_modified_since).timeTime())
except:
if_mod_since=None
-
+
client_etags = None
if if_none_match:
client_etags = parse_etags(if_none_match)
@@ -345,7 +346,7 @@
mod_time_secs < 0 or
mod_time_secs > if_modified_since ):
return False
-
+
if client_etags:
if ( not content_etag or
(content_etag not in client_etags and '*' not in client_etags) ):
@@ -365,9 +366,8 @@
response.setHeader('ETag', content_etag, literal=1)
response.setStatus(304)
delattr(REQUEST, SUBTEMPLATE)
-
+
return True
-
security.declarePrivate('_setCacheHeaders')
def _setCacheHeaders(obj, extra_context):
@@ -728,6 +728,9 @@
The (expanded) filepath is the valid absolute path on the current platform
and setup.
"""
+ warn('expandpath() is deprecated and will be removed in CMF 2.3.',
+ DeprecationWarning, stacklevel=2)
+
p = os_path.normpath(p)
if os_path.isabs(p):
return p
@@ -751,6 +754,9 @@
Returns a slash-separated path relative to the Products path. If it can't
be found, a normalized path is returned.
"""
+ warn('minimalpath() is deprecated and will be removed in CMF 2.3.',
+ DeprecationWarning, stacklevel=2)
+
p = abspath(p)
for ppath in ProductsPath:
if p.startswith(ppath):
@@ -758,6 +764,33 @@
break
return p.replace('\\','/')
+security.declarePrivate('getContainingPackage')
+def getContainingPackage(module):
+ parts = module.split('.')
+ while parts:
+ name = '.'.join(parts)
+ mod = sys.modules[name]
+ if '__init__' in mod.__file__:
+ return name
+ parts = parts[:-1]
+
+ raise ValueError('Unable to find package for module %s' % module)
+
+security.declarePrivate('getPackageLocation')
+def getPackageLocation(module):
+ """ Return the filesystem location of a module.
+
+ This is a simple wrapper around the global package_home method which
+ tricks it into working with just a module name.
+ """
+ package = getContainingPackage(module)
+ return package_home({'__name__' : package})
+
+security.declarePrivate('getPackageName')
+def getPackageName(globals_):
+ module = globals_['__name__']
+ return getContainingPackage(module)
+
def _OldCacheHeaders(obj):
# Old-style checking of modified headers
@@ -782,7 +815,7 @@
mod_since=long(mod_since.timeTime())
except TypeError:
mod_since=None
-
+
if mod_since is not None:
if last_mod > 0 and last_mod <= mod_since:
RESPONSE.setStatus(304)
@@ -816,7 +849,7 @@
mod_since=long(mod_since.timeTime())
except TypeError:
mod_since=None
-
+
if mod_since is not None:
if last_mod > 0 and last_mod <= mod_since:
RESPONSE.setStatus(304)
Modified: CMF/trunk/CMFDefault/profiles/default/skins.xml
===================================================================
--- CMF/trunk/CMFDefault/profiles/default/skins.xml 2007-02-23 17:11:17 UTC (rev 72784)
+++ CMF/trunk/CMFDefault/profiles/default/skins.xml 2007-02-23 17:29:52 UTC (rev 72785)
@@ -3,14 +3,14 @@
cookie_persistence="False" default_skin="Basic"
request_varname="portal_skin">
<object name="Images" meta_type="Filesystem Directory View"
- directory="CMFDefault/skins/Images"/>
+ directory="Products.CMFDefault:skins/Images"/>
<object name="custom" meta_type="Folder"/>
<object name="zpt_content" meta_type="Filesystem Directory View"
- directory="CMFDefault/skins/zpt_content"/>
+ directory="Products.CMFDefault:skins/zpt_content"/>
<object name="zpt_control" meta_type="Filesystem Directory View"
- directory="CMFDefault/skins/zpt_control"/>
+ directory="Products.CMFDefault:skins/zpt_control"/>
<object name="zpt_generic" meta_type="Filesystem Directory View"
- directory="CMFDefault/skins/zpt_generic"/>
+ directory="Products.CMFDefault:skins/zpt_generic"/>
<skin-path name="Basic">
<layer name="custom"/>
<layer name="zpt_content"/>
Modified: CMF/trunk/CMFTopic/profiles/default/skins.xml
===================================================================
--- CMF/trunk/CMFTopic/profiles/default/skins.xml 2007-02-23 17:11:17 UTC (rev 72784)
+++ CMF/trunk/CMFTopic/profiles/default/skins.xml 2007-02-23 17:29:52 UTC (rev 72785)
@@ -1,7 +1,7 @@
<?xml version="1.0"?>
<object name="portal_skins" meta_type="CMF Skins Tool">
<object name="zpt_topic" meta_type="Filesystem Directory View"
- directory="CMFTopic/skins/zpt_topic"/>
+ directory="Products.CMFTopic:skins/zpt_topic"/>
<skin-path name="*">
<layer name="zpt_topic" insert-before="zpt_content"/>
</skin-path>
More information about the Checkins
mailing list