1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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
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
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
79
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
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
148
150
151
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
163 return inifiles.X2GoIniFile.write(self)
164
165
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
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
196 return self.get_profile_option_type(key)
197
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
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
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
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
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
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
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
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
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
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
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
456 _profile_id = self.to_profile_id(profile_id_or_name)
457 elif self.has_profile_id(profile_id_or_name):
458
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
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
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