UserPrefs.py :  » GUI » PmwContribD » PmwContribD-r2_0_2 » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » GUI » PmwContribD 
PmwContribD » PmwContribD r2_0_2 » UserPrefs.py
#!/usr/bin/env python
#
# $Id: UserPrefs.py,v 1.3 2001/11/03 11:05:22 doughellmann Exp $
#
# Copyright 2001 Doug Hellmann.
#
#
#                         All Rights Reserved
#
# Permission to use, copy, modify, and distribute this software and
# its documentation for any purpose and without fee is hereby
# granted, provided that the above copyright notice appear in all
# copies and that both that copyright notice and this permission
# notice appear in supporting documentation, and that the name of Doug
# Hellmann not be used in advertising or publicity pertaining to
# distribution of the software without specific, written prior
# permission.
#
# DOUG HELLMANN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
# NO EVENT SHALL DOUG HELLMANN BE LIABLE FOR ANY SPECIAL, INDIRECT OR
# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
# OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#

"""User preference management.

    The UserPrefs class provides a simple interface for maintaining
    user preference values for user applications.

"""

__rcs_info__ = {
    #
    #  Creation Information
    #
    'module_name'  : '$RCSfile: UserPrefs.py,v $',
    'rcs_id'       : '$Id: UserPrefs.py,v 1.3 2001/11/03 11:05:22 doughellmann Exp $',
    'creator'      : 'Doug Hellmann <doug@hellfly.net>',
    'project'      : 'PmwContribD',
    'created'      : 'Sun, 27-May-2001 18:18:03 EDT',

    #
    #  Current Information
    #
    'author'       : '$Author: doughellmann $',
    'version'      : '$Revision: 1.3 $',
    'date'         : '$Date: 2001/11/03 11:05:22 $',
}

#
# Import system modules
#
import string
import re
import os
import UserDict
import sys
import time
import types
import base64

if sys.platform == 'win32':
    import registry
    
#
# Import Local modules
#


#
# Module
#


