--- /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
+