Mercurial > p > roundup > code
diff roundup/config.py @ 604:13719594278b config-0-4-0-branch
I've re-worked the config structure a little so it's simpler
(one less file) and added a unit test so we can be sure it's working.
| author | Richard Jones <richard@users.sourceforge.net> |
|---|---|
| date | Wed, 06 Feb 2002 07:11:13 +0000 |
| parents | fdee2ff82b40 |
| children |
line wrap: on
line diff
--- a/roundup/config.py Wed Feb 06 04:29:17 2002 +0000 +++ b/roundup/config.py Wed Feb 06 07:11:13 2002 +0000 @@ -1,7 +1,36 @@ -import sys -import os -import ConfigParser -import string +'''Organise the configuration files for roundup installations. + +There's two configuration files of interest to any given roundup instance: + +roundup.rc: + This is the global configuration file. It specifies: + . default configuration variable values + . instance names and locations + +<instance home>/config.rc: + This defines the configuration overrides for the instance + +Config values are determined in order: + 1. instance config application-specific section: + 'MAIL GATEWAY' + 'HTTP SERVER' + 'CGI' + 'ADMIN' + 2. instance config 'DEFAULT' with some added vars: + 'instance_home': the home dir + 3. all the entries from the roundup.rc global '[DEFAULT]' + 4. pre-set application defaults (in this file) + +Some variables will raise errors if an attempt is made to look them up +using the application defaults: + . mailhost + . mail_domain + . issue_tracker_email + . issue_tracker_web + . admin_email + +''' +import sys, os, ConfigParser class Error(Exception): pass @@ -13,38 +42,31 @@ pass def debug_mode(): - """ - Returns the basic debug mode/level. + """Returns the basic debug mode/level. """ return os.environ.get('ROUNDUP_DEBUG', 0) def loadBaseConfig(): - """ - Loads the base configuration for Roundup. + """Loads the base configuration for Roundup. """ - c = ConfigParser.ConfigParser() - ## - ## CTB: this is where to search for all overrides, including - ## system-specific files, registry settings, etc. - ## - + # CTB: this is where to search for all overrides, including + # system-specific files, registry settings, etc. + # # For the moment, search for the config file in # + # ${ROUNDUP_CONF}/roundup.rc # %(sys.prefix)s/share/roundup/roundup.rc, - # - # with ROUNDUP_CONF overriding it. - + # filenames_to_check = [] # list of files to check: if os.environ.has_key('ROUNDUP_CONF'): filenames_to_check.append(os.environ['ROUNDUP_CONF']) - - filenames_to_check.append('%s/share/roundup/roundup.rc'%(sys.prefix,)) + filenames_to_check.append('%s/share/roundup/roundup.rc'%sys.prefix) + # right, now try to get a config for filename in filenames_to_check: if os.path.exists(filename): - c.read(filename) break else: raise Error("could not find configuration file") @@ -52,123 +74,87 @@ if debug_mode(): print 'Loaded configuration from "%s".'%(filename,) - # we also want to give a base path for other config file names; - # for the moment, make it the base path of the filename we chose. - base_path = os.path.dirname(filename) - - return BaseConfig(c, base_path) + return BaseConfig(filename) class BaseConfig: - """ - A container for the installation-wide roundup configuration. + """A container for the installation-wide roundup configuration. """ - def __init__(self, c, base_path): - assert isinstance(c, ConfigParser.ConfigParser) - self.conf = c - self.base_path = base_path + def __init__(self, filename): + self.filename = filename + self.conf = ConfigParser.ConfigParser() + self.conf.read(filename) def get(self, group, attr): return self.conf.get(group, attr) - def loadInstances(self): - filename = string.strip(self.conf.get('base', 'instances')) - - # if it looks like an absolute path, leave it alone; otherwise, - # add on the base path. - if filename[0] == '/' or filename[0] == '\\': - pass - else: - filename = os.path.normpath(self.base_path + '/' + filename) - - defaults_dictionary = { 'roundup_conf_dir' : self.base_path } - - c = ConfigParser.ConfigParser(defaults_dictionary) - c.read(filename) - - return InstancesConfig(c, filename) - -class InstancesConfig: - """ - A container for the installation-wide list of instances. - """ - def __init__(self, c, filename=""): - assert isinstance(c, ConfigParser.ConfigParser) - self.conf = c - self.filename = filename - - instance_names = {} - instance_dirs = {} - - for name in c.sections(): - dir = c.get(name, 'homedir') + def listInstances(self): + return filter(lambda x:x!='BASE', self.conf.sections()) - if instance_names.has_key(dir) or instance_dirs.has_key(name): - error_text = 'ERROR: dir/name correspondence is not unique (%s)'%(self.filename,) - raise ValueError(error_text) - - instance_dirs[name] = dir - instance_names[dir] = name - - self.instance_dirs = instance_dirs - self.instance_names = instance_names - - def getNames(self): - return self.instance_dirs.keys() - - def getNameFromDir(self, dir): - if self.instance_names.has_key(dir): - return self.instance_names[dir] - else: - raise UnknownInstanceLocation(dir) - - def getDirFromName(self, name): - return self.instance_dirs[name] - - def loadConfig(self, name): - instance_dir = self.getDirFromName(name) + def loadInstanceConfig(self, home): + # set up the defaults for the instance config + defaults = { + 'instance_home': home, + 'http_port': '80', + 'database': '%(instance_home)s/db', + 'templates': '%(instance_home)s/html', + 'log': '%(instance_home)s/log', + 'filter_position': 'bottom', + 'anonymous_access': 'deny', + 'anonymous_register': 'deny', + 'messages_to_author': 'no', + 'email_signature_position': 'bottom', + } + for option in self.conf.options('BASE'): + defaults[option] = self.conf.get('BASE', option, 1) - defaults_file = self.conf.get(name, 'defaults') - if not os.path.exists(defaults_file): - raise NoInstanceConfigFile("defaults file %s does not exist"%(defaults_file,)) - - config_file = self.conf.get(name, 'config') - if not os.path.exists(config_file): - raise NoInstanceConfigFile("%s does not exist"%(config_file,)) - - defaults_dictionary = { 'homedir' : instance_dir, - 'instance_name' : name, - } + # make the instance config + inst = InstanceConfig(defaults) + inst.read(os.path.join(home, 'config.rc')) + inst.validate() + return inst - c = ConfigParser.ConfigParser(defaults_dictionary) - c.read(defaults_file) - c.read(config_file) - - return InstanceConfig(c, name, instance_dir) - -class InstanceConfig: - """ - A container for each per-instance configuration. +class InstanceConfig(ConfigParser.ConfigParser): + """A container for each per-instance configuration. """ - - def __init__(self, c, instanceName, instanceDirectory): - assert isinstance(c, ConfigParser.ConfigParser) - self.conf = c - self.name = instanceName - self.directory = instanceDirectory + def validate(self): + '''Make sure the config is complete + ''' + assert self.has_option('BASE', 'instance_name') + assert self.has_option('BASE', 'mailhost') + assert self.has_option('BASE', 'mail_domain') + assert self.has_option('BASE', 'issue_tracker_email') + assert self.has_option('BASE', 'issue_tracker_web') + assert self.has_option('BASE', 'admin_email') - def get_name(self): - return self.name + def getBase(self, name): + '''Convenience wrapper + ''' + return self.get('BASE', name) + + def getMailGW(self, name): + '''Look up a var for the mail gateway + ''' + return self.get('MAIL GATEWAY', name) - def get_directory(self): - return self.directory + def getHTTPServer(self, name): + '''Look up a var for the standalone HTTP server + ''' + return self.get('HTTP SERVER', name) + + def getCGI(self, name): + '''Look up a var for the cgi script + ''' + return self.get('CGI', name) - def get(self, group, attr): - return self.conf.get(group, attr) - -if __name__ == '__main__': - base_config = loadBaseConfig() - instances = base_config.loadInstances() - - for k in instances.getNames(): - print "%s:%s"%(k, instances.getDirFromName(k),) + def getAdmin(self, name): + '''Look up a var for the admin script + ''' + return self.get('ADMIN', name) + + def get_default_database_dir(self): + '''Historical method to allow migration to using this new config + system... + ''' + return self.get('BASE', 'DATABASE') +
