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 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: C{dict} 71 @param logger: you can pass an L{X2GoLogger} object to the 72 L{X2GoIniFile} 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: C{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(self.defaultValues) 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(os.path.normpath(_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 result = result.strip(',') 139 return result + ')'
140
141 - def _storeValue(self, section, key, value):
142 """\ 143 Stores a value for a given section and key. 144 145 This methods affects a SafeConfigParser object held in 146 RAM. No configuration file is affected by this 147 method. To write the configuration to disk use 148 the L{write()} method. 149 150 @param section: the ini file section 151 @type section: C{str} 152 @param key: the ini file key in the given section 153 @type key: C{str} 154 @param value: the value for the given section and key 155 @type value: C{str}, C{list}, C{booAl}, ... 156 157 """ 158 if type(value) == type(u''): 159 value = value.encode(utils.get_encoding()) 160 if type(value) is types.BooleanType: 161 self.iniConfig.set(section, key, str(int(value))) 162 elif type(value) in (types.ListType, types.TupleType): 163 self.iniConfig.set(section, key, ", ".join(value)) 164 else: 165 self.iniConfig.set(section, key, str(value))
166
167 - def _fill_defaults(self):
168 """\ 169 Fills a C{SafeConfigParser} object with the default ini file 170 values as pre-defined in Python X2Go or. This SafeConfigParser 171 object is held in RAM. No configuration file is affected by this 172 method. 173 174 """ 175 for section, sectionvalue in self.defaultValues.items(): 176 for key, value in sectionvalue.items(): 177 if self.iniConfig.has_option(section, key): continue 178 if not self.iniConfig.has_section(section): 179 self.iniConfig.add_section(section) 180 self._storeValue(section, key, value)
181
182 - def update_value(self, section, key, value):
183 """\ 184 Change a value for a given section and key. This method 185 does not have any effect on configuration files. 186 187 @param section: the ini file section 188 @type section: C{str} 189 @param key: the ini file key in the given section 190 @type key: C{str} 191 @param value: the value for the given section and key 192 @type value: C{str}, C{list}, C{bool}, ... 193 194 """ 195 if not self.iniConfig.has_section(section): 196 self.iniConfig.add_section(section) 197 self._storeValue(section, key, value) 198 self.write_user_config = True
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 writte, 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
222 - def get_type(self, section, key):
223 """\ 224 Retrieve a value type for a given section and key. The returned 225 value type is based on the default values dictionary. 226 227 @param section: the ini file section 228 @type section: C{str} 229 @param key: the ini file key in the given section 230 @type key: C{str} 231 232 @return: a Python variable type 233 @rtype: class 234 235 """ 236 return type(self.defaultValues[section][key])
237
238 - def get_value(self, section, key, key_type=None):
239 """\ 240 Retrieve a value for a given section and key. 241 242 @param section: the ini file section 243 @type section: C{str} 244 @param key: the ini file key in the given section 245 @type key: C{str} 246 247 @return: the value for the given section and key 248 @rtype: class 249 250 """ 251 if key_type is None: 252 key_type = self.get_type(section, key) 253 if self.iniConfig.has_option(section, key): 254 if key_type is types.BooleanType: 255 return self.iniConfig.getboolean(section, key) 256 elif key_type is types.IntType: 257 return self.iniConfig.getint(section, key) 258 elif key_type is types.ListType: 259 _val = self.iniConfig.get(section, key) 260 _val = _val.strip() 261 if _val.startswith('[') and _val.endswith(']'): 262 return eval(_val) 263 elif ',' in _val: 264 _val = [ v.strip() for v in _val.split(',') ] 265 else: 266 _val = [ _val ] 267 return _val 268 else: 269 _val = self.iniConfig.get(section, key) 270 return _val.decode(utils.get_encoding())
271 get = get_value 272 __call__ = get_value 273 274 @property
275 - def printable_config_file(self):
276 """\ 277 Returns a printable configuration file as a multi-line string. 278 279 """ 280 stdout = cStringIO.StringIO() 281 self.iniConfig.write(stdout) 282 _ret_val = stdout.getvalue() 283 stdout.close() 284 return _ret_val
285