support for reading .py config files
authorTero Marttila <terom@fixme.fi>
Thu, 04 Feb 2010 19:17:14 +0200
changeset 36 92c55179542a
parent 35 5b6043ce9686
child 37 6fd6a9fdc001
support for reading .py config files
fixbot/config.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/fixbot/config.py	Thu Feb 04 19:17:14 2010 +0200
@@ -0,0 +1,87 @@
+"""
+    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
+
+    def _map_name (self, name) :
+        return name.replace('_', '-')
+
+    def __getitem__ (self, name) :
+        """
+            Map from foo_bar -> foo-bar
+        """
+
+        return self.opts[self._map_name(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
+        name = self._map_name(name)
+
+        if name in self.opts :
+            # normal long opt
+            pass
+
+        else :
+            # fail
+            raise NameError(name)
+        
+        # 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
+