#!/usr/bin/env python """Generic INI-style configuration file handling. Just import this module to have access to a default config file. Theory of operation: Upon importing this module a basic config file will be parsed. The module will look for the config file in the following standard places: 1) command line (getopt style): --conf-file= 2) ~/./.conf 3) ~/..conf 4) /etc//.conf 5) /etc/.conf 6) ./.conf - last resort for DOS/Win It is helpful to have a solid log target set up before importing this module in your code. This way you will be able to even see those log messages generated during module import. For sample code see bottom of file. @copyright: GPL """ #--------------------------------------------------------------- import os.path, getopt, sys, ConfigParser import gmLog __version__ = "$Revision: 1.0 $" __author__ = "Karsten Hilbert " __log__ = gmLog.gmDefLog #--------------------------------------------------------------- def read_conf_file(aDir = None, aName = None): """Load and parse config file from standard locations.""" cmd_line = '' # long options only ! try: cmd_line = getopt.getopt(sys.argv[1:], '', ['conf-file=',]) except getopt.GetoptError: __log__.Log(gmLog.lErr, "No config file given on command line (%s). Format: --conf-file=" % str(sys.argv)) exc = sys.exc_info() __log__.LogException("non-fatal exception", exc) # config file given on command line ? __log__.Log(gmLog.lData, "getopt parsed command line: %s" % str(cmd_line)) # 1) tuple(cmd_line) -> (known options, junk) known_opts = cmd_line[0] if len(known_opts) > 0: # 2) sequence(known_opt) -> (opt 1, opt 2, ..., opt n) first_opt = known_opts[0] # 3) tuple(first_opt) -> (option name, option value) cfgName = first_opt[1] # file missing ? if not os.path.exists(cfgName): __log__.Log(gmLog.lPanic, "config file %s (given on command line) not found. Aborting." % cfgName) return None # else look in standard locations else: __log__.Log(gmLog.lWarn, "No config file given on command line.") if aName == None: # get base name from name of script base_name = os.path.splitext(os.path.basename(sys.argv[0]))[0] + ".conf" else: base_name = aName if aDir == None: # get base dir from name of script base_dir = os.path.splitext(os.path.basename(sys.argv[0]))[0] else: base_dir = aDir # ~/.base_dir/base_name cfgName = os.path.expanduser(os.path.join('~', '.' + base_dir, base_name)) # not there if not os.path.exists(cfgName): __log__.Log(gmLog.lWarn, "config file %s not found." % cfgName) # ~/.base_name cfgName = os.path.expanduser(os.path.join('~', '.' + base_name)) # not there if not os.path.exists(cfgName): __log__.Log(gmLog.lWarn, "config file %s not found." % cfgName) # /etc/base_dir/base_name cfgName = os.path.join('/etc', base_dir, base_name) # not there if not os.path.exists(cfgName): __log__.Log(gmLog.lWarn, "config file %s not found." % cfgName) # /etc/base_name cfgName = os.path.join('/etc', base_name) # not there if not os.path.exists(cfgName): __log__.Log(gmLog.lWarn, "config file %s not found." % cfgName) # ./base_name # last resort for inferior operating systems such as DOS/Windows cfgName = os.path.abspath(os.path.join(os.path.split(sys.argv[0])[0], base_name)) if not os.path.exists(cfgName): __log__.Log(gmLog.lWarn, "config file %s not found." % cfgName) __log__.Log(gmLog.lPanic, "Cannot run without any configuration file. Aborting.") return None # if we got here we have a valid file name __log__.Log(gmLog.lInfo, "config file: " + cfgName) aCfg = ConfigParser.ConfigParser() aCfg.read(cfgName) return aCfg #--------------------------------------------------------------- # MAIN #--------------------------------------------------------------- if __name__ == "__main__": print "Testing gmCfg" print "=============" # make a _real_ log target loghandle = gmLog.cLogTargetFile (gmLog.lData, 'XX-log-test_cfg.log', "a") # and tell the default logger to also use that __log__.AddTarget(loghandle) gmDefCfg = read_conf_file() else: gmDefCfg = read_conf_file() #--------------------------------------------------------------- # TODO #--------------------------------------------------------------- # - transparently handle database access # - ACAP #--------------------------------------------------------------- # sample code #--------------------------------------------------------------- # - in your main module you should set up a log target first (although # things will work fine without) # - then do this: """ import gmCfg __cfg__ = gmCfg.gmDefCfg """ # just by importing gmCfg will set up a basic default config file # __cfg__ is just a convenient handle and could have any other name