fixbot/config.py
author Tero Marttila <terom@fixme.fi>
Fri, 05 Feb 2010 21:48:14 +0200
changeset 58 31a17b0b5159
parent 38 66a42168c80b
permissions -rw-r--r--
remove concept of event_types, the event.type is now just sent as a string
"""
    Support for loading config files with twisted.python.usage
"""

from twisted.python import usage

import traceback

class ConfigMapper (dict) :
    """
        Provides access to a usage.Options's keys via python names.
    """

    IGNORED_NAMES = ('__doc__', )

    def __init__ (self, opts, defaults=None) :
        """
            opts        - store the values from the config file into the given dict
            defaults    - (optional) update any pre-exisitng values from the config file into the given dict
        """

        self.opts = opts
        self.defaults = defaults

        # temp. vars
        self.locals = {}

    def optname (self, name) :
        return name.replace('_', '-')

    def __getitem__ (self, name) :
        """
            Map from foo_bar -> foo-bar
        """

        # translate
        optname = self.optname(name)
        
        if optname in self.opts :
            # normal long opt
            return self.opts[optname]

        elif name in self.locals :
            # temp local
            return self.locals[name]

        else :
            # unknown
            raise NameError(name)

    def __setitem__ (self, name, value) :
        """
            Map from foo_bar -> foo-bar
        """
        
        store = self.opts
        
        # filter out certain keys
        if name in self.IGNORED_NAMES :
            # skip things like __doc__
            return
        
        # translate name
        optname = self.optname(name)

        if optname in self.opts :
            # normal long opt
            name = optname

        else :
            # store as a local
            store = self.locals
        
        # store
        store[name] = value

        if self.defaults is not None and name in self.defaults :
            self.defaults[name] = value

class ConfigOptions (usage.Options) :
    """
        Provide a --config param to read in new values/defaults for any defined options from the given config file
    """

    def opt_config (self, path) :
        """
            Read the given configuration file
        """

        # set up env for the config module
        globals = {}
        locals = ConfigMapper(self.opts, self.defaults)
        
        try :
            # run config
            execfile(path, globals, locals)

        except :
            # XXX: raising a usage.error prints out --help
            raise usage.error("Error reading config file: %s\n%s" % (path, traceback.format_exc()))
    
    opt_c = opt_config