Package elisa :: Package core :: Module config
[hide private]
[frames] | no frames]

Source Code for Module elisa.core.config

  1  # -*- coding: utf-8 -*- 
  2  # Elisa - Home multimedia server 
  3  # Copyright (C) 2006-2008 Fluendo Embedded S.L. (www.fluendo.com). 
  4  # All rights reserved. 
  5  # 
  6  # This file is available under one of two license agreements. 
  7  # 
  8  # This file is licensed under the GPL version 3. 
  9  # See "LICENSE.GPL" in the root of this distribution including a special 
 10  # exception to use Elisa with Fluendo's plugins. 
 11  # 
 12  # The GPL part of Elisa is also available under a commercial licensing 
 13  # agreement from Fluendo. 
 14  # See "LICENSE.Elisa" in the root directory of this distribution package 
 15  # for details on that license. 
 16   
 17  """ 
 18  Config management module 
 19  """ 
 20   
 21   
 22  __maintainer__ = 'Philippe Normand <philippe@fluendo.com>' 
 23   
 24   
 25  from elisa.extern.configobj import ConfigObj, Section 
 26  from elisa.core import log 
 27   
 28  import os 
 29  import textwrap 
 30  import tempfile 
 31   
32 -class ConfigError(Exception):
33
34 - def __init__(self, msg):
35 Exception.__init__(self) 36 self.msg = msg
37
38 - def __str__(self):
39 return self.msg
40
41 -class Config(log.Loggable):
42 """ Configuration system 43 44 Each configuration is stored in a text file. The configuration is 45 structured in sections. Each section stores a set of options. Example:: 46 47 [section_name] 48 some_list = ['some','list'] 49 some_string = 'foobar' 50 some_int = 1 51 52 """ 53
54 - def __init__(self, config_file=None, default_config=""):
55 """ Load a config stored in the given file for the given application. 56 57 @param config_file: the config filename to read 58 @type config_file: string or None. None implies to use 59 CONFIG_DIR/CONFIG_FILE 60 @raise ConfigError: when the config file contains format error 61 """ 62 log.Loggable.__init__(self) 63 self.first_load = False 64 65 config_dir = None 66 67 if config_file is not None: 68 69 if not os.path.exists(config_file) or not open(config_file).read(): 70 config_file = self._create_config(config_file, default_config) 71 72 config_dir = os.path.dirname(config_file) 73 if not config_dir: 74 config_dir = os.getcwd() 75 76 self._filename = config_file 77 self._config_dir = config_dir 78 79 self.info("Using %r config file", config_file) 80 try: 81 self._config = ConfigObj(config_file, unrepr=True) 82 except Exception,ex: 83 errors = [ error.msg for error in ex.errors ] 84 errors = ';'.join(errors) 85 raise ConfigError("Config format error in %s: %s" % (config_file, 86 errors))
87
88 - def get_config_dir(self):
89 """ Config directory name accessor 90 91 @returns: the current config directory absolute path 92 @rtype: string 93 """ 94 return self._config_dir
95
96 - def get_filename(self):
97 """ Config filename accessor 98 99 @returns: the config filename from which the config has been read 100 @rtype: string 101 """ 102 return self._filename
103
104 - def set_filename(self, filename):
105 """ Config filename setter 106 107 Updates _config_dir and _filename private attributes 108 109 @param filename: full path to the config file 110 @type filename: string 111 """ 112 self._config.filename = filename 113 self._config_dir = os.path.dirname(filename) 114 self._filename = filename
115
116 - def _create_config(self, config_file, default_config):
117 self.debug("Creating config %r", config_file) 118 119 dirname = os.path.dirname(config_file) 120 if dirname and not os.path.exists(dirname): 121 try: 122 os.makedirs(dirname) 123 except OSError, error: 124 self.warning(error) 125 raise ConfigError("Could not create %r : %r" % (dirname, 126 error)) 127 128 try: 129 f = open(config_file,'w') 130 except IOError, error: 131 self.warning(error) 132 raise ConfigError("Could not create %r : %s" % (config_file, error)) 133 134 f.write(default_config) 135 f.close() 136 self.first_load = True 137 return config_file
138
139 - def get_option(self, key, section='general', default=None):
140 """ Fetch the option value stored in the given section, at the 141 given key. Return a default value if the key is not found. 142 143 @param key: the option key to look for 144 @type key: string 145 @param section: the section name to search in 146 @type section: string 147 @param default: the default value to use if the option is not found 148 @type default: object 149 @returns: value of given option in given section 150 @rtype: object 151 """ 152 return self.get_section(section).get(key, default)
153
154 - def set_option(self, key, value, section='general'):
155 """ Store an option value under key id at the given section. 156 157 @param key: the option key to look for 158 @type key: string 159 @param value: the value to store under given key 160 @type value: object 161 @param section: the section name to search in 162 @type section: string 163 """ 164 self._config.setdefault(section,{})[key] = value
165 #self._config[section][key] = value 166
167 - def del_option(self, key, section='general'):
168 """ Remove the option identified by key under the specified 169 section. 170 171 @param key: the option key to look for 172 @type key: string 173 @param section: the section name to search in 174 @type section: string 175 """ 176 section_obj = self.get_section(section) 177 if section_obj and key in section_obj: 178 del section_obj[key] 179 self.set_section(section, section_obj)
180
181 - def write(self, filename=None):
182 """ 183 save the config in a text file (handled by ConfigObj) 184 185 """ 186 outfile = filename 187 try: 188 my_filename = self.get_filename() 189 if not outfile: 190 if my_filename: 191 outfile = open(my_filename, 'w') 192 else: 193 outfile = open(outfile, 'w') 194 except IOError, error: 195 self.warning(error) 196 else: 197 if outfile: 198 self.info('Saving config to file %r' % outfile) 199 self._config.write(outfile=outfile)
200
201 - def rename_section(self, old_name, new_name):
202 """ Rename a section of the config 203 204 Options and comments stored in the section are kept intact. 205 The config is update in-place. No result is returned by this 206 method. 207 208 @param old_name: the section to rename 209 @type old_name: string 210 @param new_name: the new section name 211 @type new_name: string 212 """ 213 section = self.get_section(old_name) 214 if section: 215 try: 216 self._config.rename(old_name, new_name) 217 except KeyError: 218 pass
219
220 - def get_section(self, section_name, default=None):
221 """ Fetch a section from the config 222 223 @param section_name: the section name to look for 224 @type section_name: string 225 @param default: the default value to use if the section is 226 not found 227 @type default: object 228 @returns: the ConfigObj section identified by section_name 229 @rtype: L{elisa.extern.configobj.ConfigObj} or empty dict 230 """ 231 if default is None: 232 default = {} 233 return self._config.get(section_name, default)
234
235 - def set_section(self, section_name, section={}, doc={}):
236 """ 237 Store section_data in a new section identified by section_name 238 in the config 239 240 @param section_name: the section name to update 241 @type section_name: string 242 @param section: the section data 243 @type section: dict 244 @param doc: documentation of section's options 245 @type doc: dict 246 """ 247 if not isinstance(section, Section): 248 section = Section(self._config, 249 self._config.depth+1, 250 self._config.main, 251 indict=section, 252 name=section_name) 253 254 for key in section.keys(): 255 doc.setdefault(key, '') 256 section.comments = dict([(k, ['# %s' % line 257 for line in textwrap.wrap(v, 77)]) 258 for k,v in doc.iteritems()]) 259 if section.items(): 260 self._config[section_name] = section
261
262 - def del_section(self, section_name):
263 """ Remove the section identified by section_name 264 265 @param section_name: the section name to delete 266 @type section_name: string 267 """ 268 if self._config.has_key(section_name): 269 del self._config[section_name]
270
271 - def as_dict(self):
272 """ Helper method to convert the Config instance to a dictionary 273 274 @returns: a mapping of the config's options by section name 275 @rtype: dict 276 """ 277 r = {} 278 for name, section in self._config.iteritems(): 279 r.update({name:section.dict()}) 280 return r
281