############################################################################## # # Copyright (c) 2001 Zope Corporation and Contributors. All Rights # Reserved. # # This software is subject to the provisions of the Zope Public License, # Version 2.1 (ZPL). A copy of the ZPL should accompany this # distribution. # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS # FOR A PARTICULAR PURPOSE. # ############################################################################## """ Represent a group of properties about a user. $Id: UserPropertySheet.py 74709 2007-04-24 16:53:31Z tseaver $ """ from types import IntType from types import FloatType from types import LongType from types import TupleType from types import ListType from types import InstanceType from types import BooleanType try: from types import StringTypes except ImportError: from types import StringType from types import UnicodeType StringTypes = ( StringType, UnicodeType ) _SequenceTypes = ( TupleType, ListType ) from DateTime.DateTime import DateTime from Products.PluggableAuthService.utils import classImplements from Products.PluggableAuthService.interfaces.propertysheets \ import IPropertySheet def _guessSchema( kw ): schema = [] for k, v in kw.items(): ptype = 'string' if type( v ) is IntType: ptype = 'int' elif type( v ) is FloatType: ptype = 'float' elif type( v ) is LongType: ptype = 'long' elif type( v ) is BooleanType: ptype = 'boolean' elif type( v ) in _SequenceTypes: if v and type( v[0] ) not in StringTypes: raise ValueError, 'Property %s: sequence items not strings' % k ptype = 'lines' elif type( v ) is InstanceType: if isinstance( v, DateTime ): ptype = 'date' else: raise ValueError, 'Property %s: unknown class' % k elif type( v ) not in StringTypes: raise ValueError, 'Property %s: unknown type' % k schema.append( ( k, ptype ) ) return schema class UserPropertySheet: """ Model a single, read-only set of properties about a user. o Values for the sheet are passed as keyword args to the c'tor. o The schema for the sheet may be passed into the c'tor explicitly as a sequence of (id, type) tuples; if not passed, the c'tor will guess the schema from the keyword args. """ def __init__( self, id, schema=None, **kw ): self._id = id if schema is None: schema = _guessSchema( kw ) self._schema = tuple( schema ) self._properties = {} for id, ptype in schema: value = kw.get( id ) if ptype == 'lines': if value is not None: value = tuple( value ) self._properties[ id ] = value # # IPropertySheet implementation # def getId( self ): """ See IPropertySheet. """ return self._id def hasProperty( self, id ): """ See IPropertySheet. """ return id in self.propertyIds() def getProperty( self, id, default=None ): """ See IPropertySheet. """ return self._properties.get( id, default ) def getPropertyType( self, id ): """ See IPropertySheet. """ found = [ x[1] for x in self._schema if x[0] == id ] return found and found[0] or None def propertyInfo( self, id ): """ See IPropertySheet. """ for schema_id, ptype in self._schema: if schema_id == id: return { 'id' : id, 'type' : ptype, 'mode' : '' } return None def propertyMap( self ): """ See IPropertySheet. """ result = [] for id, ptype in self._schema: result.append( { 'id' : id, 'type' : ptype, 'mode' : '' } ) return tuple( result ) def propertyIds( self ): """ See IPropertySheet. """ return [ x[0] for x in self._schema ] def propertyValues( self ): """ See IPropertySheet. """ return [ self._properties.get( x ) for x in self.propertyIds() ] def propertyItems( self ): """ See IPropertySheet. """ return [ ( x, self._properties.get( x ) ) for x in self.propertyIds() ] classImplements( UserPropertySheet , IPropertySheet )