[CMF-checkins] CVS: CMF - DirectoryView.py:1.10 FSObject.py:1.4 utils.py:1.15
tseaver@digicool.com
tseaver@digicool.com
Tue, 19 Jun 2001 22:17:27 -0400 (EDT)
Update of /cvs-repository/CMF/CMFCore
In directory korak.digicool.com:/tmp/cvs-serv6233/CMFCore
Modified Files:
DirectoryView.py FSObject.py utils.py
Log Message:
- Hardened DirectoryView against objects which raise exceptions
during initial reads (typically due to permission problems);
these objects now capture and log the exception, and create
a BadFile object which allows browsing the traceback via the
ZMI (Tracker #317).
--- Updated File DirectoryView.py in package CMF --
--- DirectoryView.py 2001/06/04 02:31:03 1.9
+++ DirectoryView.py 2001/06/20 02:17:27 1.10
@@ -91,49 +91,18 @@
import os
from os import path, listdir, stat
from Acquisition import aq_inner, aq_parent, aq_base
-from string import split, rfind, strip
+from string import split, rfind, strip, join
from App.Common import package_home
from OFS.ObjectManager import bad_id
from OFS.Folder import Folder
from AccessControl import ClassSecurityInfo
from CMFCorePermissions import AccessContentsInformation
import CMFCorePermissions
+from FSObject import BadFile
+from utils import expandpath, minimalpath
__reload_module__ = 0
-def normalize(p):
- return path.abspath(path.normcase(p))
-
-normINSTANCE_HOME = normalize(INSTANCE_HOME)
-normSOFTWARE_HOME = normalize(SOFTWARE_HOME)
-
-separators = (os.sep, os.altsep)
-
-def expandpath(p):
- # Converts a minimal path to an absolute path.
- if path.isabs(p):
- return p
- abs = path.join(normINSTANCE_HOME, p)
- if path.exists(abs):
- return abs
- return path.join(normSOFTWARE_HOME, p)
-
-def minimalpath(p):
- # Trims INSTANCE_HOME or SOFTWARE_HOME from a path.
- p = path.abspath(p)
- abs = normalize(p)
- l = len(normINSTANCE_HOME)
- if abs[:l] != normINSTANCE_HOME:
- l = len(normSOFTWARE_HOME)
- if abs[:l] != normSOFTWARE_HOME:
- # Can't minimize.
- return p
- p = p[l:]
- while p[:1] in separators:
- p = p[1:]
- return p
-
-
class DirectoryInformation:
data = None
_v_last_read = 0
@@ -198,12 +167,13 @@
register_subdirs=changed)
except:
from zLOG import LOG, ERROR
- import sys
+ import sys, traceback
type,value,tb = sys.exc_info()
- LOG('DirectoryView',
- ERROR,
- 'Error during prepareContents:',
- "\nType:%s\nValue:%s\n" % (type,value))
+ LOG( 'DirectoryView'
+ , ERROR
+ , 'Error during prepareContents:'
+ , traceback.format_exception( type, value, tb )
+ )
self.data = {}
self.objects = ()
@@ -265,7 +235,19 @@
if t is None:
t = registry.getTypeByExtension(ext)
if t is not None:
- ob = t(name, e_filepath, fullname=entry)
+ try:
+ ob = t(name, e_filepath, fullname=entry)
+ except:
+ from zLOG import LOG, ERROR
+ import sys, traceback
+ typ, val, tb = sys.exc_info()
+ exc_lines = traceback.format_exception( typ, val, tb )
+ LOG( 'DirectoryView', ERROR, join( exc_lines, '\n' ) )
+ ob = BadFile( name
+ , e_filepath
+ , exc_str=join( exc_lines, '\r\n' )
+ , fullname=entry
+ )
ob_id = ob.getId()
data[ob_id] = ob
objects.append({'id': ob_id, 'meta_type': ob.meta_type})
--- Updated File FSObject.py in package CMF --
--- FSObject.py 2001/04/24 14:12:13 1.3
+++ FSObject.py 2001/06/20 02:17:27 1.4
@@ -93,7 +93,7 @@
from OFS.SimpleItem import Item
from DateTime import DateTime
-from DirectoryView import expandpath
+from utils import expandpath
import CMFCorePermissions
class FSObject(Acquisition.Implicit, Item):
@@ -193,3 +193,86 @@
return self._filepath
Globals.InitializeClass(FSObject)
+
+class BadFile( FSObject ):
+ """
+ Represent a file which was not readable or parseable
+ as its intended type.
+ """
+ meta_type = 'Bad File'
+ icon = 'p_/broken'
+
+ BAD_FILE_VIEW = """\
+<dtml-var manage_page_header>
+<dtml-var manage_tabs>
+<h2> Bad Filesystem Object: &dtml-getId; </h2>
+
+<h3> File Contents </h3>
+<pre>
+<dtml-var getFileContents>
+</pre>
+
+<h3> Exception </h3>
+<pre>
+<dtml-var getExceptionText>
+</pre>
+<dtml-var manage_page_footer>
+"""
+
+ manage_options=(
+ {'label':'Error', 'action':'manage_showError'},
+ )
+
+ def __init__( self, id, filepath, exc_str=''
+ , fullname=None, properties=None):
+ id = fullname or id # Use the whole filename.
+ self.exc_str = exc_str
+ self.file_contents = ''
+ FSObject.__init__(self, id, filepath, fullname, properties)
+
+ security = ClassSecurityInfo()
+
+ showError = Globals.HTML( BAD_FILE_VIEW )
+ security.declareProtected( CMFCorePermissions.ManagePortal
+ , 'manage_showError' )
+ def manage_showError( self, REQUEST ):
+ """
+ """
+ return self.showError( self, REQUEST )
+
+ security.declarePrivate( '_readFile' )
+ def _readFile( self, reparse ):
+ """Read the data from the filesystem.
+
+ Read the file indicated by exandpath(self._filepath), and parse the
+ data if necessary. 'reparse' is set when reading the second
+ time and beyond.
+ """
+ try:
+ fp = expandpath(self._filepath)
+ file = open(fp, 'rb')
+ try:
+ data = self.file_contents = file.read()
+ finally:
+ file.close()
+ except:
+ data = self.file_contents = None #give up
+ return data
+
+ security.declarePublic( 'getFileContents' )
+ def getFileContents( self ):
+ """
+ Return the contents of the file, if we could read it.
+ """
+ return self.file_contents
+
+ security.declarePublic( 'getExceptionText' )
+ def getExceptionText( self ):
+ """
+ Return the exception thrown while reading or parsing
+ the file.
+ """
+ return self.exc_str
+
+
+Globals.InitializeClass( BadFile )
--- Updated File utils.py in package CMF --
--- utils.py 2001/06/11 19:11:59 1.14
+++ utils.py 2001/06/20 02:17:27 1.15
@@ -567,7 +567,41 @@
keylist = map(string.strip, keylist)
out.extend(filter(operator.truth, keylist))
return out
-
+
+#
+# Directory-handling utilities
+#
+def normalize(p):
+ return path.abspath(path.normcase(p))
+
+normINSTANCE_HOME = normalize(INSTANCE_HOME)
+normSOFTWARE_HOME = normalize(SOFTWARE_HOME)
+
+separators = (os.sep, os.altsep)
+
+def expandpath(p):
+ # Converts a minimal path to an absolute path.
+ if path.isabs(p):
+ return p
+ abs = path.join(normINSTANCE_HOME, p)
+ if path.exists(abs):
+ return abs
+ return path.join(normSOFTWARE_HOME, p)
+
+def minimalpath(p):
+ # Trims INSTANCE_HOME or SOFTWARE_HOME from a path.
+ p = path.abspath(p)
+ abs = normalize(p)
+ l = len(normINSTANCE_HOME)
+ if abs[:l] != normINSTANCE_HOME:
+ l = len(normSOFTWARE_HOME)
+ if abs[:l] != normSOFTWARE_HOME:
+ # Can't minimize.
+ return p
+ p = p[l:]
+ while p[:1] in separators:
+ p = p[1:]
+ return p
if 0:
# Hopefully we can use this.