Package x2go :: Module inifiles
[frames] | no frames]

Source Code for Module x2go.inifiles

  1  # -*- coding: utf-8 -*- 
  2   
  3  # Copyright (C) 2010-2011 by Mike Gabriel <mike.gabriel@das-netzwerkteam.de> 
  4  # 
  5  # Python X2go is free software; you can redistribute it and/or modify 
  6  # it under the terms of the GNU General Public License as published by 
  7  # the Free Software Foundation; either version 3 of the License, or 
  8  # (at your option) any later version. 
  9  # 
 10  # Python X2go is distributed in the hope that it will be useful, 
 11  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 12  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 13  # GNU General Public License for more details. 
 14  # 
 15  # You should have received a copy of the GNU General Public License 
 16  # along with this program; if not, write to the 
 17  # Free Software Foundation, Inc., 
 18  # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. 
 19  # 
 20  # This code was initially written by: 
 21  #       2010 Dick Kniep <dick.kniep@lindix.nl> 
 22  # 
 23  # Other contributors: 
 24  #       none so far 
 25   
 26  """\ 
 27  X2goProcessIniFile - helper class for parsing .ini files 
 28   
 29  """ 
 30  __NAME__ = 'x2goinifiles-pylib' 
 31   
 32  # modules 
 33  import os 
 34  import ConfigParser 
 35  import types 
 36  import cStringIO 
 37  import copy 
 38   
 39  # Python X2go modules 
 40  from defaults import LOCAL_HOME as _current_home 
 41  import log 
 42  import utils 
