Package turbogears :: Module config

Source Code for Module turbogears.config

  1  import os, glob, re 
  2   
  3  from cherrypy import config 
  4  from configobj import ConfigObj 
  5  import pkg_resources 
  6  import logging 
  7  import logging.handlers 
  8   
  9  __all__ = ["update_config", "get", "update"] 
 10   
 11  try: 
 12      set 
 13  except NameError: # Python 2.3 
 14      from sets import Set as set 
 15   
16 -class ConfigError(Exception):
17 pass
18
19 -def _get_formatters(formatters):
20 for key, formatter in formatters.items(): 21 kw = {} 22 fmt = formatter.get("format", None) 23 if fmt: 24 fmt = fmt.replace("*(", "%(") 25 kw["fmt"] = fmt 26 datefmt = formatter.get("datefmt", None) 27 if datefmt: 28 kw["datefmt"] = datefmt 29 formatter = logging.Formatter(**kw) 30 formatters[key] = formatter
31
32 -def _get_handlers(handlers, formatters):
33 for key, handler in handlers.items(): 34 kw = {} 35 try: 36 cls = handler.get("class") 37 args = handler.get("args", tuple()) 38 level = handler.get("level", None) 39 try: 40 cls = eval(cls, logging.__dict__) 41 except NameError: 42 try: 43 cls = eval(cls, logging.handlers.__dict__) 44 except NameError, err: 45 raise ConfigError("Specified class in handler " 46 "%s is not a recognizable logger name" % key) 47 try: 48 handler_obj = cls(*eval(args, logging.__dict__)) 49 except IOError,err: 50 raise ConfigError("Missing or wrong argument to " 51 "%s in handler %s -> %s " % (cls.__name__,key,err)) 52 except TypeError,err: 53 raise ConfigError("Wrong format for arguments " 54 "to %s in handler %s -> %s" % (cls.__name__,key,err)) 55 if level: 56 level = eval(level, logging.__dict__) 57 handler_obj.setLevel(level) 58 except KeyError: 59 raise ConfigError("No class specified for logging " 60 "handler %s" % key) 61 formatter = handler.get("formatter", None) 62 if formatter: 63 try: 64 formatter = formatters[formatter] 65 except KeyError: 66 raise ConfigError("Handler %s references unknown " 67 "formatter %s" % (key, formatter)) 68 handler_obj.setFormatter(formatter) 69 handlers[key] = handler_obj
70
71 -def _get_loggers(loggers, handlers):
72 for key, logger in loggers.items(): 73 qualname = logger.get("qualname", None) 74 if qualname: 75 log = logging.getLogger(qualname) 76 else: 77 log = logging.getLogger() 78 79 level = logger.get("level", None) 80 if level: 81 level = eval(level, logging.__dict__) 82 else: 83 level = logging.NOTSET 84 log.setLevel(level) 85 86 propagate = logger.get("propagate", None) 87 if propagate is not None: 88 log.propagate = propagate 89 90 cfghandlers = logger.get("handlers", None) 91 if cfghandlers: 92 if isinstance(cfghandlers, basestring): 93 cfghandlers = [cfghandlers] 94 for handler in cfghandlers: 95 try: 96 handler = handlers[handler] 97 except KeyError: 98 raise ConfigError("Logger %s references unknown " 99 "handler %s" % (key, handler)) 100 log.addHandler(handler)
101
102 -def configure_loggers(config):
103 """Configures the Python logging module, using options that are very 104 similar to the ones listed in the Python documentation. This also 105 removes the logging configuration from the configuration dictionary 106 because CherryPy doesn't like it there. Here are some of the Python 107 examples converted to the format used here: 108 109 [logging] 110 [[loggers]] 111 [[[parser]]] 112 [logger_parser] 113 level="DEBUG" 114 handlers="hand01" 115 propagate=1 116 qualname="compiler.parser" 117 118 [[handlers]] 119 [[[hand01]]] 120 class="StreamHandler" 121 level="NOTSET" 122 formatter="form01" 123 args="(sys.stdout,)" 124 125 [[formatters]] 126 [[[form01]]] 127 format="F1 *(asctime)s *(levelname)s *(message)s" 128 datefmt= 129 130 131 One notable format difference is that *() is used in the formatter 132 instead of %() because %() is already used for config file 133 interpolation. 134 """ 135 if not config.has_key("logging"): 136 config["global"]["tg.new_style_logging"] = False 137 return 138 logcfg = config["logging"] 139 formatters = logcfg.get("formatters", {}) 140 _get_formatters(formatters) 141 142 handlers = logcfg.get("handlers", {}) 143 _get_handlers(handlers, formatters) 144 145 loggers = logcfg.get("loggers", {}) 146 _get_loggers(loggers, handlers) 147 148 del config["logging"] 149 config["global"]["tg.new_style_logging"] = True
150
151 -def config_defaults():
152 current_dir_uri = os.path.abspath(os.getcwd()) 153 if not current_dir_uri.startswith('/'): 154 current_dir_uri = '/' + current_dir_uri 155 defaults = {'current_dir_uri' : current_dir_uri} 156 return defaults
157
158 -def config_obj(configfile = None, modulename = None):
159 defaults = config_defaults() 160 161 if modulename: 162 lastdot = modulename.rfind('.') 163 firstdot = modulename.find('.') 164 packagename = modulename[:lastdot] 165 top_level_package = modulename[:firstdot] 166 modname = modulename[lastdot+1:] 167 modfile = pkg_resources.resource_filename(packagename, 168 modname + '.cfg') 169 if not os.path.exists(modfile): 170 modfile = pkg_resources.resource_filename(packagename, 171 modname) 172 if os.path.isdir(modfile): 173 configfiles = glob.glob(os.path.join(modfile, '*.cfg')) 174 else: 175 configfiles = [modfile] 176 configdata = ConfigObj(unrepr=True) 177 top_level_dir = os.path.normpath(pkg_resources.resource_filename( 178 top_level_package, '')) 179 180 package_dir = os.path.normpath(pkg_resources.resource_filename( 181 packagename, '')) 182 183 defaults.update(dict(top_level_dir=top_level_dir, 184 package_dir=package_dir)) 185 configdata.merge(dict(DEFAULT=defaults)) 186 for file in configfiles: 187 configdata2 = ConfigObj(file, unrepr=True) 188 configdata2.merge(dict(DEFAULT=defaults)) 189 configdata.merge(configdata2) 190 191 if configfile: 192 if modulename: 193 configdata2 = ConfigObj(configfile, unrepr=True) 194 configdata2.merge(dict(DEFAULT=defaults)) 195 configdata.merge(configdata2) 196 else: 197 configdata = ConfigObj(configfile, unrepr=True) 198 return configdata
199
200 -def update_config(configfile=None, modulename=None):
201 """Updates the system configuration either from a ConfigObj 202 (INI-style) config file, a module name specified in dotted notation 203 or both (the module name is assumed to have a ".cfg" extension). 204 If both are specified, the module is called first, 205 followed by the config file. This means that the config file's options 206 override the options in the module file.""" 207 configdict = config_obj(configfile, modulename).dict() 208 configure_loggers(configdict) 209 config.update(configdict)
210
211 -def get(key, default_value=None, return_section=False, path=None):
212 """Retrieves a config value""" 213 value = config.get(key, default_value, return_section, path) 214 if value and key == 'sqlobject.dburi' and os.name == 'nt': 215 value = re.sub('///(\w):', '///\\1|', value) 216 return value
217
218 -def update(configvalues):
219 """Updates the configuration with the values from the dictionary.""" 220 return config.update(configvalues)
221