class UserPrefs(UserDict.UserDict):
    """A class for managing user preferences.

    Preferences are stored in a platform-specific storage area.  Under
    UNIX, this will be a '~/.<classname>' file.  On the Macintosh, the
    file will be written to the Preferences folder.  On win32 systems,
    the values will be stored in the registry.

    Members:

        allowedValues -- The 'allowedValues' class attribute is a
        dictionary defining the preferences managed.  The keys of the
        dictionary should be the names of the preference values.  The
        values should be tuples of the form (type name, default value,
        comment).  Type name can be any value which appears as a key
        in the converters dictionary (see below).  The default value
        should be of the correct time.  The comment should be a string
        which will help the user make sense of the value when it is
        written out to the storage area.

        storeOnChange -- The 'storeOnChange' instance attribute is a boolean flag
        indicating whether or not all preference values should be
        written to the storage area each time any value is modified.

        converters -- Listed in the class attribute 'converters'
        should be a mapping of a type name to a conversion function.
        The conversion function should take one parameter and should
        attempt to conver that value to the named type.  If the value
        cannot be converted to the specified type, a 'ValueError'
        should be raised to prevent the input value from being stored.
        If the value can be converted, the converted value should be
        returned.

        enumValues -- The 'enumValues' dictionary is keyed on value
        names.  Associated with the name of the value should be a
        sequence of allowed enumeration items.
    
    """

    allowedValues = {}

    order = ()

    depricated = ()

    enumValues = {}

    storeOnChange = 1
    
    REGISTRY='registry'

    def __init__(self):
        #
        # Set up the type converters
        #
        self.storage_converters = {
            'string'  : self.storageConverter_string,
            'password': self.storageConverter_password,
            'text'    : self.storageConverter_text,
            'integer' : self.storageConverter_integer,
            'float'   : self.storageConverter_float,
            'boolean' : self.storageConverter_boolean,
            'enum'    : self.storageConverter_enum,
            'color'   : self.storageConverter_color,
            'font'    : self.storageConverter_font,
            }
        self.read_converters = {
            'string'  : self.readConverter_string,
            'password': self.readConverter_password,
            'text'    : self.readConverter_text,
            'integer' : self.readConverter_integer,
            'float'   : self.readConverter_float,
            'boolean' : self.readConverter_boolean,
            'enum'    : self.readConverter_enum,
            'color'   : self.readConverter_color,
            'font'    : self.readConverter_font,
            }
        
        #
        # Compute and initialize the default values
        #
        defaults = {}
        for av in self.allowedValues.keys():
            defaults[av] = self.allowedValues[av][1]
        UserDict.UserDict.__init__(self, defaults)
        #
        # Read any values from the storage area
        #
        self._prefs_storage_name = self.getPrefsStorageName()
        #
        # Initialize the default values.
        #
        self.initializeDefaults()
        #
        # Get values from storage, if they are there.
        #
        self.readValuesFromStorage()
        #
        # Write values back to storage, in case they were not
        # there.
        #
        self.writeValuesToStorage()
        return

    def keys(self):
        """Returns a sequence of names of the preference values.
        
        We override this so that we can control the order of
        the values in other places, but so that users of
        the class can treat us as a dictionary.
        """
        return self.order

    def getPrefsStorageName(self):
        """Returns the name of the storage for the preferences.

        The location might be a filename or 'self.REGISTRY'.
        """
        plat = sys.platform
        #print 'platform is ', plat
        if plat == 'macintosh':
            return os.path.join( os.environ['PREF_FOLDER'],
                                 self.__class__.__name__ )
        elif plat == 'win32':
            #
            # Build up the base registry key name
            #
            self._registry_key_name = registry.keyNameMake((
              'HKEY_CURRENT_USER',
              'Software',
              'WhackyChat',
              ))
            self._registry_key = None
            return self.REGISTRY
        else:
            return os.path.join( os.environ['HOME'],
                                 '.%s' % self.__class__.__name__ )

    def readValuesFromStorage_File(self):
        try:
            input = open(self._prefs_storage_name, 'rt')
        except IOError:
            # No file, or can't read it.  Do not do
            # anything.
            pass
        else:
            for line in input.readlines():
                line = string.strip(line)
                if not line: continue
                if line[0] == '#': continue
                #parts = map(string.strip, string.split(line, '='))
                try:
                    eq = string.index(line, '=')
                    var = string.strip(line[:eq])
                    val = string.strip(line[eq+1:])
                except ValueError:
                    raise ValueError('Could not parse line "%s" in %s.' \
                                     % (line, self._prefs_storage_name))
                if var in self.depricated:
                    # Report the user of an old configuration value.
                    print 'The use of the configuration value "%s"' % var
                    print 'has been depricated.'
                    print 'The stored value for this parameter will be discarded.'
                    print 
                    continue
                if var not in self.allowedValues.keys():
                    raise ValueError('Unknown preference value found in %s' \
                                     % self._prefs_storage_name, var, val)
                val = self.convert_on_read(var, val)
                self[var] = val
                input.close()
        return
        
    def readValuesFromStorage_Registry(self):
        #print 'readValuesFromStorage_Regitry'
        if not self._registry_key:
            self._registry = registry.Registry()
            self._registry_key = self._registry.openKey(
              self._registry_key_name)
        existing_keys = self._registry_key.subKeyNames()
        for key in existing_keys:
            sub_key_name = registry.keyNameMake( (self._registry_key_name,
                        key))
            sub_key = self._registry.openKey(sub_key_name)
            val, ignore = sub_key.valueQuery()
            #print 'read %s as %s' % (sub_key_name, val)
            val = self.convert_on_read(key, val)
            self[key] = val
        return

    def readValuesFromStorage(self):
        #
        # We are giong to set values based on the
        # storage contents, so we don't want
        # to be writing over the storage every
        # time we read a value from it.  Temporarily
        # set the value to not write, then restore
        # the original value when we're done.
        #
        if self._prefs_storage_name == self.REGISTRY:
            self.readValuesFromStorage_Registry()
        else:
            storeOnChange = self.storeOnChange
            self.storeOnChange = 0
            self.readValuesFromStorage_File()
            self.storeOnChange = storeOnChange
        return

    def writeValuesToStorage_Registry(self, value_names):
        self._registry_key.valueSet('Last updated %s' % time.ctime(time.time()))
        if value_names:
            var_names = value_names
        else:
            var_names = self.keys()
        for key in var_names:
            sub_key_name = registry.keyNameMake( (self._registry_key_name,
                        key))
            sub_key = self._registry.openKey(sub_key_name)
            pref_type, pref_default, pref_comment = self.allowedValues[key]
            try:
                converter = self.storage_converters[pref_type]
                representation = converter(key, self[key])
            except KeyError:
                # No converter, store as a string
                representation = str(self[key])
            #print 'Storing %s as "%s"' % (key, representation) 
            representation = str(representation)  
            sub_key.valueSet(pref_comment, 'Description')
            sub_key.valueSet(representation)
        return

    def writeValuesToStorage_File(self, value_names):
        #print 'writing'
        output = open(self._prefs_storage_name, 'wt')
        output.write('#\n# Last updated: %s\n#\n\n' % time.ctime(time.time()))
        varNames = self.keys()
        for var in varNames:
            prefType, prefDefault, prefComment = self.allowedValues[var]
            prefCommentLines = string.split(prefComment, '\n')
            #prefType, prefDefault, prefComment = self.allowedValues[var]
            try:
                converter = self.storage_converters[prefType]
                #print 'CONVERTING:', self[var]
                representation = converter(var, self[var])
            except KeyError:
                # No converter, store as a string
                representation = str(self[var])
            output.write('#\n')
            for line in prefCommentLines:
                output.write('# %s\n' % line)
            output.write('#\n')
            output.write('%s = %s\n\n' % (var, representation))
            #print '\t%s = %s' % (var, representation)
        output.close()
        return

    def writeValuesToStorage(self, value_names=()):
        if self._prefs_storage_name == self.REGISTRY:
            self.writeValuesToStorage_Registry(value_names)
        else:
            self.writeValuesToStorage_File( () )
        return

    #
    # create a shortcut for storing
    #
    store = writeValuesToStorage

    def convert_on_read(self, item, value):
        try:
            prefType, prefDefault, prefComment = self.allowedValues[item]
        except KeyError:
            # Not a defined preference
            raise ValueError('Unknown preference %s' % item)
        # Force the value to the right type
        converter = self.read_converters[prefType]
        if converter:
            try:
                value = converter(item, value)
            except ValueError, msg:
                raise ValueError('Could not convert "%s" to a %s for %s' \
                                 % (value, prefType, item),
                                 str(msg))
        return value
    
    def __setitem__(self, item, value):
        #print 'Recording %s=%s' % (item, value)
        # Validate the preference name
        #value = self.convert_on_read(item, value)
        UserDict.UserDict.__setitem__(self, item, value)
        if self.storeOnChange:
            self.store( (item,) )
        return

    #
    # Define basic converters
    #
    def storageConverter_integer(self, name, value):
        return int(value)

    def readConverter_integer(self, name, value):
        return int(value)

    def storageConverter_string(self, name, value):
        return str(value)

    def readConverter_string(self, name, value):
        return value

    def storageConverter_password(self, name, value):
        return base64.encodestring(str(value))

    def readConverter_password(self, name, value):
        return base64.decodestring(value)

    def storageConverter_text(self, name, value):
        s = self.storageConverter_string(name, value)
        s = string.replace(s, '\r', ' ')
        s = string.replace(s, '\n', '|')
        return s

    def readConverter_text(self, name, value):
        s = self.readConverter_string(name, value)
        s = string.replace(s, '|', '\n')
        return s

    def storageConverter_color(self, name, value):
        return str(value)

    def readConverter_color(self, name, value):
        return str(value)
    
    def storageConverter_float(self, name, value):
        return float(value)

    def readConverter_float(self, name, value):
        return float(value)

    def valueToBoolean(self, name, value):
        #print 'converting %s:%s' % (name, value)
        if type(value) == types.StringType:
            value = string.lower(value)
            if value in ('yes', 'true'):
                value = 1
            elif value in ('no', 'false'):
                value = 0
            else:
                value = int(value)
        if value:
            bool = 1
        else:
            bool = 0
        #print 'bool = ', bool
        return bool

    def storageConverter_boolean(self, name, value):
        return self.valueToBoolean(name, value)
    
    def readConverter_boolean(self, name, value):
        return self.valueToBoolean(name, value)        

    def valueToEnum(self, name, value):
        #
        # Determine the legal values
        #
        try:
            values = self.enumValues[name]
        except KeyError:
            raise ValueError('No enumerations defined for %s' % name)
        #
        # Determine if the requested value
        # is one of the legal values.
        #
        if value in values:
            return value
        else:
            #
            # Try to convert the value to an index number
            #
            try:
                valueNum = int(value)
            except ValueError:
                raise ValueError('Enum value %s must be one of %s' \
                                 % (value, str(values)))
            try:
                return values[value]
            except IndexError:
                raise ValueError('Enum value %s must be one of %s' \
                                 % (value, str(values)))
        
    def readConverter_enum(self, name, value):
        return self.valueToEnum(name, value)
        
    def storageConverter_enum(self, name, value):
        return self.valueToEnum(name, value)

    def readConverter_font(self, name, value):
        #print 'readConverter_font(%s, %s)' % (name, value)
        readval = eval(value)
        #print '\ttype=', type(readval)
        #print '\tval=', readval
        return readval

    def storageConverter_font(self, name, value):
        #print 'storageConverter_font(%s, %s)' % (name, value)
        if type(value) == type(''):
            #print '\tconverting to sequence'
            seq = eval(value)
        #print '\ttype of value:', type(value)
        storage = str(value)
        #print '\tstorage: ', storage
        return storage

    def initializeDefaults(self):
        """Initialize internal default values.
        
        Initialize our default values as though they were written
        in the storage area.
        """
        storeOnChange = self.storeOnChange
        self.storeOnChange = 0
        for name, valueT in self.allowedValues.items():
            default = valueT[1]
            self[name] = default
        self.storeOnChange = storeOnChange
        return