43 44 -class X2goIniFile(object):
45 """ 46 Base class for processing the different ini files used by X2go 47 clients. Primarily used to standardize the content of the different 48 X2go client ini file (settings, printing, sessions, xconfig). 49 50 If entries are omitted in an ini file, they are filled with 51 default values (as hard coded in Python X2go), so the resulting objects 52 always contain the same fields. 53 54 """ 55 defaultValues = { 56 'none': { 57 'none': 'empty', 58 }, 59 } 60 write_user_config = False 61 user_config_file = None 62
63 - def __init__(self, config_files, defaults=None, logger=None, loglevel=log.loglevel_DEFAULT):
64 """\ 65 @param config_files: a list of configuration file names (e.g. a global filename and a user's home 66 directory filename) 67 @type config_files: C{list} 68 @param defaults: a cascaded Python dicitionary structure with ini file defaults (to override 69 Python X2go's hard coded defaults in L{defaults} 70 @type defaults: dict 71 @param logger: you can pass an L{X2goLogger} object to the 72 L{X2goFwServer} constructor 73 @type logger: L{X2goLogger} instance 74 @param loglevel: if no L{X2goLogger} object has been supplied a new one will be 75 constructed with the given loglevel 76 @type loglevel: int 77 78 """ 79 # make sure a None type gets turned into list type 80 if not config_files: 81 config_files = [] 82 83 if logger is None: 84 self.logger = log.X2goLogger(loglevel=loglevel) 85 else: 86 self.logger = copy.deepcopy(logger) 87 self.logger.tag = __NAME__ 88 89 self.config_files = config_files 90 91 if utils._checkIniFileDefaults(defaults): 92 self.defaultValues = defaults 93 94 # we purposefully do not inherit the SafeConfigParser class 95 # here as we do not want to run into name conflicts between 96 # X2go ini file options and method / property names in 97 # SafeConfigParser... This is a pre-cautious approach... 98 self.iniConfig = ConfigParser.SafeConfigParser() 99 self.iniConfig.optionxform = str 100 101 _create_file = False 102 for file_name in self.config_files: 103 if file_name.startswith(_current_home): 104 if not os.path.exists(file_name): 105 utils.touch_file(file_name) 106 _create_file = True 107 break 108 109 self.load() 110 111 if _create_file: 112 self.write_user_config = True 113 self.write()
114
115 - def load(self):
116 """\ 117 R(e-r)ead configuration file(s). 118 119 """ 120 self.logger('proposed config files are %s' % self.config_files, loglevel=log.loglevel_INFO, ) 121 _found_config_files = self.iniConfig.read(self.config_files) 122 self.logger('config files found: %s' % _found_config_files or 'none', loglevel=log.loglevel_INFO, ) 123 124 for file_name in _found_config_files: 125 if file_name.startswith(_current_home): 126 # we will use the first file found in the user's home dir for writing modifications 127 self.user_config_file = file_name 128 break 129 130 self.config_files = _found_config_files 131 self._fill_defaults()
132
133 - def __repr__(self):
134 result = 'X2goIniFile(' 135 for p in dir(self): 136 if '__' in p or not p in self.__dict__ or type(p) is types.InstanceType: continue 137 result += p + '=' + str(self.__dict__[p]) 138 return result + ')'
139
140 - def _storeValue(self, section, key, value):
141 """\ 142 Stores a value for a given section and key. 143 144 This methods affects a SafeConfigParser object held in 145 RAM. No configuration file is affected by this 146 method. To write the configuration to disk use 147 the L{write()} method. 148 149 @param section: the ini file section 150 @type section: C{str} 151 @param key: the ini file key in the given section 152 @type key: C{str} 153 @param value: the value for the given section and key 154 @type value: C{str}, C{list}, C{booAl}, ... 155 156 """ 157 if type(value) == type(u''): 158 value = value.encode(utils.get_encoding()) 159 if type(value) is types.BooleanType: 160 self.iniConfig.set(section, key, str(int(value))) 161 elif type(value) in (types.ListType, types.TupleType): 162 self.iniConfig.set(section, key, ", ".join(value)) 163 else: 164 self.iniConfig.set(section, key, str(value))
165
166 - def _fill_defaults(self):
167 """\ 168 Fills a C{SafeConfigParser} object with the default ini file 169 values as pre-defined in Python X2go or. This SafeConfigParser 170 object is held in RAM. No configuration file is affected by this 171 method. 172 173 """ 174 for section, sectionvalue in self.defaultValues.items(): 175 for key, value in sectionvalue.items(): 176 if self.iniConfig.has_option(section, key): continue 177 if not self.iniConfig.has_section(section): 178 self.iniConfig.add_section(section) 179 self._storeValue(section, key, value)
180
181 - def update_value(self, section, key, value):
182 """\ 183 Change a value for a given section and key. This method 184 does not have any effect on configuration files. 185 186 @param section: the ini file section 187 @type section: C{str} 188 @param key: the ini file key in the given section 189 @type key: C{str} 190 @param value: the value for the given section and key 191 @type value: C{str}, C{list}, C{bool}, ... 192 193 """ 194 if not self.iniConfig.has_section(section): 195 self.iniConfig.add_section(section) 196 self._storeValue(section, key, value) 197 self.write_user_config = True
198
199 - def write(self):
200 """\ 201 Write the ini file modifications (SafeConfigParser object) from RAM to disk. 202 203 For writing the first of the C{config_files} specified on instance construction 204 that is writable will be used. 205 206 """ 207 if self.user_config_file and self.write_user_config: 208 fd = open(self.user_config_file, 'wb') 209 self.iniConfig.write(fd) 210 fd.close() 211 self.write_user_config = False
212
213 - def get_type(self, section, key):
214 """\ 215 Retrieve a value type for a given section and key. The returned 216 value type is based on the default values dictionary. 217 218 @param section: the ini file section 219 @type section: C{str} 220 @param key: the ini file key in the given section 221 @type key: C{str} 222 223 @return: a Python variable type 224 @rtype: class 225 226 """ 227 return type(self.defaultValues[section][key])
228
229 - def get_value(self, section, key, key_type=None):
230 """\ 231 Retrieve a value for a given section and key. 232 233 @param section: the ini file section 234 @type section: C{str} 235 @param key: the ini file key in the given section 236 @type key: C{str} 237 238 @return: the value for the given section and key 239 @rtype: class 240 241 """ 242 if key_type is None: 243 key_type = self.get_type(section, key) 244 if self.iniConfig.has_option(section, key): 245 if key_type is types.BooleanType: 246 return self.iniConfig.getboolean(section, key) 247 elif key_type is types.IntType: 248 return self.iniConfig.getint(section, key) 249 elif key_type is types.ListType: 250 val = self.iniConfig.get(section, key) 251 if val.startswith('[') and val.endswith(']'): 252 return eval(val) 253 elif ',' in val: 254 val = [ v.strip() for v in val.split(',') ] 255 else: 256 val = [ val ] 257 else: 258 _val = self.iniConfig.get(section, key) 259 return _val.decode(utils.get_encoding())
260 get = get_value 261 __call__ = get_value 262 263 @property
264 - def printable_config_file(self):
265 """\ 266 Returns a printable configuration file as a multi-line string. 267 268 """ 269 stdout = cStringIO.StringIO() 270 self.iniConfig.write(stdout) 271 _ret_val = stdout.getvalue() 272 stdout.close() 273 return _ret_val
274