[CMF-checkins] CVS: CMF/CMFCore - DirectoryView.py:1.44
utils.py:1.54
Yvo Schubbe
y.2004_ at wcm-solutions.de
Mon May 17 09:23:18 EDT 2004
Update of /cvs-repository/CMF/CMFCore
In directory cvs.zope.org:/tmp/cvs-serv27370/CMFCore
Modified Files:
DirectoryView.py utils.py
Log Message:
Merged yuppie-collector210-branch:
- refactored path handling to make it work with any products path: 'filepath' is now always the absolute filepath, 'minimal_fp' the cross-platform / cross-setup relative path. 'dirpath' is the minimal_fp stored in DirectoryView objects.
- some cleanup
=== CMF/CMFCore/DirectoryView.py 1.43 => 1.44 ===
--- CMF/CMFCore/DirectoryView.py:1.43 Thu Apr 29 12:13:16 2004
+++ CMF/CMFCore/DirectoryView.py Mon May 17 09:22:47 2004
@@ -17,8 +17,8 @@
import re
from os import path, listdir, stat
-import sys
from sys import exc_info
+from sys import platform
from types import StringType
from AccessControl import ClassSecurityInfo
@@ -33,13 +33,14 @@
from OFS.ObjectManager import bad_id
from zLOG import LOG, ERROR
-from permissions import AccessContentsInformation
-from permissions import ManagePortal
from FSMetadata import FSMetadata
from FSObject import BadFile
+from permissions import AccessContentsInformation
+from permissions import ManagePortal
from utils import _dtmldir
-from utils import expandpath
from utils import minimalpath
+from utils import normalize
+
__reload_module__ = 0
@@ -68,12 +69,13 @@
_v_last_read = 0
_v_last_filelist = [] # Only used on Win32
- def __init__(self, expanded_fp, minimal_fp):
- self.filepath = minimal_fp
+ def __init__(self, filepath, minimal_fp):
+ self._filepath = filepath
+ self._minimal_fp = minimal_fp
subdirs = []
- for entry in _filtered_listdir(expanded_fp):
- e_fp = path.join(expanded_fp, entry)
- if path.isdir(e_fp):
+ for entry in _filtered_listdir(self._filepath):
+ entry_filepath = path.join(self._filepath, entry)
+ if path.isdir(entry_filepath):
subdirs.append(entry)
self.subdirs = tuple(subdirs)
@@ -91,13 +93,11 @@
self.data = None
def _readTypesFile(self):
- '''
- Reads the .objects file produced by FSDump.
- '''
+ """ Read the .objects file produced by FSDump.
+ """
types = {}
- fp = expandpath(self.filepath)
try:
- f = open( path.join(fp, '.objects'), 'rt' )
+ f = open( path.join(self._filepath, '.objects'), 'rt' )
except IOError:
pass
else:
@@ -118,14 +118,13 @@
mtime=0
filelist=[]
try:
- fp = expandpath(self.filepath)
- mtime = stat(fp)[8]
- if sys.platform == 'nt':
+ mtime = stat(self._filepath)[8]
+ if platform == 'nt':
# some Windows directories don't change mtime
# when a file is added to or deleted from them :-(
# So keep a list of files as well, and see if that
# changes
- path.walk(fp,_walker,filelist)
+ path.walk(self._filepath, _walker, filelist)
filelist.sort()
except:
LOG('DirectoryView',
@@ -164,23 +163,22 @@
def prepareContents(self, registry, register_subdirs=0):
# Creates objects for each file.
- fp = expandpath(self.filepath)
data = {}
objects = []
types = self._readTypesFile()
- for entry in _filtered_listdir(fp):
+ for entry in _filtered_listdir(self._filepath):
if not self._isAllowableFilename(entry):
continue
- e_filepath = path.join(self.filepath, entry)
- e_fp = expandpath(e_filepath)
- if path.isdir(e_fp):
+ entry_minimal_fp = '/'.join( (self._minimal_fp, entry) )
+ entry_filepath = path.join(self._filepath, entry)
+ if path.isdir(entry_filepath):
# Add a subdirectory only if it was previously registered,
# unless register_subdirs is set.
- info = registry.getDirectoryInfo(e_filepath)
+ info = registry.getDirectoryInfo(entry_minimal_fp)
if info is None and register_subdirs:
# Register unknown subdirs
- registry.registerDirectoryByPath(e_fp)
- info = registry.getDirectoryInfo(e_filepath)
+ registry.registerDirectoryByPath(entry_filepath)
+ info = registry.getDirectoryInfo(entry_minimal_fp)
if info is not None:
mt = types.get(entry)
t = None
@@ -188,7 +186,7 @@
t = registry.getTypeByMetaType(mt)
if t is None:
t = DirectoryView
- ob = t(entry, e_filepath)
+ ob = t(entry, entry_minimal_fp)
ob_id = ob.getId()
data[ob_id] = ob
objects.append({'id': ob_id, 'meta_type': ob.meta_type})
@@ -217,10 +215,10 @@
t = registry.getTypeByExtension(ext)
if t is not None:
- metadata = FSMetadata(e_fp)
+ metadata = FSMetadata(entry_filepath)
metadata.read()
try:
- ob = t(name, e_filepath, fullname=entry,
+ ob = t(name, entry_minimal_fp, fullname=entry,
properties=metadata.getProperties())
except:
import traceback
@@ -233,7 +231,7 @@
'\n'.join(exc_lines) )
ob = BadFile( name,
- e_filepath,
+ entry_minimal_fp,
exc_str='\r\n'.join(exc_lines),
fullname=entry )
finally:
@@ -312,26 +310,23 @@
# 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
- fp = minimalpath(filepath)
- normfilepath = path.normpath(filepath)
- self._directories[fp] = di = DirectoryInformation(normfilepath, fp)
+ minimal_fp = minimalpath(filepath)
+ info = DirectoryInformation(filepath, minimal_fp)
+ self._directories[minimal_fp] = info
if subdirs:
- for entry in di.getSubdirs():
- e_filepath = path.join(normfilepath, entry)
- self.registerDirectoryByPath(e_filepath, subdirs)
+ for entry in info.getSubdirs():
+ entry_filepath = path.join(filepath, entry)
+ self.registerDirectoryByPath(entry_filepath, subdirs)
- def reloadDirectory(self, filepath):
- info = self.getDirectoryInfo(filepath)
+ def reloadDirectory(self, minimal_fp):
+ info = self.getDirectoryInfo(minimal_fp)
if info is not None:
info.reload()
- def getDirectoryInfo(self, filepath):
+ def getDirectoryInfo(self, minimal_fp):
# This is called when we need to get hold of the information
- # for a minimal path.
- # minimalpath is called on the supplied path on the hope
- # that if it is incorrect, something can be done to fix it.
- # Can return None.
- return self._directories.get(minimalpath(filepath), None)
+ # for a minimal path. Can return None.
+ return self._directories.get(minimal_fp, None)
def listDirectories(self):
dirs = self._directories.keys()
@@ -380,8 +375,8 @@
class DirectoryView (Persistent):
- '''
- '''
+ """ Directory views mount filesystem directories.
+ """
meta_type = 'Filesystem Directory View'
_dirpath = None
_objects = ()
@@ -392,13 +387,21 @@
def __of__(self, parent):
info = _dirreg.getDirectoryInfo(self._dirpath)
- if info is not None:
- info = info.getContents(_dirreg)
+ if info is None:
+ # for DirectoryViews created with CMF versions before 1.5
+ # this is basically the old minimalpath() code
+ self._dirpath = normalize(self._dirpath)
+ index = self._dirpath.rfind('Products')
+ if index == -1:
+ index = self._dirpath.rfind('products')
+ if index != -1:
+ self._dirpath = self._dirpath[index+len('products/'):]
+ info = _dirreg.getDirectoryInfo(self._dirpath)
if info is None:
data = {}
objects = ()
else:
- data, objects = info
+ data, objects = info.getContents(_dirreg)
s = DirectoryViewSurrogate(self, data, objects)
res = s.__of__(parent)
return res
@@ -438,8 +441,7 @@
security.declareProtected(ManagePortal, 'manage_properties')
def manage_properties( self, dirpath, REQUEST=None ):
- """
- Update the directory path of the DV.
+ """ Update the directory path of the DirectoryView.
"""
self.__dict__['_real']._dirpath = dirpath
if REQUEST is not None:
@@ -455,10 +457,8 @@
security.declareProtected(AccessContentsInformation, 'listCustFolderPaths')
def listCustFolderPaths(self, adding_meta_type=None):
- '''
- Returns a list of possible customization folders
- as key, value pairs.
- '''
+ """ List possible customization folders as key, value pairs.
+ """
rval = []
ob = self.getCustomizableObject()
listFolderHierarchy(ob, '', rval, adding_meta_type)
@@ -478,49 +478,45 @@
manage_addDirectoryViewForm = HTMLFile('dtml/addFSDirView', globals())
-def createDirectoryView(parent, filepath, id=None):
- '''
- Adds either a DirectoryView or a derivative object.
- '''
- info = _dirreg.getDirectoryInfo(filepath)
+def createDirectoryView(parent, minimal_fp, id=None):
+ """ Add either a DirectoryView or a derivative object.
+ """
+ info = _dirreg.getDirectoryInfo(minimal_fp)
if info is None:
- raise ValueError('Not a registered directory: %s' % filepath)
+ raise ValueError('Not a registered directory: %s' % minimal_fp)
if not id:
- id = path.split(filepath)[-1]
+ id = minimal_fp.split('/')[-1]
else:
id = str(id)
- ob = DirectoryView(id, filepath)
+ ob = DirectoryView(id, minimal_fp)
parent._setObject(id, ob)
def addDirectoryViews(ob, name, _prefix):
- '''
- Adds a directory view for every subdirectory of the
- given directory.
- '''
- # Meant to be called by filesystem-based code.
- # Note that registerDirectory() still needs to be called
- # by product initialization code to satisfy
- # persistence demands.
+ """ Add a directory view for every subdirectory of the given directory.
+
+ Meant to be called by filesystem-based code. Note that registerDirectory()
+ still needs to be called by product initialization code to satisfy
+ persistence demands.
+ """
if not isinstance(_prefix, StringType):
_prefix = package_home(_prefix)
- fp = path.join(_prefix, name)
- filepath = minimalpath(fp)
- info = _dirreg.getDirectoryInfo(filepath)
+ filepath = path.join(_prefix, name)
+ minimal_fp = minimalpath(filepath)
+ info = _dirreg.getDirectoryInfo(minimal_fp)
if info is None:
- raise ValueError('Not a registered directory: %s' % filepath)
+ raise ValueError('Not a registered directory: %s' % minimal_fp)
for entry in info.getSubdirs():
- filepath2 = path.join(filepath, entry)
- createDirectoryView(ob, filepath2, entry)
+ entry_minimal_fp = '/'.join( (minimal_fp, entry) )
+ createDirectoryView(ob, entry_minimal_fp, entry)
-def manage_addDirectoryView(self, filepath, id=None, REQUEST=None):
- '''
- Adds either a DirectoryView or a derivative object.
- '''
- createDirectoryView(self, filepath, id)
+def manage_addDirectoryView(self, dirpath, id=None, REQUEST=None):
+ """ Add either a DirectoryView or a derivative object.
+ """
+ createDirectoryView(self, dirpath, id)
if REQUEST is not None:
return self.manage_main(self, REQUEST)
def manage_listAvailableDirectories(*args):
- '''
- '''
+ """ List registered directories.
+ """
return list(_dirreg.listDirectories())
=== CMF/CMFCore/utils.py 1.53 => 1.54 ===
--- CMF/CMFCore/utils.py:1.53 Sun May 16 11:35:58 2004
+++ CMF/CMFCore/utils.py Mon May 17 09:22:47 2004
@@ -17,6 +17,7 @@
import os
from os import path as os_path
+from os.path import abspath
import re
from types import StringType
from types import UnicodeType
@@ -668,27 +669,20 @@
#
security.declarePublic('normalize')
def normalize(p):
- # the weird .replace is needed to help normpath
- # when dealing with Windows paths under *nix
- return os_path.normpath(p.replace('\\','/'))
-
-separators = (os.sep, os.altsep)
+ # the first .replace is needed to help normpath when dealing with Windows
+ # paths under *nix, the second to normalize to '/'
+ return os_path.normpath(p.replace('\\','/')).replace('\\','/')
import Products
-ProductsPath = []
-ProductsPath = map(normalize,Products.__path__)
+ProductsPath = [ abspath(ppath) for ppath in Products.__path__ ]
security.declarePublic('expandpath')
def expandpath(p):
- # Converts a minimal path to an absolute path.
-
- # This has a slight weakness in that if someone creates a new
- # product with the same name as an old one, then the skins may
- # become confused between the two.
- # However, that's an acceptable risk as people don't seem
- # to re-use product names ever (it would create ZODB persistence
- # problems too ;-)
+ """ Convert minimal filepath to (expanded) filepath.
+ The (expanded) filepath is the valid absolute path on the current platform
+ and setup.
+ """
p = os_path.normpath(p)
if os_path.isabs(p):
return p
@@ -704,14 +698,17 @@
security.declarePublic('minimalpath')
def minimalpath(p):
- # This trims down to just beyond a 'Products' root if it can.
- # otherwise, it returns what it was given.
- # In either case, the path is normalized.
- p = normalize(p)
- index = p.rfind('Products')
- if index == -1:
- index = p.rfind('products')
- if index == -1:
- # couldn't normalise
- return p
- return p[index+len('products/'):]
+ """ Convert (expanded) filepath to minimal filepath.
+
+ The minimal filepath is the cross-platform / cross-setup path stored in
+ persistent objects and used as key in the directory registry.
+
+ Returns a slash-separated path relative to the Products path. If it can't
+ be found, a normalized path is returned.
+ """
+ p = abspath(p)
+ for ppath in ProductsPath:
+ if p.startswith(ppath):
+ p = p[len(ppath)+1:]
+ break
+ return p.replace('\\','/')
More information about the CMF-checkins
mailing list