Package x2go :: Package backends :: Package profiles :: Module _file
[frames] | no frames]

Source Code for Module x2go.backends.profiles._file

  1  # -*- coding: utf-8 -*- 
  2   
  3  # Copyright (C) 2010-2013 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  """\ 
 21  L{X2GoSessionProfiles} class - managing x2goclient session profiles. 
 22   
 23  L{X2GoSessionProfiles} is a public API class. Use this class in your Python X2Go based  
 24  applications. 
 25   
 26  """ 
 27  __NAME__ = 'x2gosessionprofiles-pylib' 
 28   
 29  import copy 
 30  import types 
 31  import re 
 32   
 33  # Python X2Go modules 
 34  from x2go.defaults import X2GO_SESSIONPROFILES_CONFIGFILES as _X2GO_SESSIONPROFILES_CONFIGFILES 
 35  from x2go.defaults import X2GO_SESSIONPROFILE_DEFAULTS as _X2GO_SESSIONPROFILE_DEFAULTS 
 36  from x2go.defaults import X2GO_DESKTOPSESSIONS as _X2GO_DESKTOPSESSIONS 
 37  import x2go.inifiles as inifiles 
 38  import x2go.log as log 
 39  import x2go.utils as utils 
 40  from x2go.x2go_exceptions import X2GoProfileException 
41 42 43 -class X2GoSessionProfilesFILE(inifiles.X2GoIniFile):
44 45 defaultSessionProfile = _X2GO_SESSIONPROFILE_DEFAULTS 46 _non_profile_sections = ('embedded') 47
48 - def __init__(self, config_files=_X2GO_SESSIONPROFILES_CONFIGFILES, defaults=None, session_profile_defaults=None, logger=None, loglevel=log.loglevel_DEFAULT):
49 """\ 50 Retrieve X2Go session profiles from a file, typically C{~/.x2goclient/sessions}. 51 52 @param config_files: a list of config file locations, the first file name in this list the user has write access to will be the user configuration file 53 @type config_files: C{list} 54 @param defaults: not used for this class 55 @type defaults: C{dict} 56 @param session_profile_defaults: a default session profile 57 @type session_profile_defaults: C{dict} 58 @param logger: you can pass an L{X2GoLogger} object to the 59 L{X2GoSessionProfilesFILE} constructor 60 @type logger: L{X2GoLogger} instance 61 @param loglevel: if no L{X2GoLogger} object has been supplied a new one will be 62 constructed with the given loglevel 63 @type loglevel: C{int} 64 65 """ 66 self.defaultValues = {} 67 self._profile_metatypes = {} 68 self._cached_profile_ids = [] 69 self._cached_profile_names = [] 70 self._profiles_need_profile_id_renewal = [] 71 72 if logger is None: 73 self.logger = log.X2GoLogger(loglevel=loglevel) 74 else: 75 self.logger = copy.deepcopy(logger) 76 self.logger.tag = __NAME__ 77 78 # providing defaults for an X2GoSessionProfiles instance will---in the worst case---override your 79 # existing sessions file in your home directory once you write the sessions back to file... 80 inifiles.X2GoIniFile.__init__(self, config_files, defaults=defaults, logger=logger, loglevel=loglevel) 81 82 if utils._checkSessionProfileDefaults(session_profile_defaults): 83 self.defaultSessionProfile = session_profile_defaults 84 85 self.session_profiles = [ p for p in self.iniConfig.sections() if p not in self._non_profile_sections ] 86 for session_profile in self.session_profiles: 87 for key, default_value in self.defaultSessionProfile.iteritems(): 88 if not self.iniConfig.has_option(session_profile, key): 89 self._storeValue(session_profile, key, default_value) 90 self.get_profile_metatype(session_profile)
91
92 - def __call__(self, profile_id_or_name):
93 """\ 94 Retrieve the session profile configuration for a given session profile ID (or name) 95 96 @param profile_id_or_name: profile ID or profile name 97 @type profile_id_or_name: C{str} 98 99 @return: the profile ID's / name's profile configuration 100 @rtype: C{dict} 101 102 """ 103 _profile_id = self.check_profile_id_or_name(self, profile_id_or_name) 104 return self.get_profile_config(profile_id=_profile_id)
105
106 - def get_profile_metatype(self, profile_id_or_name, force=False):
107 """\ 108 Detect a human readable session profile type from the session profile configuration. 109 110 @param profile_id_or_name: profile ID or profile name 111 @type profile_id_or_name: C{str} 112 @param force: re-detect the meta type, otherwise use a cached result 113 @type force: C{bool} 114 115 @return: the profile ID's / name's meta type 116 @rtype: C{str} 117 118 """ 119 _profile_id = self.check_profile_id_or_name(profile_id_or_name) 120 if not self._profile_metatypes.has_key(_profile_id) or force: 121 _config = self.get_profile_config(_profile_id) 122 if _config['host']: 123 if _config['rdpserver'] and _config['command'] == 'RDP': 124 _metatype = 'RDP/proxy' 125 elif _config['published']: 126 127 if _config['command'] in _X2GO_DESKTOPSESSIONS.keys(): 128 _metatype = '%s + Published Applications' % _config['command'] 129 else: 130 _metatype = 'Published Applications' 131 132 elif _config['rootless']: 133 _metatype = 'Single Applications' 134 elif _config['command'] in _X2GO_DESKTOPSESSIONS.keys(): 135 _metatype = '%s Desktop' % _config['command'] 136 elif _config['command'] in _X2GO_DESKTOPSESSIONS.values(): 137 _metatype = '%s Desktop' % [ s for s in _X2GO_DESKTOPSESSIONS.keys() if _config['command'] == _X2GO_DESKTOPSESSIONS[s] ][0] 138 else: 139 _metatype = 'CUSTOM Desktop' 140 else: 141 if _config['rdpserver'] and _config['command'] == 'RDP': 142 _metatype = 'RDP/direct' 143 else: 144 _metatype = 'not supported' 145 self._profile_metatypes[_profile_id] = _metatype 146 else: 147 return self._profile_metatypes[_profile_id]
148
149 - def write(self):
150 151 # then update profile IDs for profiles that have a renamed host attribute... 152 for profile_id in self._profiles_need_profile_id_renewal: 153 _config = self.get_profile_config(profile_id=profile_id) 154 self.iniConfig.remove_section(profile_id) 155 try: self._cached_profile_ids.remove(profile_id) 156 except ValueError: pass 157 self.add_profile(profile_id=None, force_add=True, **_config) 158 self._profiles_need_profile_id_renewal = [] 159 self._cached_profile_ids = [] 160 self._cached_profile_names = [] 161 162 # at last write the profile config as is... 163 return inifiles.X2GoIniFile.write(self)
164 165
166 - def get_profile_option_type(self, option):
167 """\ 168 Get the data type for a specific session profile option. 169 170 @param option: the option to get the data type for 171 @type option: will be detected by this method 172 173 @return: the data type of C{option} 174 @rtype: C{type} 175 176 """ 177 try: 178 return type(self.defaultSessionProfile[option]) 179 except KeyError: 180 return types.StringType
181
182 - def get_type(self, section, key):
183 """\ 184 Override the parent class's get_type method due to the special layout of this class. 185 186 @param section: INI file section 187 @type section: C{str} 188 @param key: key in INI file section 189 @type key: C{str} 190 191 @return: the data type of C{key} in C{section} 192 @rtype: C{type} 193 194 """ 195 # we have to handle the get_type method separately... 196 return self.get_profile_option_type(key)
197
198 - def get_profile_config(self, profile_id_or_name=None, parameter=None, profile_id=None):
199 """\ 200 The configuration options for a single session profile. 201 202 @param profile_id_or_name: either profile ID or profile name is accepted 203 @type profile_id_or_name: C{str} 204 @param parameter: if specified, only the value for the given parameter is returned 205 @type parameter: C{str} 206 @param profile_id: profile ID (faster than specifying C{profile_id_or_name}) 207 @type profile_id: C{str} 208 209 @return: the session profile configuration for the given profile ID (or name) 210 @rtype: C{dict} 211 212 """ 213 _profile_id = profile_id or self.check_profile_id_or_name(profile_id_or_name) 214 _profile_config = {} 215 for option in self.iniConfig.options(_profile_id): 216 _profile_config[option] = self.get(_profile_id, option, key_type=self.get_profile_option_type(option)) 217 218 if parameter is not None: 219 if parameter in _profile_config.keys(): 220 221 value = _profile_config[parameter] 222 223 if parameter == 'export': 224 _strvalue = value.replace(',', ';').strip().strip('"').strip().strip(';').strip() 225 value = {} 226 if _strvalue: 227 _export_paths = _strvalue.split(';') 228 for _path in _export_paths: 229 if not re.match('.*:(0|1)$', _path): _path = '%s:1' % _path 230 _auto_export_path = re.match('.*:1$', _path) and True or False 231 _export_path = ':'.join(_path.split(':')[:-1]) 232 value[_export_path] = _auto_export_path 233 234 return value 235 236 else: 237 raise X2GoProfileException('no such session profile parameter: %s' % parameter) 238 return _profile_config
239
240 - def default_profile_config(self):
241 """\ 242 Return a default session profile. 243 244 @return: default session profile 245 @rtype: C{dict} 246 247 """ 248 return copy.deepcopy(self.defaultSessionProfile)
249
250 - def has_profile(self, profile_id_or_name):
251 """\ 252 Does a session profile of a given profile ID or profile name exist? 253 254 @param profile_id_or_name: profile ID or profile name 255 @type profile_id_or_name: C{str} 256 257 @return: C{True} if there is such a session profile, C{False} otherwise 258 @rtype: C{bool} 259 260 """ 261 try: 262 self.check_profile_id_or_name(profile_id_or_name) 263 return True 264 except X2GoProfileException: 265 return False
266 267 @property
268 - def profile_ids(self):
269 """\ 270 Renders a list of all profile IDs found in the session profile configuration file. 271 272 """ 273 if not self._cached_profile_ids: 274 self._cached_profile_ids = [ s for s in self.iniConfig.sections() if s not in self._non_profile_sections ] 275 return self._cached_profile_ids
276
277 - def has_profile_id(self, profile_id):
278 """\ 279 Does a session profile of a given profile ID exist? (Faster than L{has_profile()}.) 280 281 @param profile_id: profile ID 282 @type profile_id: C{str} 283 284 @return: C{True} if there is such a session profile, C{False} otherwise 285 @rtype: C{bool} 286 287 """ 288 return profile_id in self.profile_ids
289 290 @property
291 - def profile_names(self):
292 """\ 293 Renders a list of all profile names found in the session profile configuration file. 294 295 """ 296 if not self._cached_profile_names: 297 self._cached_profile_names = [ self.to_profile_name(p) for p in self.profile_ids ] 298 return self._cached_profile_names
299
300 - def has_profile_name(self, profile_name):
301 """\ 302 Does a session profile of a given profile name exist? (Faster than L{has_profile()}.) 303 304 @param profile_name: profile name 305 @type profile_name: C{str} 306 307 @return: C{True} if there is such a session profile, C{False} otherwise 308 @rtype: C{bool} 309 310 """ 311 return profile_name in self.profile_names
312
313 - def to_profile_id(self, profile_name):
314 """\ 315 Convert profile name to profile ID. 316 317 @param profile_name: profile name 318 @type profile_name: C{str} 319 320 @return: profile ID 321 @rtype: C{str} 322 323 """ 324 _profile_ids = [ p for p in self.profile_ids if self.to_profile_name(p) == profile_name ] 325 if len(_profile_ids) == 1: 326 return _profile_ids[0] 327 elif len(_profile_ids) == 0: 328 return None 329 else: 330 raise X2GoProfileException('The sessions config file contains multiple session profiles with name: %s' % profile_name)
331
332 - def to_profile_name(self, profile_id):
333 """\ 334 Convert profile ID to profile name. 335 336 @param profile_id: profile ID 337 @type profile_id: C{str} 338 339 @return: profile name 340 @rtype: C{str} 341 342 """ 343 _profile_config = self.get_profile_config(profile_id=profile_id) 344 if _profile_config.has_key('name'): 345 return _profile_config['name'] 346 else: 347 return ''
348
349 - def add_profile(self, profile_id=None, force_add=False, **kwargs):
350 """\ 351 Add a new session profile. 352 353 @param profile_id: a custom profile ID--if left empty a profile ID will be auto-generated 354 @type profile_id: C{str} 355 @param kwargs: session profile options for this new session profile 356 @type kwargs: C{dict} 357 358 @return: the (auto-generated) profile ID of the new session profile 359 @rtype: C{str} 360 361 """ 362 if profile_id is None or profile_id in self.profile_ids: 363 profile_id = utils._genSessionProfileId() 364 365 if 'name' not in kwargs.keys(): 366 raise X2GoProfileException('session profile parameter ,,name\'\' is missing in method parameters') 367 368 if kwargs['name'] in self.profile_names and not force_add: 369 raise X2GoProfileException('a profile of name ,,%s\'\' already exists' % kwargs['name']) 370 371 for key, value in kwargs.items(): 372 self.update_value(None, key, value, profile_id=profile_id) 373 374 for key, value in self.defaultSessionProfile.items(): 375 if key in kwargs: continue 376 self.update_value(None, key, value, profile_id=profile_id) 377 378 self._cached_profile_ids = [] 379 self._cached_profile_names = [] 380 381 return profile_id
382
383 - def delete_profile(self, profile_id_or_name):
384 """\ 385 Delete a session profile from the configuration file. 386 387 @param profile_id_or_name: profile ID or profile name 388 @type profile_id_or_name: C{str} 389 390 """ 391 _profile_id = self.check_profile_id_or_name(profile_id_or_name) 392 self.iniConfig.remove_section(_profile_id) 393 self.write_user_config = True 394 self.write() 395 self._cached_profile_ids = [] 396 self._cached_profile_names = []
397
398 - def update_value(self, section, key, value, profile_id=None):
399 """\ 400 Update a value in a session profile. 401 402 @param section: the profile ID 403 @type section: C{str} 404 @param key: the session profile option of the given profile ID 405 @type key: C{str} 406 @param value: the value to update the session profile option with 407 @type value: any type, depends on the session profile option 408 409 """ 410 try: 411 profile_id = profile_id or self.check_profile_id_or_name(section) 412 except X2GoProfileException: 413 profile_id = section 414 415 if key == 'name': 416 profile_name = value 417 current_profile_name = self.get_value(profile_id, key) 418 if not profile_name: 419 raise X2GoProfileException('profile name for profile id %s may not be empty' % profile_id) 420 else: 421 self._cached_profile_names = [] 422 if profile_name != current_profile_name and profile_name in self.profile_names: 423 raise X2GoProfileException('a profile of name ,,%s\'\' already exists' % profile_name) 424 425 if key == 'export' and type(value) == types.DictType: 426 _strvalue = '"' 427 for folder in value.keys(): 428 _strvalue += "%s:%s;" % (folder, int(value[folder])) 429 _strvalue += '"' 430 _strvalue = _strvalue.replace('""', '') 431 value = _strvalue 432 433 if key == 'host': 434 _config = self.get_profile_config(profile_id=profile_id) 435 if _config.has_key('host') and _config['host'] != value: 436 self._profiles_need_profile_id_renewal.append(profile_id) 437 438 inifiles.X2GoIniFile.update_value(self, profile_id, key, value)
439
440 - def check_profile_id_or_name(self, profile_id_or_name):
441 """\ 442 Detect the profile ID from a given string which maybe profile ID or profile name. 443 444 @param profile_id_or_name: profile ID or profile name 445 @type profile_id_or_name: C{str} 446 447 @return: profile ID 448 @rtype: C{str} 449 450 @raise X2GoProfileException: if no such session profile exists 451 452 """ 453 _profile_id = None 454 if self.has_profile_name(profile_id_or_name): 455 # we were given a sesion profile name... 456 _profile_id = self.to_profile_id(profile_id_or_name) 457 elif self.has_profile_id(profile_id_or_name): 458 # we were given a session profile id... 459 _profile_id = profile_id_or_name 460 else: 461 raise X2GoProfileException('No session profile with id or name ,,%s\'\' exists.' % profile_id_or_name) 462 return _profile_id
463
464 - def to_session_params(self, profile_id_or_name=None, profile_id=None):
465 """\ 466 Convert session profile options to L{X2GoSession} constructor method parameters. 467 468 @param profile_id_or_name: either profile ID or profile name is accepted 469 @type profile_id_or_name: C{str} 470 @param profile_id: profile ID (fast than specifying C{profile_id_or_name}) 471 @type profile_id: C{str} 472 473 @return: a dictionary of L{X2GoSession} constructor method parameters 474 @rtype: C{dict} 475 476 """ 477 _profile_id = profile_id or self.check_profile_id_or_name(profile_id_or_name) 478 return utils._convert_SessionProfileOptions_2_SessionParams(self.get_profile_config(_profile_id))
479
480 - def get_session_param(self, profile_id_or_name, param):
481 """\ 482 Get a single L{X2GoSession} parameter from a specific session profile. 483 484 @param profile_id_or_name: either profile ID or profile name is accepted 485 @type profile_id_or_name: C{str} 486 @param param: the parameter name in the L{X2GoSession} constructor method 487 @type param: C{str} 488 489 @return: the value of the session profile option represented by C{param} 490 @rtype: depends on the session profile option requested 491 492 """ 493 return self.to_session_params(profile_id_or_name)[param]
494