if __name__ == '__main__':

    class testprefsrc(UserPrefs):
        order = (
            'fonttest',
            'userName',
            'password',
            'userId',
            'timeout',
            'updatetime',
            'exampleenum',
            'colortest',
            'booltest',
            )
        allowedValues = {
            'fonttest'    : ('font', '("Courier",)', 'Font for displaying values'),
            'userName'    : ('string', None, 'The name of the user.'),
            'password'    : ('password', None, 'Your password.'),
            'userId'      : ('integer', 0, 'The id number of the user.'),
            'timeout'     : ('float', 0.0, 'How long to wait?'),
            'updatetime'  : ('string', time.ctime(time.time()),
                             'What time is it?'),
            'exampleenum' : ('enum', 'one', 'Pick one of the enum.'),
            'colortest'   : ('color', 'white', 'Favorite color'),
            'booltest'    : ('boolean', 1, 'Toggle me'),
            }
        enumValues = {
            'exampleenum': ('zero', 'one', 'two', 'three'),
            }

    def testfunc():
        tp = testprefsrc()
        print 'tp=', tp
        tp['userName'] = 'Doug'
        tp['password'] = 'password'
        tp['userId'] = '10'
        tp['timeout'] = 1
        tp['updatetime'] = time.ctime(time.time())
        tp['exampleenum'] = 1
        print 'tp=', tp
        tp['exampleenum'] = 'two'
        print 'tp=', tp
        tp.store()
        for name, value in tp.items():
            print '%s=%s (%s)' % (name, value, type(value))
        return

    testfunc()
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.