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