[CMF-checkins] CVS: CMF/CMFCore - FSMetadata.py:1.1 DirectoryView.py:1.36
Florent Guillaume
fg@nuxeo.com
Fri, 14 Mar 2003 15:18:37 +0100
Hi,
This is a nice feature, but
- the tests are failing,
- there should be documentation about the goal of this in the module or
class docstring, and also in CHANGES.txt.
Cheers,
Florent
In article <200303120507.h2C576E20431@cvs.baymountain.com> you write:
> Update of /cvs-repository/CMF/CMFCore
> In directory cvs.zope.org:/tmp/cvs-serv19816
>
> Modified Files:
> DirectoryView.py
> Added Files:
> FSMetadata.py
> Log Message:
> Add new .metadata file which combines previous formats into a ConfigParser
> type format. Proxy role stuff to come
>
>
> === Added File CMF/CMFCore/FSMetadata.py ===
> """ Handles reading the properties for an object that comes from the filesystem.
>
> $Id: FSMetadata.py,v 1.1 2003/03/12 05:06:28 andym Exp $
> """
>
> from zLOG import LOG, ERROR
> from sys import exc_info
> from os.path import exists
> from ConfigParser import ConfigParser
>
> import re
>
> class CMFConfigParser(ConfigParser):
> """ This our wrapper around ConfigParser to
> solve a few minor niggles with the code """
> # adding in a space so that names can contain spaces
> OPTCRE = re.compile(
> r'(?P<option>[]\-[ \w_.*,(){}]+)' # a lot of stuff found by IvL
> r'[ \t]*(?P<vi>[:=])[ \t]*' # any number of space/tab,
> # followed by separator
> # (either : or =), followed
> # by any # space/tab
> r'(?P<value>.*)$' # everything up to eol
> )
>
> def optionxform(self, optionstr):
> """
> Stop converting the key to lower case, very annoying for security etc
> """
> return optionstr.strip()
>
> class FSMetadata:
> # public API
> def __init__(self, filename):
> self._filename = filename
>
> def read(self):
> """ Find the files to read, either the old security and properties
> type or
> the new metadata type """
> filename = self._filename + '.metadata'
> if exists(filename):
> # found the new type, lets use that
> self._readMetadata()
> else:
> # not found so try the old ones
> self._properties = self._old_readProperties()
> self._security = self._old_readSecurity()
>
> def getSecurity(self):
> """ Gets the security settings """
> return self._security
>
> def getProperties(self):
> """ Gets the properties settings """
> return self._properties
>
> # private API
> def _readMetadata(self):
> """ Read the new file format using ConfigParser """
> cfg = CMFConfigParser()
> cfg.read(self._filename + '.metadata')
>
> # the two sections we care about
> self._properties = self._getSectionDict(cfg, 'default')
> self._security = self._getSectionDict(cfg, 'security',
> self._securityParser)
> # to add in a new value such as proxy roles,
> # just add in the section, call it using getSectionDict
> # if you need a special parser for some whacky
> # config, then just pass through a special parser
>
> def _nullParser(self, data):
> """
> This is the standard rather boring null parser that does very little
> """
> return data
>
> def _securityParser(self, data):
> """ A specific parser for security lines
>
> Security lines must be of the format
>
> (0|1):Role[,Role...]
>
> Where 0|1 is the acquire permission setting
> and Role is the roles for this permission
> eg: 1:Manager or 0:Manager,Anonymous
> """
> if data.find(':') < 1:
> raise ValueError, "The security declaration is in the wrong format"
>
> acquire, roles = data.split(':')
> roles = [r.strip() for r in roles.split(',') if r.strip()]
> return (acquire, roles)
>
> def _getSectionDict(self, cfg, section, parser=None):
> """
> Get a section and put it into a dict, mostly a convenience
> function around the ConfigParser
>
> Note: the parser is a function to parse each value, so you can
> have custom values for the key value pairs
> """
> if parser is None:
> parser = self._nullParser
>
> props = {}
> if cfg.has_section(section):
> for opt in cfg.options(section):
> props[opt] = parser(cfg.get(section, opt))
> return props
>
> # we need to return None if we have none to be compatible
> # with existing API
> return None
>
> def _old_readProperties(self):
> """
> Reads the properties file next to an object.
>
> Moved from DirectoryView.py to here with only minor
> modifications. Old and deprecated in favour of .metadata now
> """
> fp = self._filename + '.properties'
> try:
> f = open(fp, 'rt')
> except IOError:
> return None
> else:
> lines = f.readlines()
> f.close()
> props = {}
> for line in lines:
> try: key, value = split(line, '=',1)
> except: pass
> else:
> props[strip(key)] = strip(value)
> return props
>
> def _old_readSecurity(self):
> """
> Reads the security file next to an object.
>
> Moved from DirectoryView.py to here with only minor
> modifications. Old and deprecated in favour of .metadata now
> """
> fp = self._filename + '.security'
> try:
> f = open(fp, 'rt')
> except IOError:
> return None
> else:
> lines = f.readlines()
> f.close()
> prm = {}
> for line in lines:
> try:
> c1 = line.index(':')+1
> c2 = line.index(':',c1)
> permission = line[:c1-1]
> acquire = not not line[c1:c2] # get boolean
>
> proles = line[c2+1:].split(',')
> roles=[]
> for role in proles:
> role = role.strip()
> if role:
> roles.append(role)
> except:
> LOG('DirectoryView',
> ERROR,
> 'Error reading permission from .security file',
> error=exc_info())
> # warning use of exc_info is deprecated
> prm[permission]=(acquire,roles)
> return prm
>
>
> === CMF/CMFCore/DirectoryView.py 1.35 => 1.36 ===
> --- CMF/CMFCore/DirectoryView.py:1.35 Thu Jan 23 09:31:12 2003
> +++ CMF/CMFCore/DirectoryView.py Wed Mar 12 00:06:28 2003
> @@ -32,6 +32,7 @@
> from zLOG import LOG, ERROR
> from sys import exc_info
> from types import StringType
> +from FSMetadata import FSMetadata
>
> _dtmldir = path.join( package_home( globals() ), 'dtml' )
>
> @@ -99,56 +100,6 @@
> types[strip(obname)] = strip(meta_type)
> return types
>
> -
> - def _readProperties(self, fp):
> - """Reads the properties file next to an object.
> - """
> - try:
> - f = open(fp, 'rt')
> - except IOError:
> - return None
> - else:
> - lines = f.readlines()
> - f.close()
> - props = {}
> - for line in lines:
> - try: key, value = split(line, '=',1)
> - except: pass
> - else:
> - props[strip(key)] = strip(value)
> - return props
> -
> - def _readSecurity(self, fp):
> - """Reads the security file next to an object.
> - """
> - try:
> - f = open(fp, 'rt')
> - except IOError:
> - return None
> - else:
> - lines = f.readlines()
> - f.close()
> - prm = {}
> - for line in lines:
> - try:
> - c1 = line.index(':')+1
> - c2 = line.index(':',c1)
> - permission = line[:c1-1]
> - acquire = not not line[c1:c2] # get boolean
>
> - proles = line[c2+1:].split(',')
> - roles=[]
> - for role in proles:
> - role = role.strip()
> - if role:
> - roles.append(role)
> - except:
> - LOG('DirectoryView',
> - ERROR,
> - 'Error reading permission from .security file',
> - error=exc_info())
> - prm[permission]=(acquire,roles)
> - return prm
> -
> if Globals.DevelopmentMode:
>
> def _changed(self):
> @@ -253,11 +204,11 @@
> t = registry.getTypeByExtension(ext)
>
> if t is not None:
> - properties = self._readProperties(
> - e_fp + '.properties')
> + metadata = FSMetadata(e_fp)
> + metadata.read()
> try:
> ob = t(name, e_filepath, fullname=entry,
> - properties=properties)
> + properties=metadata.getProperties())
> except:
> import traceback
> typ, val, tb = exc_info()
> @@ -278,7 +229,7 @@
>
> # FS-based security
> try:
> - permissions = self._readSecurity(e_fp + '.security')
> + permissions = metadata.getSecurity()
> if permissions is not None:
> for name in permissions.keys():
> acquire,roles = permissions[name]
>
>
> _______________________________________________
> CMF-checkins mailing list
> CMF-checkins@zope.org
> http://mail.zope.org/mailman/listinfo/cmf-checkins
>
--
Florent Guillaume, Nuxeo (Paris, France)
+33 1 40 33 79 87 http://nuxeo.com mailto:fg@nuxeo.com