File: __init__.py

package info (click to toggle)
python-application 1.0.9-4
  • links: PTS, VCS
  • area: main
  • in suites: lenny
  • size: 156 kB
  • ctags: 187
  • sloc: python: 843; makefile: 6
file content (96 lines) | stat: -rw-r--r-- 3,353 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# Copyright (C) 2006-2007 Dan Pascu. See LICENSE for details.
#

"""Application configuration file handling"""

__all__ = ['ConfigSection', 'ConfigFile', 'dump_settings', 'datatypes']

import os
try:    from ConfigParser import SafeConfigParser as ConfigParser
except: from ConfigParser import ConfigParser
from ConfigParser import NoSectionError

from application import log
from application.process import process
from application.configuration import datatypes


class ConfigSection:
    """Defines a section in the configuration file"""
    _datatypes = {}


class ConfigFile(object):
    """Provide access to a configuration file"""
    
    instances = {}
    log_context = {'system': 'configuration'}
    
    def __new__(cls, filename):
        if not cls.instances.has_key(filename):
            instance = object.__new__(cls)
            instance.parser = ConfigParser()
            files = [os.path.join(path, filename) for path in process.get_config_directories() if path is not None]
            instance.parser.read(files)
            cls.instances[filename] = instance
        return cls.instances[filename]
    
    def read_settings(self, section, cls):
        """Update cls's attributes with values read from the given section"""
        if not issubclass(cls, ConfigSection):
            raise TypeError("cls must be a subclass of ConfigSection")
        if section not in self.parser.sections():
            return
        for prop in dir(cls):
            if prop[0]=='_':
                continue
            ptype = cls._datatypes.get(prop, eval('cls.%s.__class__' % prop))
            try:
                val = self.parser.get(section, prop)
            except:
                continue
            else:
                try:
                    if ptype is bool:
                        value = bool(datatypes.Boolean(val))
                    else:
                        value = ptype(val)
                except Exception, why:
                    msg = "ignoring invalid config value: %s.%s=%s (%s)." % (section, prop, val, why)
                    log.warn(msg, **ConfigFile.log_context)
                else:
                    setattr(cls, prop, value)
    
    def get_option(self, section, option, default='', type=str):
        """Get an option from a given section using type, or default if not found"""
        try:
            value = self.parser.get(section, option)
        except:
            return default
        else:
            try:
                if type is bool:
                    return bool(datatypes.Boolean(value))
                else:
                    return type(value)
            except Exception, why:
                msg = "ignoring invalid config value: %s.%s=%s (%s)." % (section, option, value, why)
                log.warn(msg, **ConfigFile.log_context)
                return default
    
    def get_section(self, section):
        """Return a list of tuples with name, value pairs from the section or None if section doesn't exist"""
        try:
            return self.parser.items(section)
        except NoSectionError:
            return None


def dump_settings(cls):
    """Print a ConfigSection class attributes"""
    print '%s:' % cls.__name__
    for x in dir(cls):
        if x[0] == '_': continue
        print '  %s: %s' % (x, eval('cls.%s' % x))
    print ''