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

Source Code for Module x2go.inifiles

  1  # -*- coding: utf-8 -*- 
  2   
  3  # Copyright (C) 2010-2014 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 Affero 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 Affero General Public License for more details. 
 14  # 
 15  # You should have received a copy of the GNU Affero 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
56 - def __init__(self, config_files, defaults=None, logger=None, loglevel=log.loglevel_DEFAULT):
57 """\ 58 @param config_files: a list of configuration file names (e.g. a global filename and a user's home 59 directory filename) 60 @type config_files: C{list} 61 @param defaults: a cascaded Python dicitionary structure with ini file defaults (to override 62 Python X2Go's hard coded defaults in L{defaults} 63 @type defaults: C{dict} 64 @param logger: you can pass an L{X2GoLogger} object to the 65 L{X2GoIniFile} constructor 66 @type logger: L{X2GoLogger} instance 67 @param loglevel: if no L{X2GoLogger} object has been supplied a new one will be 68 constructed with the given loglevel 69 @type loglevel: C{int} 70 71 """ 72 self.user_config_file = None 73 self._write_user_config = True 74 75 # make sure a None type gets turned into list type 76 if not config_files: 77 config_files = [] 78 79 if logger is None: 80 self.logger = log.X2GoLogger(loglevel=loglevel) 81 else: 82 self.logger = copy.deepcopy(logger) 83 self.logger.tag = __NAME__ 84 85 self.config_files = config_files 86 87 if utils._checkIniFileDefaults(defaults): 88 self.defaultValues = defaults 89 else: 90 self.defaultValues = {} 91 92 # we purposefully do not inherit the SafeConfigParser class 93 # here as we do not want to run into name conflicts between 94 # X2Go ini file options and method / property names in 95 # SafeConfigParser... This is a pre-cautious approach... 96 self.iniConfig = ConfigParser.SafeConfigParser() 97 self.iniConfig.optionxform = str 98 99 _create_file = False 100 for file_name in self.config_files: 101 file_name = os.path.normpath(file_name) 102 if file_name.startswith(_current_home): 103 if not os.path.exists(file_name): 104 utils.touch_file(file_name) 105 _create_file = True 106 self.user_config_file = file_name 107 break 108 self.load() 109 110 if _create_file: 111 self._write_user_config = True 112 self._X2GoIniFile__write()
113
114 - def load(self):
115 """\ 116 R(e-r)ead configuration file(s). 117 118 """ 119 self.logger('proposed config files are %s' % self.config_files, loglevel=log.loglevel_INFO, ) 120 _found_config_files = self.iniConfig.read(self.config_files) 121 self.logger('config files found: %s' % _found_config_files or 'none', loglevel=log.loglevel_INFO, ) 122 123 for file_name in _found_config_files: 124 if file_name.startswith(os.path.normpath(_current_home)): 125 # we will use the first file found in the user's home dir for writing modifications 126 self.user_config_file = file_name 127 break 128 129 self.config_files = _found_config_files 130 self._fill_defaults()
131
132 - def __repr__(self):
133 result = 'X2GoIniFile(' 134 for p in dir(self): 135 if '__' in p or not p in self.__dict__ or type(p) is types.InstanceType: continue 136 result += p + '=' + str(self.__dict__[p]) + ',' 137 result = result.strip(',') 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 __update_value = update_value 199
200 - def write(self):
201 """\ 202 Write the ini file modifications (SafeConfigParser object) from RAM to disk. 203 204 For writing the first of the C{config_files} specified on instance construction 205 that is writable will be used. 206 207 @return: C{True} if the user config file has been successfully written, C{False} otherwise. 208 @rtype: C{bool} 209 210 """ 211 if self.user_config_file and self._write_user_config: 212 try: 213 fd = open(self.user_config_file, 'wb') 214 self.iniConfig.write(fd) 215 fd.close() 216 self._write_user_config = False 217 return True 218 except Exception, e: 219 print e 220 return False
221 __write = write 222
223 - def get_type(self, section, key):
224 """\ 225 Retrieve a value type for a given section and key. The returned 226 value type is based on the default values dictionary. 227 228 @param section: the ini file section 229 @type section: C{str} 230 @param key: the ini file key in the given section 231 @type key: C{str} 232 233 @return: a Python variable type 234 @rtype: class 235 236 """ 237 return type(self.defaultValues[section][key])
238
239 - def get_value(self, section, key, key_type=None):
240 """\ 241 Retrieve a value for a given section and key. 242 243 @param section: the ini file section 244 @type section: C{str} 245 @param key: the ini file key in the given section 246 @type key: C{str} 247 248 @return: the value for the given section and key 249 @rtype: class 250 251 """ 252 if key_type is None: 253 key_type = self.get_type(section, key) 254 if self.iniConfig.has_option(section, key): 255 if key_type is types.BooleanType: 256 return self.iniConfig.getboolean(section, key) 257 elif key_type is types.IntType: 258 return self.iniConfig.getint(section, key) 259 elif key_type is types.ListType: 260 _val = self.iniConfig.get(section, key) 261 _val = _val.strip() 262 if _val.startswith('[') and _val.endswith(']'): 263 return eval(_val) 264 elif ',' in _val: 265 _val = [ v.strip() for v in _val.split(',') ] 266 else: 267 _val = [ _val ] 268 return _val 269 else: 270 _val = self.iniConfig.get(section, key) 271 return _val.decode(utils.get_encoding())
272 get = get_value 273 __call__ = get_value 274 275 @property
276 - def printable_config_file(self):
277 """\ 278 Returns a printable configuration file as a multi-line string. 279 280 """ 281 stdout = cStringIO.StringIO() 282 self.iniConfig.write(stdout) 283 _ret_val = stdout.getvalue() 284 stdout.close() 285 return _ret_val
286