Package x2go :: Module client

[frames] | no frames]

# Source Code for Module x2go.client

       1  # -*- coding: utf-8 -*-
       2
       3  # Copyright (C) 2010-2013 by Mike Gabriel <mike.gabriel@das-netzwerkteam.de>
       4
       5  #
       6  # Python X2Go is free software; you can redistribute it and/or modify
       7  # it under the terms of the GNU Affero General Public License as published by
       8  # the Free Software Foundation; either version 3 of the License, or
       9  # (at your option) any later version.
      10  #
      11  # Python X2Go is distributed in the hope that it will be useful,
      12  # but WITHOUT ANY WARRANTY; without even the implied warranty of
      13  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14  # GNU Affero General Public License for more details.
      15  #
      16  # You should have received a copy of the GNU Affero General Public License
      17  # along with this program; if not, write to the
      18  # Free Software Foundation, Inc.,
      19  # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
      20
      21  """\
      22  L{X2GoClient} is a public API class. Use this class in your Python X2Go based
      23  applications.  Use it as a parent class for your own object oriented L{X2GoClient}'ish
      24  class implementation.
      25
      26  Supported Features
      27  ==================
      28      Supported features are:
      29
      30          - X2Go multi-session management
      31          - keep track of initiated sessions
      32          - grant access to X2Go client config files: C{settings}, C{printing}, C{sessions}
      33            and C{xconfig} (Windows only) as normally found in C{~/.x2goclient}
      34          - instantiate an X2Go session by a set of Python parameters
      35          - load a session profile from x2goclient's C{sessions} configuration file
      36            and start the---profile-based pre-configured---session
      37          - sharing of local folders with remote X2Go sessions
      38          - enabling and mangaging X2Go printing (real printing, viewing as PDF, saving
      39            to a local folder or executing a custom »print« command
      40          - transparent tunneling of audio (Pulseaudio, ESD)
      41          - sharing of other desktops
      42          - LDAP support for X2Go server clusters (NOT IMPLEMENTED YET)
      43
      44  Non-Profile Sessions
      45  ====================
      46      A new non-profile based X2Go session within an L{X2GoClient} instance is setup in the
      47      following way:
      48
      49          - import the Python X2Go module and call the session constructor::
      50
      51              import x2go
      52              x2go_client = x2go.X2GoClient()
      53
      54          - register a new L{X2GoClient} session; this creates an L{X2GoSession} instance
      55            and calls its constructor method::
      56
      57              x2go_sess_uuid = x2go_client.register_session(<many-options>)
      58
      59          - connect to the session's remote X2Go server (SSH/Paramiko)::
      60
      61              x2go_client.connect_session(x2go_sess_uuid)
      62
      63          - via the connected X2Go client session you can start or resume a remote
      64            X-windows session on an X2Go server now::
      65
      66              x2go_client.start_session(x2go_sess_uuid)
      67
      68            resp.::
      69
      70              x2go_client.resume_session(x2go_sess_uuid, session_name=<session_name_of_resumable_session>)
      71
      72          - a list of available sessions on the respective server (for resuming) can be obtained in
      73            this way::
      74
      75              x2go_client.list_sessions(x2go_sess_uuid, session_name=<session_name_of_resumable_session>)
      76
      77  Profiled Sessions
      78  =================
      79      A new profile based X2Go session (i.e. using pre-defined session profiles) within an
      80      L{X2GoClient} instance is setup in a much easier way:
      81
      82          - import the Python X2Go module and call the session constructor::
      83
      84              import x2go
      85              x2go_client = x2go.X2GoClient()
      86
      87          - register an X2GoClient session based on a pre-configured session profile::
      88
      89              x2go_sess_uuid = x2go_client.register_session(profile_name=<session_profile_name>)
      90
      91          - or alternatively by the profile id in the »sessions« file (the name of the [<section>]
      92            in the »sessions« file::
      93
      94              x2go_sess_uuid = x2go_client.register_session(profile_id=<session_profile_id>)
      95
      96          - now you proceed in a similar way as shown above::
      97
      98              x2go_client.connect_session(x2go_sess_uuid)
      99              x2go_client.start_session(x2go_sess_uuid)
     100
     101            resp.::
     102
     103              x2go_client.resume_session(x2go_sess_uuid, session_name=<session_name_of_resumable_session>)
     104
     105
     106  Session Suspending/Terminating
     107  ==============================
     108
     109      You can suspend or terminate your sessions by calling the follwing commands::
     110
     111          x2go_client.suspend_session(x2go_sess_uuid)
     112
     113      resp.::
     114
     115          x2go_client.terminate_session(x2go_sess_uuid)
     116
     117  """
     118  __NAME__ = 'x2goclient-pylib'
     119
     120  #modules
     121  import copy
     122  import sys
     123  import types
     124  import os
     125
     126  # Python X2Go modules
     127  from registry import X2GoSessionRegistry
     128  from guardian import X2GoSessionGuardian
     129  from cache import X2GoListSessionsCache
     130  import x2go_exceptions
     131  import log
     132  import utils
     133
     134  # we hide the default values from epydoc (that's why we transform them to _UNDERSCORE variables)
     135  from defaults import X2GOCLIENT_OS as _X2GOCLIENT_OS
     136  from defaults import LOCAL_HOME as _LOCAL_HOME
     137  from defaults import CURRENT_LOCAL_USER as _CURRENT_LOCAL_USER
     138  from defaults import X2GO_CLIENT_ROOTDIR as _X2GO_CLIENT_ROOTDIR
     139  from defaults import X2GO_SESSIONS_ROOTDIR as _X2GO_SESSIONS_ROOTDIR
     140  from defaults import X2GO_SSH_ROOTDIR as _X2GO_SSH_ROOTDIR
     141  from defaults import X2GO_SESSIONPROFILES_FILENAME as _X2GO_SESSIONPROFILES_FILENAME
     142  from defaults import X2GO_SETTINGS_FILENAME as _X2GO_SETTINGS_FILENAME
     143  from defaults import X2GO_PRINTING_FILENAME as _X2GO_PRINTING_FILENAME
     144  from defaults import X2GO_XCONFIG_FILENAME as _X2GO_XCONFIG_FILENAME
     145  from defaults import PUBAPP_MAX_NO_SUBMENUS as _PUBAPP_MAX_NO_SUBMENUS
     146
     147  from defaults import BACKENDS_CONTROLSESSION as _BACKENDS_CONTROLSESSION
     148  from defaults import BACKENDS_TERMINALSESSION as _BACKENDS_TERMINALSESSION
     149  from defaults import BACKENDS_SERVERSESSIONINFO as _BACKENDS_SERVERSESSIONINFO
     150  from defaults import BACKENDS_SERVERSESSIONLIST as _BACKENDS_SERVERSESSIONLIST
     151  from defaults import BACKENDS_PROXY as _BACKENDS_PROXY
     152  from defaults import BACKENDS_SESSIONPROFILES as _BACKENDS_SESSIONPROFILES
     153  from defaults import BACKENDS_CLIENTSETTINGS as _BACKENDS_CLIENTSETTINGS
     154  from defaults import BACKENDS_CLIENTPRINTING as _BACKENDS_CLIENTPRINTING
     155
     156  import x2go.backends.control as control
     157  import x2go.backends.terminal as terminal
     158  import x2go.backends.info as info
     159  import x2go.backends.proxy as proxy
     160  import x2go.backends.profiles as profiles
     161  import x2go.backends.settings as settings
     162  import x2go.backends.printing as printing
     163
     164  if _X2GOCLIENT_OS == 'Windows':
     165      from xserver import X2GoClientXConfig, X2GoXServer
     166      from pulseaudio import X2GoPulseAudio
     167
     168
     169 -class X2GoClient(object):
     170      """\
     171      The X2GoClient implements _THE_ public Python X2Go API. With it you can
     172      construct your own X2Go client application in Python.
     173
     174      Most methods in this class require that you have registered a session
     175      with a remote X2Go server (passing of session options, initialization of the
     176      session object etc.) and connected to it (authentication). For these two steps
     177      use these methods: L{X2GoClient.register_session()} and L{X2GoClient.connect_session()}.
     178
     179      """
     180
     181      lang = 'en'
     182
     183 -    def __init__(self,
     184                   control_backend=control.X2GoControlSession,
     185                   terminal_backend=terminal.X2GoTerminalSession,
     186                   info_backend=info.X2GoServerSessionInfo,
     187                   list_backend=info.X2GoServerSessionList,
     188                   proxy_backend=proxy.X2GoProxy,
     189                   profiles_backend=profiles.X2GoSessionProfiles,
     190                   settings_backend=settings.X2GoClientSettings,
     191                   printing_backend=printing.X2GoClientPrinting,
     192                   client_rootdir=None,
     193                   sessions_rootdir=None,
     194                   ssh_rootdir=None,
     195                   start_xserver=False,
     196                   start_pulseaudio=False,
     197                   use_cache=False,
     198                   use_listsessions_cache=False,
     199                   auto_update_listsessions_cache=False,
     200                   auto_update_listdesktops_cache=False,
     201                   auto_update_listmounts_cache=False,
     202                   auto_update_sessionregistry=False,
     203                   auto_register_sessions=False,
     204                   no_auto_reg_pubapp_sessions=False,
     205                   refresh_interval=5,
     206                   pulseaudio_installdir=os.path.join(os.getcwd(), 'pulseaudio'),
     207                   logger=None, loglevel=log.loglevel_DEFAULT):
     208          """\
     209          @param control_backend: X2Go control session backend to use
     210          @type control_backend: C{class}
     211          @param terminal_backend: X2Go terminal session backend to use
     212          @type terminal_backend: C{class}
     213          @param info_backend: X2Go session info backend to use
     214          @type info_backend: C{class}
     215          @param list_backend: X2Go session list backend to use
     216          @type list_backend: C{class}
     217          @param proxy_backend: X2Go proxy backend to use
     218          @type proxy_backend: C{class}
     219          @param profiles_backend: X2Go session profiles backend to use
     220          @type profiles_backend: C{class}
     221          @param settings_backend: X2Go client settings backend to use
     222          @type settings_backend: C{class}
     223          @param printing_backend: X2Go client printing backend to use
     224          @type printing_backend: C{class}
     225          @param client_rootdir: client base dir (default: ~/.x2goclient)
     226          @type client_rootdir: C{str}
     227          @param sessions_rootdir: sessions base dir (default: ~/.x2go)
     228          @type sessions_rootdir: C{str}
     229          @param ssh_rootdir: ssh base dir (default: ~/.ssh)
     230          @type ssh_rootdir: C{str}
     231          @param start_xserver: start XServer when registering an L{X2GoClient} instance
     232          @type start_xserver: C{bool}
     233          @param start_pulseaudio: start Pulseaudio daemon when registering an L{X2GoClient} instance
     234          @type start_pulseaudio: C{bool}
     235          @param use_cache: alias for C{use_listsessions_cache}
     236          @type use_cache: C{bool}
     237          @param use_listsessions_cache: activate the X2Go session list cache in (L{X2GoListSessionsCache})
     238          @type use_listsessions_cache: C{bool}
     239          @param auto_update_listsessions_cache: activate automatic updates of the X2Go session list cache (L{X2GoListSessionsCache})
     240          @type auto_update_listsessions_cache: C{bool}
     241          @param auto_update_listdesktops_cache: activate automatic updates of desktop lists in (L{X2GoListSessionsCache})
     242          @type auto_update_listdesktops_cache: C{bool}
     243          @param auto_update_listmounts_cache: activate automatic updates of mount lists in (L{X2GoListSessionsCache})
     244          @type auto_update_listmounts_cache: C{bool}
     245          @param auto_update_sessionregistry: activate automatic updates of the X2Go session registry
     246          @type auto_update_sessionregistry: C{bool}
     247          @param auto_register_sessions: activate automatic X2Go session registration
     248          @type auto_register_sessions: C{bool}
     249          @param no_auto_reg_pubapp_sessions: skip automatic X2Go session registration for suspended/running published applications sessions
     250          @type no_auto_reg_pubapp_sessions: C{bool}
     251          @param refresh_interval: refresh session list cache and session status every C{refresh_interval} seconds
     252          @type refresh_interval: C{int}
     253          @param pulseaudio_installdir: install path of Pulseaudio binary
     254          @type pulseaudio_installdir: C{str}
     255          @param logger: you can pass an L{X2GoLogger} object to the
     256              L{X2GoClient} constructor
     257          @type logger: L{X2GoLogger} instance
     258          @param loglevel: if no X2GoLogger object has been supplied a new one will be
     259              constructed with the given loglevel
     260          @type loglevel: C{int}
     261
     262          """
     263          self.listsessions_cache = None
     264
     265          if logger is None:
     266              self.logger = log.X2GoLogger(loglevel=loglevel)
     267          else:
     268              self.logger = copy.deepcopy(logger)
     269          self._logger_tag = __NAME__
     270          if self.logger.tag is None:
     271              self.logger.tag = self._logger_tag
     272
     273          self.control_backend = control_backend
     274          self.terminal_backend = terminal_backend
     275          self.info_backend = info_backend
     276          self.list_backend = list_backend
     277          self.proxy_backend = proxy_backend
     278          self.profiles_backend = profiles_backend
     279          self.settings_backend = settings_backend
     280          self.printing_backend = printing_backend
     281
     282          self._detect_backend_classes()
     283
     284          self.client_rootdir = client_rootdir or os.path.normpath(os.path.join(_LOCAL_HOME, _X2GO_CLIENT_ROOTDIR))
     285          self.sessions_rootdir = sessions_rootdir or os.path.normpath(os.path.join(_LOCAL_HOME, _X2GO_SESSIONS_ROOTDIR))
     286          self.ssh_rootdir = ssh_rootdir or os.path.normpath(os.path.join(_LOCAL_HOME, _X2GO_SSH_ROOTDIR))
     287
     288          self.client_rootdir = os.path.normpath(self.client_rootdir)
     289          self.sessions_rootdir = os.path.normpath(self.sessions_rootdir)
     290          self.ssh_rootdir = os.path.normpath(self.ssh_rootdir)
     291
     292          self.pulseaudio_installdir = os.path.normpath(pulseaudio_installdir)
     293
     294          if self.client_rootdir is not None:
     295              self._has_custom_client_rootdir = True
     296              _sessions_config_file = os.path.join(self.client_rootdir, _X2GO_SESSIONPROFILES_FILENAME)
     297              _settings_config_file = os.path.join(self.client_rootdir, _X2GO_SETTINGS_FILENAME)
     298              _printing_config_file = os.path.join(self.client_rootdir, _X2GO_PRINTING_FILENAME)
     299              _xconfig_config_file = os.path.join(self.client_rootdir, _X2GO_XCONFIG_FILENAME)
     300              self.session_profiles = self.profiles_backend(config_files=[_sessions_config_file], logger=self.logger)
     301              self.client_settings = self.settings_backend(config_files=[_settings_config_file], logger=self.logger)
     302              self.client_printing = self.printing_backend(config_files=[_printing_config_file], client_instance=self, logger=self.logger)
     303          else:
     304              self.session_profiles = self.profiles_backend(logger=self.logger)
     305              self.client_settings = self.settings_backend(logger=self.logger)
     306              self.client_printing = self.printing_backend(client_instance=self, logger=self.logger)
     307
     308          if _X2GOCLIENT_OS == 'Windows' and start_xserver:
     309
     310              if self.client_rootdir:
     311                  self.client_xconfig = X2GoClientXConfig(config_files=[_xconfig_config_file], logger=self.logger)
     312              else:
     313                  self.client_xconfig = X2GoClientXConfig(logger=self.logger)
     314
     315              if not self.client_xconfig.known_xservers:
     316                  self.HOOK_no_known_xserver_found()
     317              else:
     318
     319                  _last_display = None
     320                  if  type(start_xserver) is types.BooleanType:
     321                      p_xs_name = self.client_xconfig.preferred_xserver_names[0]
     322                      _last_display = self.client_xconfig.get_xserver_config(p_xs_name)['last_display']
     323                      self.client_xconfig.detect_unused_xdisplay_port(p_xs_name)
     324                      p_xs = (p_xs_name, self.client_xconfig.get_xserver_config(p_xs_name))
     325                  elif type(start_xserver) is types.StringType:
     326                      _last_display = self.client_xconfig.get_xserver_config(start_xserver)['last_display']
     327                      self.client_xconfig.detect_unused_xdisplay_port(start_xserver)
     328                      p_xs = (start_xserver, self.client_xconfig.get_xserver_config(start_xserver))
     329
     330                  if not self.client_xconfig.running_xservers:
     331
     332                      if p_xs is not None:
     333                          self.xserver = X2GoXServer(p_xs[0], p_xs[1], logger=self.logger)
     334
     335                  else:
     336
     337                      if p_xs is not None and _last_display is not None:
     338                          #
     339                          # FIXME: this trick is nasty, client implementation should rather cleanly shutdown launch X-server processes
     340                          #
     341                          # re-use a left behind X-server instance of a previous/crashed run of Python X2Go Client
     342                          self.logger('found a running (and maybe stray) X-server, trying to re-use it on X DISPLAY port: %s' % _last_display, loglevel=log.loglevel_WARN)
     343                          os.environ.update({'DISPLAY': str(_last_display)})
     344                      else:
     345                          # presume the running XServer listens on :0
     346                          self.logger('using fallback display for X-server: localhost:0', loglevel=log.loglevel_WARN)
     347                          os.environ.update({'DISPLAY': 'localhost:0'})
     348
     349          if _X2GOCLIENT_OS == 'Windows' and start_pulseaudio:
     350              self.pulseaudio = X2GoPulseAudio(path=self.pulseaudio_installdir, client_instance=self, logger=self.logger)
     351
     352          self.auto_register_sessions = auto_register_sessions
     353          self.no_auto_reg_pubapp_sessions = no_auto_reg_pubapp_sessions
     354          self.session_registry = X2GoSessionRegistry(self, logger=self.logger)
     355          self.session_guardian = X2GoSessionGuardian(self, auto_update_listsessions_cache=auto_update_listsessions_cache & (use_listsessions_cache|use_cache),
     356                                                      auto_update_listdesktops_cache=auto_update_listdesktops_cache & use_listsessions_cache,
     357                                                      auto_update_listmounts_cache=auto_update_listmounts_cache & use_listsessions_cache,
     358                                                      auto_update_sessionregistry=auto_update_sessionregistry,
     359                                                      auto_register_sessions=auto_register_sessions,
     360                                                      no_auto_reg_pubapp_sessions=no_auto_reg_pubapp_sessions,
     361                                                      refresh_interval=refresh_interval,
     362                                                      logger=self.logger
     363                                                     )
     364          self.auto_update_sessionregistry = auto_update_sessionregistry
     365
     366          if use_listsessions_cache:
     367              self.listsessions_cache = X2GoListSessionsCache(self, logger=self.logger)
     368
     369          self.use_listsessions_cache = use_listsessions_cache | use_cache
     370          self.auto_update_listsessions_cache = auto_update_listsessions_cache
     371          self.auto_update_listdesktops_cache = auto_update_listdesktops_cache
     372          self.auto_update_listmounts_cache = auto_update_listmounts_cache
     373
     374 -    def HOOK_profile_auto_connect(self, profile_name='UNKNOWN'):
     375          """\
     376          HOOK method: called if a session demands to auto connect the session profile.
     377
     378          """
     379          self.logger('HOOK_profile_auto_connect: profile ,,%s'' wants to be auto-connected to the X2Go server.' % profile_name, loglevel=log.loglevel_WARN)
     380
     381 -    def HOOK_session_startup_failed(self, profile_name='UNKNOWN'):
     382          """\
     383          HOOK method: called if the startup of a session failed.
     384
     385          """
     386          self.logger('HOOK_session_startup_failed: session startup for session profile ,,%s'' failed.' % profile_name, loglevel=log.loglevel_WARN)
     387
     388 -    def HOOK_list_desktops_timeout(self, profile_name='UNKNOWN'):
     389          """\
     390          HOOK method: called if the x2golistdesktops command generates a timeout due to long execution time.
     391
     392          """
     393          self.logger('HOOK_list_desktops_timeout: the server-side x2golistdesktops command for session profile %s took too long to return results. This can happen from time to time, please try again.' % profile_name, loglevel=log.loglevel_WARN)
     394
     395 -    def HOOK_no_such_desktop(self, profile_name='UNKNOWN', desktop='UNKNOWN'):
     396          """\
     397          HOOK method: called if it is tried to connect to a (seen before) sharable desktop that's not available (anymore).
     398
     399          """
     400          self.logger('HOOK_no_such_desktop: the desktop %s (via session profile %s) is not available for sharing (anymore).' % (desktop, profile_name), loglevel=log.loglevel_WARN)
     401
     402 -    def HOOK_no_known_xserver_found(self):
     403          """\
     404          HOOK method: called if the Python X2Go module could not find any usable XServer
     405          application to start. You will not be able to start X2Go sessions without an XServer.
     406
     407          """
     408          self.logger('the Python X2Go module could not find any usable XServer application, you will not be able to start X2Go sessions without an XServer', loglevel=log.loglevel_WARN)
     409
     410 -    def HOOK_open_print_dialog(self, profile_name='UNKNOWN', session_name='UNKNOWN'):
     411          """\
     412          HOOK method: called if an incoming print job has been detected by L{X2GoPrintQueue} and a print dialog box is
     413          requested.
     414
     415          @param profile_name: profile name of session that called this hook method
     416          @type profile_name: C{str}
     417          @param session_name: X2Go session name
     418          @type session_name: C{str}
     419
     420          """
     421          self.logger('HOOK_open_print_dialog: incoming print job detected by X2GoClient hook method', loglevel=log.loglevel_WARN)
     422
     423 -    def HOOK_no_such_command(self, cmd, profile_name='UNKNOWN', session_name='UNKNOWN'):
     424          """\
     425          HOOK: the command <cmd> is not available on the connected X2Go server.
     426
     427          @param cmd: the command that failed
     428          @type cmd: C{str}
     429          @param profile_name: profile name of session that called this hook method
     430          @type profile_name: C{str}
     431          @param session_name: X2Go session name
     432          @type session_name: C{str}
     433
     434          """
     435          self.logger('HOOK_no_such_command: the command %s is not available for X2Go server (profile: %s, session: %s)' % (cmd, profile_name, session_name), loglevel=log.loglevel_WARN)
     436
     437 -    def HOOK_open_mimebox_saveas_dialog(self, filename, profile_name='UNKNOWN', session_name='UNKNOWN'):
     438          """\
     439          HOOK method: called on detection of an incoming MIME box job ,,<filename>''.
     440
     441          @param filename: file name of the incoming MIME box job
     442          @type filename: C{str}
     443          @param profile_name: profile name of session that called this hook method
     444          @type profile_name: C{str}
     445          @param session_name: X2Go session name
     446          @type session_name: C{str}
     447
     448          """
     449          self.logger('HOOK_open_mimebox_saveas_dialog: incoming MIME box job ,, %s'' detected by X2GoClient hook method' % filename, loglevel=log.loglevel_WARN)
     450
     451 -    def HOOK_printaction_error(self, filename, profile_name='UNKNOWN', session_name='UNKNOWN', err_msg='GENERIC_ERROR', printer=None):
     452          """\
     453          HOOK method: called if an incoming print job caused an error.
     454
     455          @param filename: file name of the print job that failed
     456          @type filename: C{str}
     457          @param profile_name: profile name of session that called this hook method
     458          @type profile_name: C{str}
     459          @param session_name: X2Go session name
     460          @type session_name: C{str}
     461          @param err_msg: if available, an appropriate error message
     462          @type err_msg: C{str}
     463          @param printer: if available, the printer name the print job failed on
     464          @type printer: C{str}
     465
     466          """
     467          if printer:
     468              self.logger('HOOK_printaction_error: incoming print job ,, %s'' on printer %s caused error: %s' % (filename, printer, err_msg), loglevel=log.loglevel_ERROR)
     469          else:
     470              self.logger('HOOK_printaction_error: incoming print job ,, %s'' caused error: %s' % (filename, err_msg), loglevel=log.loglevel_ERROR)
     471
     472 -    def HOOK_check_host_dialog(self, profile_name='UNKNOWN', host='UNKNOWN', port=22, fingerprint='no fingerprint', fingerprint_type='UNKNOWN'):
     473          """\
     474          HOOK method: called if a host check is requested. This hook has to either return C{True} (default) or C{False}.
     475
     476          @param profile_name: profile name of session that called this hook method
     477          @type profile_name: C{str}
     478          @param host: SSH server name to validate
     479          @type host: C{str}
     480          @param port: SSH server port to validate
     481          @type port: C{int}
     482          @param fingerprint: the server's fingerprint
     483          @type fingerprint: C{str}
     484          @param fingerprint_type: finger print type (like RSA, DSA, ...)
     485          @type fingerprint_type: C{str}
     486
     487          @return: if host validity is verified, this hook method should return C{True}
     488          @rtype: C{bool}
     489
     490          """
     491          self.logger('HOOK_check_host_dialog: host check requested for session profile %s: Automatically adding host [%s]:%s with fingerprint: ,,%s\'\' as a known host.' % (profile_name, host, port, fingerprint), loglevel=log.loglevel_WARN)
     492          # this HOOK has to return either True (accept host connection) or False (deny host conection)
     493          return True
     494
     495 -    def HOOK_on_control_session_death(self, profile_name):
     496          """\
     497          HOOK method: called if a control session (server connection) has unexpectedly encountered a failure.
     498
     499          @param profile_name: profile name of session that called this hook method
     500          @type profile_name: C{str}
     501
     502          """
     503          self.logger('HOOK_on_control_session_death: the control session of profile %s has died unexpectedly' % profile_name, loglevel=log.loglevel_WARN)
     504
     505 -    def HOOK_pulseaudio_not_supported_in_RDPsession(self):
     506          """HOOK method: called if trying to run the Pulseaudio daemon within an RDP session, which is not supported by Pulseaudio."""
     507          self.logger('HOOK_pulseaudio_not_supported_in_RDPsession: The pulseaudio daemon cannot be used within RDP sessions', loglevel=log.loglevel_WARN)
     508
     509 -    def HOOK_pulseaudio_server_startup_failed(self):
     510          """HOOK method: called if the Pulseaudio daemon startup failed."""
     511          self.logger('HOOK_pulseaudio_server_startup_failed: The pulseaudio daemon could not be started', loglevel=log.loglevel_ERROR)
     512
     513 -    def HOOK_pulseaudio_server_died(self):
     514          """HOOK method: called if the Pulseaudio daemon has died away unexpectedly."""
     515          self.logger('HOOK_pulseaudio_server_died: The pulseaudio daemon has just died away', loglevel=log.loglevel_ERROR)
     516
     517 -    def HOOK_on_sound_tunnel_failed(self, profile_name='UNKNOWN', session_name='UNKNOWN'):
     518          """\
     519          HOOK method: called if a sound tunnel setup failed.
     520
     521          @param profile_name: profile name of session that called this hook method
     522          @type profile_name: C{str}
     523          @param session_name: X2Go session name
     524          @type session_name: C{str}
     525
     526          """
     527          self.logger('HOOK_on_sound_tunnel_failed: setting up X2Go sound for %s (%s) support failed' % (profile_name, session_name))
     528
     529 -    def HOOK_rforward_request_denied(self, profile_name='UNKNOWN', session_name='UNKNOWN', server_port=0):
     530          """\
     531          HOOK method: called if a reverse port forwarding request has been denied.
     532
     533          @param profile_name: profile name of session that called this hook method
     534          @type profile_name: C{str}
     535          @param session_name: X2Go session name
     536          @type session_name: C{str}
     537          @param server_port: remote server port (starting point of reverse forwarding tunnel)
     538          @type server_port: C{str}
     539
     540          """
     541          self.logger('TCP port (reverse) forwarding request for session %s to server port %s has been denied by the X2Go server. This is a common issue with SSH, it might help to restart the X2Go server\'s SSH daemon.' % (session_name, server_port), loglevel=log.loglevel_WARN)
     542
     543 -    def HOOK_forwarding_tunnel_setup_failed(self, profile_name='UNKNOWN', session_name='UNKNOWN', chain_host='UNKNOWN', chain_port=0):
     544          """\
     545          HOOK method: called if a port forwarding tunnel setup failed.
     546
     547          @param profile_name: profile name of session that called this hook method
     548          @type profile_name: C{str}
     549          @param session_name: X2Go session name
     550          @type session_name: C{str}
     551          @param chain_host: hostname of chain host (forwarding tunnel end point)
     552          @type chain_host: C{str}
     553          @param chain_port: port of chain host (forwarding tunnel end point)
     554          @type chain_port: C{str}
     555
     556          """
     557          self.logger('Forwarding tunnel request to [%s]:%s for session %s (%s) was denied by remote X2Go/SSH server. Session startup failed.' % (chain_host, chain_port, session_name, profile_name), loglevel=log.loglevel_ERROR)
     558
     559 -    def HOOK_on_session_has_started_by_me(self, session_uuid='UNKNOWN', profile_name='UNKNOWN', session_name='UNKNOWN'):
     560          """\
     561          HOOK method: called if a session has been started by this instance of L{X2GoClient}.
     562
     563          @param session_uuid: unique session identifier of the calling session
     564          @type session_uuid: C{str}
     565          @param profile_name: profile name of session that called this hook method
     566          @type profile_name: C{str}
     567          @param session_name: X2Go session name
     568          @type session_name: C{str}
     569
     570          """
     571          self.logger('HOOK_on_session_has_started_by_me (session_uuid: %s, profile_name: %s): a new session %s has been started by this application' %  (session_uuid, profile_name, session_name), loglevel=log.loglevel_NOTICE)
     572
     573 -    def HOOK_on_session_has_started_by_other(self, session_uuid='UNKNOWN', profile_name='UNKNOWN', session_name='UNKNOWN'):
     574          """\
     575          HOOK method: called if a session has been started by another C{x2goclient}.
     576
     577          @param session_uuid: unique session identifier of the calling session
     578          @type session_uuid: C{str}
     579          @param profile_name: profile name of session that called this hook method
     580          @type profile_name: C{str}
     581          @param session_name: X2Go session name
     582          @type session_name: C{str}
     583
     584          """
     585          self.logger('HOOK_on_session_has_started (session_uuid: %s, profile_name: %s): a new session %s has started been started by other application' %  (session_uuid, profile_name, session_name), loglevel=log.loglevel_NOTICE)
     586
     587 -    def HOOK_on_session_has_resumed_by_me(self, session_uuid='UNKNOWN', profile_name='UNKNOWN', session_name='UNKNOWN'):
     588          """\
     589          HOOK method: called if a session has been resumed by this instance of L{X2GoClient}.
     590
     591          @param session_uuid: unique session identifier of the calling session
     592          @type session_uuid: C{str}
     593          @param profile_name: profile name of session that called this hook method
     594          @type profile_name: C{str}
     595          @param session_name: X2Go session name
     596          @type session_name: C{str}
     597
     598          """
     599          self.logger('HOOK_on_session_has_resumed_by_me (session_uuid: %s, profile_name: %s): suspended session %s has been resumed by this application' %  (session_uuid, profile_name, session_name), loglevel=log.loglevel_NOTICE)
     600
     601 -    def HOOK_on_session_has_resumed_by_other(self, session_uuid='UNKNOWN', profile_name='UNKNOWN', session_name='UNKNOWN'):
     602          """\
     603          HOOK method: called if a session has been resumed by another C{x2goclient}.
     604
     605          @param session_uuid: unique session identifier of the calling session
     606          @type session_uuid: C{str}
     607          @param profile_name: profile name of session that called this hook method
     608          @type profile_name: C{str}
     609          @param session_name: X2Go session name
     610          @type session_name: C{str}
     611
     612          """
     613          self.logger('HOOK_on_session_has_resumed_by_other (session_uuid: %s, profile_name: %s): suspended session %s has been resumed by other application' %  (session_uuid, profile_name, session_name), loglevel=log.loglevel_NOTICE)
     614
     615 -    def HOOK_on_found_session_running_after_connect(self, session_uuid='UNKNOWN', profile_name='UNKNOWN', session_name='UNKNOWN'):
     616          """\
     617          HOOK method: called after server connect if an already running session has been found.
     618
     619          @param session_uuid: unique session identifier of the calling session
     620          @type session_uuid: C{str}
     621          @param profile_name: profile name of session that called this hook method
     622          @type profile_name: C{str}
     623          @param session_name: X2Go session name
     624          @type session_name: C{str}
     625
     626          """
     627          self.logger('HOOK_found_session_running_after_connect (session_uuid: %s, profile_name: %s): running session %s has been found after connecting to session profile %s' %  (session_uuid, profile_name, session_name, profile_name), loglevel=log.loglevel_NOTICE)
     628
     629 -    def HOOK_on_session_has_been_suspended(self, session_uuid='UNKNOWN', profile_name='UNKNOWN', session_name='UNKNOWN'):
     630          """\
     631          HOOK method: called if a session has been suspended by this instance of L{X2GoClient}.
     632
     633          @param session_uuid: unique session identifier of the calling session
     634          @type session_uuid: C{str}
     635          @param profile_name: profile name of session that called this hook method
     636          @type profile_name: C{str}
     637          @param session_name: X2Go session name
     638          @type session_name: C{str}
     639
     640          """
     641          self.logger('HOOK_on_session_has_been_suspended (session_uuid: %s, profile_name: %s): session %s has been suspended' %  (session_uuid, profile_name, session_name), loglevel=log.loglevel_NOTICE)
     642
     643 -    def HOOK_on_session_has_terminated(self, session_uuid='UNKNOWN', profile_name='UNKNOWN', session_name='UNKNOWN'):
     644          """\
     645          HOOK method: called if a session has been suspended by another C{x2goclient}.
     646
     647          @param session_uuid: unique session identifier of the calling session
     648          @type session_uuid: C{str}
     649          @param profile_name: profile name of session that called this hook method
     650          @type profile_name: C{str}
     651          @param session_name: X2Go session name
     652          @type session_name: C{str}
     653
     654          """
     655          self.logger('HOOK_on_session_has_terminated (session_uuid: %s, profile_name: %s): session %s has terminated' % (session_uuid, profile_name, session_name), loglevel=log.loglevel_NOTICE)
     656
     657 -    def HOOK_printing_not_available(self, profile_name='UNKNOWN', session_name='UNKNOWN'):
     658          """\
     659          HOOK method: called if X2Go client-side printing is not available.
     660
     661          @param profile_name: profile name of session that called this hook method
     662          @type profile_name: C{str}
     663          @param session_name: X2Go session name
     664          @type session_name: C{str}
     665
     666          """
     667          self.logger('HOOK_foldersharing_not_available: X2Go\'s client-side printing feature is not available with this session (%s) of profile %s.' % (session_name, profile_name), loglevel=log.loglevel_WARN)
     668
     669 -    def HOOK_mimebox_not_available(self, profile_name='UNKNOWN', session_name='UNKNOWN'):
     670          """\
     671          HOOK method: called if the X2Go MIME box is not available.
     672
     673          @param profile_name: profile name of session that called this hook method
     674          @type profile_name: C{str}
     675          @param session_name: X2Go session name
     676          @type session_name: C{str}
     677
     678          """
     679          self.logger('HOOK_mimebox_not_available: X2Go\'s MIME box feature is not available with this session (%s) of profile %s.' % (session_name, profile_name), loglevel=log.loglevel_WARN)
     680
     681 -    def HOOK_foldersharing_not_available(self, profile_name='UNKNOWN', session_name='UNKNOWN'):
     682          """\
     683          HOOK method: called if X2Go client-side folder-sharing is not available.
     684
     685          @param profile_name: profile name of session that called this hook method
     686          @type profile_name: C{str}
     687          @param session_name: X2Go session name
     688          @type session_name: C{str}
     689
     690          """
     691          self.logger('HOOK_foldersharing_not_available: X2Go\'s client-side folder sharing feature is not available with this session (%s) of profile %s.' % (session_name, profile_name), loglevel=log.loglevel_WARN)
     692
     693 -    def HOOK_sshfs_not_available(self, profile_name='UNKNOWN', session_name='UNKNOWN'):
     694          """\
     695          HOOK method: called if the X2Go server denies SSHFS access.
     696
     697          @param profile_name: profile name of session that called this hook method
     698          @type profile_name: C{str}
     699          @param session_name: X2Go session name
     700          @type session_name: C{str}
     701
     702          """
     703          self.logger('HOOK_sshfs_not_available: the remote X2Go server (%s) denies SSHFS access for session %s. This will result in client-side folder sharing, printing and the MIME box feature being unavailable' % (session_name, profile_name), loglevel=log.loglevel_WARN)
     704
     705 -    def _detect_backend_classes(self):
     706          """\
     707          Detect backend classes from the command line
     708
     709          @raise X2GoBackendException: if a given backend name is unknown."
     710
     711          """
     712          # CONTROL session backend
     713          if type(self.control_backend) is types.StringType:
     714              try:
     715                  _classname = _BACKENDS_CONTROLSESSION[self.control_backend]
     716              except KeyError:
     717                  if self.control_backend in _BACKENDS_CONTROLSESSION.values():
     718                     _classname = self.control_backend
     719                  else:
     720                      raise x2go_exceptions.X2GoBackendException('unknown control session backend name %s' % self.control_backend)
     721              self.control_backend = eval('control.%s' % _classname)
     722
     723          # TERMINAL session backend
     724          if type(self.terminal_backend) is types.StringType:
     725              try:
     726                  _classname = _BACKENDS_TERMINALSESSION[self.terminal_backend]
     727              except KeyError:
     728                  if self.terminal_backend in _BACKENDS_TERMINALSESSION.values():
     729                     _classname = self.terminal_backend
     730                  else:
     731                      raise x2go_exceptions.X2GoBackendException('unknown terminal session backend name %s' % self.terminal_backend)
     732              self.terminal_backend = eval('terminal.%s' % _classname)
     733
     734          # PROXY session backend
     735          if type(self.proxy_backend) is types.StringType:
     736              try:
     737                  _classname = _BACKENDS_PROXY[self.proxy_backend]
     738              except KeyError:
     739                  if self.proxy_backend in _BACKENDS_PROXY.values():
     740                     _classname = self.proxy_backend
     741                  else:
     742                      raise x2go_exceptions.X2GoBackendException('unknown proxy backend name %s' % self.proxy_backend)
     743              self.proxy_backend = eval('proxy.%s' % _classname)
     744
     745          # server session info backend
     746          if type(self.info_backend) is types.StringType:
     747              try:
     748                  _classname = _BACKENDS_SERVERSESSIONINFO[self.info_backend]
     749              except KeyError:
     750                  if self.info_backend in _BACKENDS_SERVERSESSIONINFO.values():
     751                     _classname = self.info_backend
     752                  else:
     753                      raise x2go_exceptions.X2GoBackendException('unknown server session info backend name %s' % self.info_backend)
     754              self.info_backend = eval('info.%s' % _classname)
     755
     756          # server session list backend
     757          if type(self.list_backend) is types.StringType:
     758              try:
     759                  _classname = _BACKENDS_SERVERSESSIONLIST[self.list_backend]
     760              except KeyError:
     761                  if self.list_backend in _BACKENDS_SERVERSESSIONLIST.values():
     762                     _classname = self.list_backend
     763                  else:
     764                      raise x2go_exceptions.X2GoBackendException('unknown server session info backend name %s' % self.list_backend)
     765              self.list_backend = eval('info.%s' % _classname)
     766
     767          # session profiles backend
     768          if type(self.profiles_backend) is types.StringType:
     769              try:
     770                  _classname = _BACKENDS_SESSIONPROFILES[self.profiles_backend]
     771              except KeyError:
     772                  if self.profiles_backend in _BACKENDS_SESSIONPROFILES.values():
     773                     _classname = self.profiles_backend
     774                  else:
     775                      raise x2go_exceptions.X2GoBackendException('unknown session profiles backend name %s' % self.profiles_backend)
     776              self.profiles_backend = eval('profiles.%s' % _classname)
     777
     778          # client settings backend
     779          if type(self.settings_backend) is types.StringType:
     780              try:
     781                  _classname = _BACKENDS_CLIENTSETTINGS[self.settings_backend]
     782              except KeyError:
     783                  if self.settings_backend in _BACKENDS_CLIENTSETTINGS.values():
     784                     _classname = self.settings_backend
     785                  else:
     786                      raise x2go_exceptions.X2GoBackendException('unknown client settings backend name %s' % self.settings_backend)
     787              self.settings_backend = eval('settings.%s' % _classname)
     788
     789          # client printing backend
     790          if type(self.printing_backend) is types.StringType:
     791              try:
     792                  _classname = _BACKENDS_CLIENTPRINTING[self.printing_backend]
     793              except KeyError:
     794                  if self.printing_backend in _BACKENDS_CLIENTPRINTING.values():
     795                     _classname = self.printing_backend
     796                  else:
     797                      raise x2go_exceptions.X2GoBackendException('unknown client printing backend name %s' % self.printing_backend)
     798              self.printing_backend = eval('printing.%s' % _classname)
     799
     800 -    def get_client_rootdir(self):
     801          """\
     802          Retrieve the settings root directory of this L{X2GoClient} instance.
     803
     804          @return: X2Go client root directory
     805          @rtype: C{str}
     806          """
     807          return os.path.normpath(self.client_rootdir)
     808      __get_client_rootdir = get_client_rootdir
     809
     810      @property
     811 -    def has_custom_client_rootdir(self):
     812          """\
     813          Does this L{X2GoClient} instance have a customized root dir path?
     814          Equals C{True} in case it has.
     815
     816          """
     817          return self._has_custom_client_rootdir
     818      __has_custom_client_rootdir = has_custom_client_rootdir
     819
     820 -    def get_sessions_rootdir(self):
     821          """\
     822          Retrieve the sessions root directory of this L{X2GoClient} instance.
     823
     824          @return: X2Go sessions root directory
     825          @rtype: C{str}
     826          """
     827          return os.path.normpath(self.sessions_rootdir)
     828      __get_sessions_rootdir = get_sessions_rootdir
     829
     830 -    def get_ssh_rootdir(self):
     831          """\
     832          Retrieve the SSH client root dir used with this L{X2GoClient} instance.
     833
     834          @return: SSH client root directory
     835          @rtype: C{str}
     836          """
     837          return os.path.normpath(self.ssh_rootdir)
     838      __get_ssh_rootdir = get_ssh_rootdir
     839
     840 -    def get_client_username(self):
     841          """\
     842          Query the local user's username (i.e. the user running the X2Go client).
     843
     844          @return: the local username this L{X2GoClient} instance runs as
     845          @rtype: C{str}
     846
     847          """
     848          return _CURRENT_LOCAL_USER
     849      __get_client_username = get_client_username
     850
     851 -    def register_all_session_profiles(self, return_objects=False):
     852          """\
     853          Register all session profiles found in the C{sessions} configuration node
     854          as potential X2Go sessions.
     855
     856          @param return_objects: if set to C{True} this methods returns a list of L{X2GoSession}
     857              instances, otherwise a list of session UUIDs representing the corresponding
     858              registered sessions is returned
     859          @type return_objects: C{bool}
     860
     861          @return: a Python dictionary containing one registered session for each available session profile
     862              configuration, whereas the profile names are used as dictionary keys and L{X2GoSession}
     863              instances as their values
     864          @rtype: C{list}
     865
     866          """
     867          sessions = {}
     868          for profile_name in self.session_profiles.profile_names:
     869              _obj = self._X2GoClient__register_session(profile_name=profile_name, return_object=True)
     870              sessions[_obj.get_profile_name()] = _obj
     871          return sessions
     872      __register_all_session_profiles = register_all_session_profiles
     873
     874 -    def register_session(self, server=None, profile_id=None, profile_name=None, session_name=None,
     875                           allow_printing=False,
     876                           allow_share_local_folders=False, share_local_folders=[],
     877                           allow_mimebox=False, mimebox_extensions=[], mimebox_action='OPEN',
     878                           add_to_known_hosts=False, known_hosts=None, forward_sshagent=False,
     879                           proxy_options={},
     880                           return_object=False, **kwargs):
     881          """\
     882          Register a new L{X2GoSession}. Within one L{X2GoClient}
     883          instance you can manage several L{X2GoSession} instances on serveral
     884          remote X2Go servers under different user names.
     885
     886          These sessions can be instantiated by passing direct L{X2GoSession}
     887          parameters to this method or by specifying the name of an existing session profile
     888          (as found in the L{X2GoClient}'s C{sessions} configuration node.
     889
     890          A session profile is a pre-defined set of session options stored in a sessions
     891          profile node (e.g. a configuration file). With the FILE backend such session
     892          profiles are stored as a file (by default: C{~/.x2goclient/sessions} or globally (for all users on the
     893          client) in C{/etc/x2goclient/sessions}).
     894
     895          Python X2Go also supports starting multiple X2Go sessions for the same
     896          session profile simultaneously.
     897
     898          This method (L{X2GoClient.register_session()}) accepts a similar set of parameters
     899          as the L{X2GoSession} constructor itself. For a complete set of session options refer
     900          there.
     901
     902          Alternatively, you can also pass a profile name or a profile id
     903          to this method. If you do this, Python X2Go tries to find the specified session
     904          in the C{sessions} configuration node and then derives the necessary session parameters
     905          from the session profile configuration. Additional L{X2GoSession} parameters can
     906          also be passed to this method---they will override the option values retrieved from
     907          the session profile.
     908
     909          @param server: hostname of the remote X2Go server
     910          @type server: C{str}
     911          @param profile_id: id (config section name) of a session profile to load
     912              from your session config
     913          @type profile_id: C{str}
     914          @param profile_name: name of a session profile to load from your session
     915              config
     916          @type profile_name: C{str}
     917          @param allow_printing: enable X2Go printing support for the to-be-registered X2Go session
     918          @type allow_printing: C{bool}
     919          @param allow_share_local_folders: set local folder sharing to enabled/disabled
     920          @type allow_share_local_folders: C{bool}
     921          @param share_local_folders: a list of local folders (as strings) to be shared directly
     922              after session start up
     923          @type share_local_folders: C{list}
     924          @param allow_mimebox: enable X2Go MIME box support for the to-be-registered X2Go session
     925          @type allow_mimebox: C{bool}
     926          @param mimebox_extensions: MIME box support is only allowed for the given file extensions
     927          @type mimebox_extensions: C{list}
     928          @param mimebox_action: MIME box action to use on incoming MIME job files
     929          @type mimebox_action: C{str}
     930          @param add_to_known_hosts: add unknown host keys to the C{known_hosts} file and accept the connection
     931              automatically
     932          @type add_to_known_hosts: C{bool}
     933          @param known_hosts: full path to C{known_hosts} file
     934          @type known_hosts: C{str}
     935          @param forward_sshagent: forward SSH agent authentication requests to the X2Go client-side
     936          @type forward_sshagent: C{bool}
     937          @param proxy_options: a set of very C{X2GoProxy*} backend specific options; any option that is not known
     938              to the C{X2GoProxy*} backend will simply be ignored
     939          @type proxy_options: C{dict}
     940          @param return_object: normally this method returns a unique session UUID. If
     941              C{return_object} is set to C{True} an X2GoSession object will be returned
     942              instead
     943          @type return_object: C{bool}
     944          @param kwargs: any option that is also valid for the L{X2GoSession} constructor
     945          @type kwargs: C{dict}
     946
     947          @return: a unique identifier (UUID) for the newly registered X2Go session (or an
     948              X2GoSession object if C{return_object} is set to True
     949          @rtype: C{str}
     950
     951          """
     952          # detect profile name and profile id properly
     953          if profile_id and self.session_profiles.has_profile_id(profile_id):
     954              _p = profile_id
     955          elif profile_name and self.session_profiles.has_profile_name(profile_name):
     956              _p = profile_name
     957          else:
     958              _p = None
     959
     960          if _p:
     961
     962              _profile_id = self.session_profiles.check_profile_id_or_name(_p)
     963              _profile_name = self.session_profiles.to_profile_name(_profile_id)
     964
     965          # test if session_name has already been registered. If yes, return it immediately.
     966          if type(session_name) is types.StringType:
     967              _retval = self.get_session_of_session_name(session_name, return_object=return_object, match_profile_name=profile_name)
     968              if _retval is not None:
     969                  return _retval
     970
     971          if known_hosts is None:
     972              known_hosts = os.path.join(_LOCAL_HOME, self.ssh_rootdir, 'known_hosts')
     973
     974
     975          if _p:
     976
     977              _params = self.session_profiles.to_session_params(profile_id=_profile_id)
     978              del _params['profile_name']
     979
     980              # override any available session parameter passed to this method
     981              for k in _params.keys():
     982                  if k in kwargs.keys():
     983                      _params[k] = kwargs[k]
     984
     985              server = _params['server']
     986              del _params['server']
     987              _params['client_instance'] = self
     988
     989          else:
     990              if server is None:
     991                  return None
     992              _profile_id = utils._genSessionProfileId()
     993              _profile_name = profile_name or sys.argv[0]
     994              _params = kwargs
     995              _params['printing'] = allow_printing
     996              _params['allow_share_local_folders'] = allow_share_local_folders
     997              _params['share_local_folders'] = share_local_folders
     998              _params['allow_mimebox'] = allow_mimebox
     999              _params['mimebox_extensions'] = mimebox_extensions
    1000              _params['mimebox_action'] = mimebox_action
    1001              _params['client_instance'] = self
    1002              _params['proxy_options'] = proxy_options
    1003              _params['forward_sshagent'] = forward_sshagent
    1004
    1005          session_uuid = self.session_registry.register(server=server,
    1006                                                        profile_id=_profile_id, profile_name=_profile_name,
    1007                                                        session_name=session_name,
    1008                                                        control_backend=self.control_backend,
    1009                                                        terminal_backend=self.terminal_backend,
    1010                                                        info_backend=self.info_backend,
    1011                                                        list_backend=self.list_backend,
    1012                                                        proxy_backend=self.proxy_backend,
    1013                                                        settings_backend=self.settings_backend,
    1014                                                        printing_backend=self.printing_backend,
    1015                                                        client_rootdir=self.client_rootdir,
    1016                                                        sessions_rootdir=self.sessions_rootdir,
    1017                                                        ssh_rootdir=self.ssh_rootdir,
    1018                                                        keep_controlsession_alive=True,
    1019                                                        add_to_known_hosts=add_to_known_hosts,
    1020                                                        known_hosts=known_hosts,
    1021                                                        **_params)
    1022
    1023          self.logger('initializing X2Go session...', log.loglevel_NOTICE, tag=self._logger_tag)
    1024          if return_object:
    1025              return self.session_registry(session_uuid)
    1026          else:
    1027              return session_uuid
    1028      __register_session = register_session
    1029
    1030      ###
    1031      ### WRAPPER METHODS FOR X2GoSessionRegistry objects
    1032      ###
    1033
    1034 -    def get_session_summary(self, session_uuid):
    1035          """\
    1036          Retrieves a Python dictionary, containing a short session summary (session status, names, etc.)
    1037
    1038          @param session_uuid: the X2Go session's UUID registry hash
    1039          @type session_uuid: C{str}
    1040
    1041          """
    1042          return self.session_registry.session_summary(session_uuid)
    1043      __get_session_summary = get_session_summary
    1044
    1045      ###
    1046      ### WRAPPER METHODS FOR X2GoSession objects
    1047      ###
    1048
    1049 -    def get_session_username(self, session_uuid):
    1050          """\
    1051          After an L{X2GoSession} has been set up you can query the
    1052          username that the remote sessions runs as.
    1053
    1054          @param session_uuid: the X2Go session's UUID registry hash
    1055          @type session_uuid: C{str}
    1056
    1057          @return: the remote username the X2Go session runs as
    1058          @rtype: C{str}
    1059
    1060          """
    1061          return self.session_registry(session_uuid).get_username()
    1062      __get_session_username = get_session_username
    1063
    1064 -    def get_session_server_peername(self, session_uuid):
    1065          """\
    1066          After a session has been set up you can query the
    1067          hostname of the host the session is connected to (or
    1068          about to connect to).
    1069
    1070          @param session_uuid: the X2Go session's UUID registry hash
    1071          @type session_uuid: C{str}
    1072
    1073          @return: the host an X2Go session is connected to
    1074              (as an C{(addr,port)} tuple)
    1075          @rtype: tuple
    1076
    1077          """
    1078          return self.session_registry(session_uuid).get_server_peername()
    1079      __get_session_server_peername = get_session_server_peername
    1080
    1081 -    def get_session_server_hostname(self, session_uuid):
    1082          """\
    1083          Retrieve the server hostname as provided by the calling
    1084          application (e.g. like it has been specified in the session
    1085          profile).
    1086
    1087          @param session_uuid: the X2Go session's UUID registry hash
    1088          @type session_uuid: C{str}
    1089
    1090          @return: the hostname for the queried X2Go session as specified
    1091              by the calling application
    1092          @rtype: str
    1093
    1094          """
    1095          return self.session_registry(session_uuid).get_server_hostname()
    1096      __get_session_server_hostname = get_session_server_hostname
    1097
    1098 -    def get_session(self, session_uuid):
    1099          """\
    1100          Retrieve the complete L{X2GoSession} object that has been
    1101          registered under the given session registry hash.
    1102
    1103          @param session_uuid: the X2Go session's UUID registry hash
    1104          @type session_uuid: C{str}
    1105
    1106          @return: the L{X2GoSession} instance
    1107          @rtype: obj
    1108
    1109          """
    1110          return self.session_registry(session_uuid)
    1111      __get_session = get_session
    1112      with_session = __get_session
    1113      """Alias for L{get_session()}."""
    1114
    1115 -    def get_session_of_session_name(self, session_name, return_object=False, match_profile_name=None):
    1116          """\
    1117          Retrieve session UUID or L{X2GoSession} for session name
    1118          <session_name> from the session registry.
    1119
    1120          @param session_name: the X2Go session's UUID registry hash
    1121          @type session_name: C{str}
    1122          @param return_object: session UUID hash or L{X2GoSession} instance wanted?
    1123          @type return_object: C{bool}
    1124          @param match_profile_name: only return sessions that match this profile name
    1125          @type match_profile_name: C{str}
    1126
    1127          @return: the X2Go session's UUID registry hash or L{X2GoSession} instance
    1128          @rtype: C{str} or L{X2GoSession} instance
    1129
    1130          """
    1131          try:
    1132              return self.session_registry.get_session_of_session_name(session_name=session_name, return_object=return_object, match_profile_name=match_profile_name)
    1133          except x2go_exceptions.X2GoSessionRegistryException:
    1134              return None
    1135      __get_session_of_session_name = get_session_of_session_name
    1136
    1137 -    def get_session_name(self, session_uuid):
    1138          """\
    1139          Retrieve the server-side X2Go session name for the session that has
    1140          been registered under C{session_uuid}.
    1141
    1142          @param session_uuid: the X2Go session's UUID registry hash
    1143          @type session_uuid: C{str}
    1144
    1145          @return: X2Go session name
    1146          @rtype: C{str}
    1147
    1148          """
    1149          return self.session_registry(session_uuid).get_session_name()
    1150      __get_session_name = get_session_name
    1151
    1152 -    def get_session_info(self, session_uuid):
    1153          """\
    1154          Retrieve the server-side X2Go session information object for the session that has
    1155          been registered under C{session_uuid}.
    1156
    1157          @param session_uuid: the X2Go session's UUID registry hash
    1158          @type session_uuid: C{str}
    1159
    1160          @return: X2Go session info
    1161          @rtype: C{obj}
    1162
    1163          """
    1164          return self.session_registry(session_uuid).get_session_info()
    1165      __get_session_info = get_session_info
    1166
    1167 -    def get_published_applications(self, session_uuid=None, profile_name=None, lang=None, refresh=False, raw=False, very_raw=False, max_no_submenus=_PUBAPP_MAX_NO_SUBMENUS):
    1168          """\
    1169          Retrieve the server-side X2Go published applications menu for the session
    1170          registered under C{session_uuid} or for profile name C{profile_name}.
    1171
    1172          @param session_uuid: the X2Go session's UUID registry hash
    1173          @type session_uuid: C{str}
    1174          @param profile_name: a valid session profile name
    1175          @type profile_name: C{str}
    1176
    1177          @return: a representative of the published applications menu tree
    1178          @rtype: C{dict}
    1179
    1180          """
    1181          if session_uuid is None and profile_name:
    1182              _session_uuids = self._X2GoClient__client_pubapp_sessions_of_profile_name(profile_name, return_objects=False)
    1183              if len(_session_uuids): session_uuid = _session_uuids[0]
    1184          if session_uuid:
    1185              try:
    1186                  if self.session_registry(session_uuid).is_published_applications_provider():
    1187                      return self.session_registry(session_uuid).get_published_applications(lang=lang, refresh=refresh, raw=raw, very_raw=False, max_no_submenus=max_no_submenus)
    1188              except x2go_exceptions.X2GoSessionRegistryException:
    1189                  pass
    1190          else:
    1191              self.logger('Cannot find a terminal session for profile ,,%s\'\' that can be used to query a published applications menu tree' % profile_name, loglevel=log.loglevel_INFO)
    1192          return None
    1193      __get_published_applications = get_published_applications
    1194      profile_get_published_applications = get_published_applications
    1195      __profile_get_published_applications = get_published_applications
    1196
    1197 -    def set_session_username(self, session_uuid, username):
    1198          """\
    1199          Set the session username for the L{X2GoSession} that has been registered under C{session_uuid}.
    1200          This can be helpful for modifying user credentials during an authentication phase.
    1201
    1202          @param session_uuid: the X2Go session's UUID registry hash
    1203          @type session_uuid: C{str}
    1204          @param username: new user name to be used for session authentication
    1205          @type username: C{str}
    1206
    1207          @return: return C{True} on success
    1208          @rtype: C{bool}
    1209
    1210          """
    1211          return self.session_registry(session_uuid).set_username(username=username)
    1212      __set_session_username = set_session_username
    1213
    1214 -    def check_session_host(self, session_uuid):
    1215          """\
    1216          Provide a mechanism to evaluate the validity of an X2Go server host.
    1217
    1218          @param session_uuid: the X2Go session's UUID registry hash
    1219          @type session_uuid: C{str}
    1220
    1221          @return: return C{True} if host validation has been successful.
    1222          @rtype: C{bool}
    1223
    1224          """
    1225          return self.session_registry(session_uuid).check_host()
    1226      __check_session_host = check_session_host
    1227
    1228 -    def session_reuses_sshproxy_authinfo(self, session_uuid):
    1229          """\
    1230          Check if session with unique identifier <session_uuid> is configured to re-use the X2Go session's
    1231          password / key for proxy authentication, as well.
    1232
    1233          @return: returns C{True} if the session is configured to re-use session password / key for proxy authentication
    1234          @rtype: C{bool}
    1235          """
    1236          return self.session_registry(session_uuid).reuses_sshproxy_authinfo()
    1237      __session_reuses_sshproxy_authinfo = session_reuses_sshproxy_authinfo
    1238
    1239 -    def session_uses_sshproxy(self, session_uuid):
    1240          """\
    1241          Check if session with unique identifier <session_uuid> is configured to use an
    1242          intermediate SSH proxy server.
    1243
    1244          @return: returns C{True} if the session is configured to use an SSH proxy, C{False} otherwise.
    1245          @rtype: C{bool}
    1246
    1247          """
    1248          return self.session_registry(session_uuid).uses_sshproxy()
    1249      __session_uses_sshproxy = session_uses_sshproxy
    1250
    1251 -    def session_can_sshproxy_auto_connect(self, session_uuid):
    1252          """\
    1253          Check if the SSH proxy of session with unique identifier <session_uuid> is configured adequately
    1254          to be able to auto-connect to the SSH proxy server (e.g. by public key authentication).
    1255
    1256          @param session_uuid: the X2Go session's UUID registry hash
    1257          @type session_uuid: C{str}
    1258
    1259          @return: returns C{True} if the session's SSH proxy can auto-connect, C{False} otherwise, C{None}
    1260              if no control session has been set up yet.
    1261          @rtype: C{bool}
    1262
    1263          """
    1264          return self.session_registry(session_uuid).can_sshproxy_auto_connect()
    1265      __session_can_sshproxy_auto_connect = session_can_sshproxy_auto_connect
    1266
    1267 -    def session_can_auto_connect(self, session_uuid):
    1268          """\
    1269          Check if session with unique identifier <session_uuid> is configured adequately
    1270          to be able to auto-connect to the X2Go server (e.g. by public key authentication).
    1271
    1272          @param session_uuid: the X2Go session's UUID registry hash
    1273          @type session_uuid: C{str}
    1274
    1275          @return: returns C{True} if the session can auto-connect, C{False} otherwise, C{None}
    1276              if no control session has been set up yet.
    1277          @rtype: C{bool}
    1278
    1279          """
    1280          return self.session_registry(session_uuid).can_auto_connect()
    1281      __session_can_auto_connect = session_can_auto_connect
    1282
    1283      # user hooks for detecting/notifying what happened during application runtime
    1284 -    def session_auto_connect(self, session_uuid):
    1285          """\
    1286          Auto-connect a given session. This method is called from within the session itself
    1287          and can be used to override the auto-connect procedure from within your
    1288          client implementation.
    1289
    1290          @param session_uuid: the X2Go session's UUID registry hash
    1291          @type session_uuid: C{str}
    1292
    1293          @return: returns C{True} if the session could be auto-connected.
    1294          @rtype: C{bool}
    1295
    1296          """
    1297          self.session_registry(session_uuid).do_auto_connect(redirect_to_client=False)
    1298      __session_auto_connect = session_auto_connect
    1299
    1300 -    def connect_session(self, session_uuid,
    1301                          username='',
    1302                          password='',
    1303                          sshproxy_user='',
    1304                          sshproxy_password='',
    1305                          add_to_known_hosts=False,
    1306                          force_password_auth=False,
    1307                          sshproxy_force_password_auth=False,
    1308                         ):
    1309          """\
    1310          Connect to a registered X2Go session with registry hash C{session_uuid}
    1311          This method basically wraps around paramiko.SSHClient.connect() for the
    1312          corresponding session.
    1313
    1314          @param session_uuid: the X2Go session's UUID registry hash
    1315          @type session_uuid: C{str}
    1316          @param username: user name to be used for session authentication
    1317          @type username: C{str}
    1318          @param password: the user's password for the X2Go server that is going to be
    1319              connected to
    1320          @type password: C{str}
    1321          @param sshproxy_user: user name to be used for SSH proxy authentication
    1322          @type sshproxy_user: C{str}
    1323          @param sshproxy_password: the SSH proxy user's password
    1324          @type sshproxy_password: C{str}
    1325          @param add_to_known_hosts: non-Paramiko option, if C{True} paramiko.AutoAddPolicy()
    1326              is used as missing-host-key-policy. If set to C{False} L{checkhosts.X2GoInteractiveAddPolicy()}
    1327              is used
    1328          @type add_to_known_hosts: C{bool}
    1329          @param force_password_auth: disable SSH pub/priv key authentication mechanisms
    1330              completely
    1331          @type force_password_auth: C{bool}
    1332          @param sshproxy_force_password_auth: disable SSH pub/priv key authentication mechanisms
    1333              completely for SSH proxy connection
    1334          @type sshproxy_force_password_auth: C{bool}
    1335
    1336          @return: returns True if this method has been successful
    1337          @rtype: C{bool}
    1338
    1339          """
    1340          _success = self.session_registry(session_uuid).connect(username=username, password=password,
    1341                                                                 sshproxy_user=sshproxy_user, sshproxy_password=sshproxy_password,
    1342                                                                 add_to_known_hosts=add_to_known_hosts,
    1343                                                                 force_password_auth=force_password_auth,
    1344                                                                 sshproxy_force_password_auth=sshproxy_force_password_auth,
    1345                                                                )
    1346          if self.auto_register_sessions:
    1347              self.session_registry.register_available_server_sessions(profile_name=self.get_session_profile_name(session_uuid),
    1348                                                                       newly_connected=True,
    1349                                                                      )
    1350          return _success
    1351      __connect_session = connect_session
    1352
    1353 -    def disconnect_session(self, session_uuid):
    1354          """\
    1355          Disconnect an L{X2GoSession} by closing down its Paramiko/SSH Transport thread.
    1356
    1357          @param session_uuid: the X2Go session's UUID registry hash
    1358          @type session_uuid: C{str}
    1359          """
    1360          self.session_registry(session_uuid).disconnect()
    1361          if self.use_listsessions_cache:
    1362              self.__update_cache_all_profiles()
    1363      __disconnect_session = disconnect_session
    1364
    1365 -    def set_session_print_action(self, session_uuid, print_action, **kwargs):
    1366          """\
    1367          If X2Go client-side printing is enable within an X2Go session you can use
    1368          this method to alter the way how incoming print spool jobs are handled/processed.
    1369
    1370          Currently, there are five different print actions available, each defined as an individual
    1371          print action class:
    1372
    1373              - B{PDFVIEW} (L{X2GoPrintActionPDFVIEW}): view an incoming spool job (a PDF file)
    1374                locally in a PDF viewer
    1375              - B{PDFSAVE} (L{X2GoPrintActionPDFSAVE}): save an incoming spool job (a PDF file)
    1376                under a nice name in a designated folder
    1377              - B{PRINT} (L{X2GoPrintActionPRINT}): really print the incoming spool job on a real printing device
    1378              - B{PRINTCMD} L{X2GoPrintActionPRINTCMD}: on each incoming spool job execute an
    1379                external command that lets the client user handle the further processing of the
    1380                print job (PDF) file
    1381              - B{DIALOG} (L{X2GoPrintActionDIALOG}): on each incoming spool job this print action
    1382                will call L{X2GoClient.HOOK_open_print_dialog()}
    1383
    1384          Each of the print action classes accepts different print action arguments. For detail
    1385          information on these print action arguments please refer to the constructor methods of
    1386          each class individually.
    1387
    1388          @param session_uuid: the X2Go session's UUID registry hash
    1389          @type session_uuid: C{str}
    1390          @param print_action: one of the named above print actions, either as string or class instance
    1391          @type print_action: C{str} or C{instance}
    1392          @param kwargs: additional information for the given print action (print
    1393              action arguments), for possible print action arguments and their values see each individual
    1394              print action class
    1395          @type kwargs: C{dict}
    1396
    1397          """
    1398          self.session_registry(session_uuid).set_print_action(print_action=print_action, **kwargs)
    1399      __set_session_print_action = set_session_print_action
    1400
    1401 -    def set_session_window_title(self, session_uuid, title=''):
    1402          """\
    1403          Modify session window title. If the session ID does not occur in the
    1404          given title, it will be prepended, so that every X2Go session window
    1405          always contains the X2Go session ID of that window.
    1406
    1407          @param session_uuid: the X2Go session's UUID registry hash
    1408          @type session_uuid: C{str}
    1409          @param title: new title for session window
    1410          @type title: C{str}
    1411
    1412          """
    1413          self.session_registry(session_uuid).set_session_window_title(title=title)
    1414      __set_session_window_title = set_session_window_title
    1415
    1416 -    def raise_session_window(self, session_uuid):
    1417          """\
    1418          Try to lift the session window above all other windows and bring
    1419          it to focus.
    1420
    1421          @param session_uuid: the X2Go session's UUID registry hash
    1422          @type session_uuid: C{str}
    1423          """
    1424          self.session_registry(session_uuid).raise_session_window()
    1425      __raise_session_window = raise_session_window
    1426
    1427 -    def session_auto_start_or_resume(self, session_uuid, newest=True, oldest=False, all_suspended=False, start=True):
    1428          """\
    1429          Automatically start or resume one or several sessions.
    1430
    1431          This method is called from within the session itself on session registration, so this method
    1432          can be used to handle auto-start/-resume events.
    1433
    1434          @param session_uuid: the X2Go session's UUID registry hash
    1435          @type session_uuid: C{str}
    1436          @param newest: if resuming, only resume newest/youngest session
    1437          @type newest: C{bool}
    1438          @param oldest: if resuming, only resume oldest session
    1439          @type oldest: C{bool}
    1440          @param all_suspended: if resuming, resume all suspended sessions
    1441          @type all_suspended: C{bool}
    1442          @param start: if no session is to be resumed, start a new session
    1443          @type start: C{bool}
    1444
    1445          """
    1446          self.session_registry(session_uuid).do_auto_start_or_resume(newest=newest, oldest=oldest, all_suspended=all_suspended, start=start, redirect_to_client=False)
    1447      __session_auto_start_or_resume = session_auto_start_or_resume
    1448
    1449 -    def start_session(self, session_uuid, **sessionopts):
    1450          """\
    1451          Start a new X2Go session on the remote X2Go server. This method
    1452          will open---if everything has been successful till here---the X2Go
    1453          session window.
    1454
    1455          Before calling this method you have to register your desired session
    1456          with L{register_session} (initialization of session parameters) and
    1457          connect to it with L{connect_session} (authentication).
    1458
    1459          @param session_uuid: the X2Go session's UUID registry hash
    1460          @type session_uuid: C{str}
    1461          @param sessionopts: pass-through of options directly to the session instance's L{X2GoSession.start()} method
    1462          @type sessionopts: C{dict}
    1463
    1464          @return: returns True if this method has been successful
    1465          @rtype: C{bool}
    1466
    1467          """
    1468          # prevent the newly started session from being registered twice
    1469          if self.auto_register_sessions:
    1470              self.session_registry.disable_session_auto_registration()
    1471
    1472          # start the actual session
    1473          _retval = self.session_registry(session_uuid).start(**sessionopts)
    1474
    1475          # re-enable session auto-registration...
    1476          if self.auto_register_sessions:
    1477              self.session_registry.enable_session_auto_registration()
    1478
    1479          return _retval
    1480      __start_session = start_session
    1481
    1482 -    def share_desktop_session(self, session_uuid, desktop=None, user=None, display=None, share_mode=0, check_desktop_list=False, **sessionopts):
    1483          """\
    1484          Share another already running desktop session. Desktop sharing can be run
    1485          in two different modes: view-only and full-access mode. Like new sessions
    1486          a to-be-shared session has be registered first with the L{X2GoClient}
    1487          instance.
    1488
    1489          @param desktop: desktop ID of a sharable desktop in format <user>@<display>
    1490          @type desktop: C{str}
    1491          @param user: user name and display number can be given separately, here give the
    1492              name of the user who wants to share a session with you.
    1493          @type user: C{str}
    1494          @param display: user name and display number can be given separately, here give the
    1495              number of the display that a user allows you to be shared with.
    1496          @type display: C{str}
    1497          @param share_mode: desktop sharing mode, 0 is VIEW-ONLY, 1 is FULL-ACCESS.
    1498          @type share_mode: C{int}
    1499          @param sessionopts: pass-through of options directly to the session instance's L{X2GoSession.share_desktop()} method
    1500          @type sessionopts: C{dict}
    1501
    1502          @return: True if the session could be successfully shared.
    1503          @rtype: C{bool}
    1504
    1505          @raise X2GoDesktopSharingException: if a given desktop ID does not specify an available desktop session
    1506
    1507          """
    1508
    1509          # X2GoClient.list_desktops() uses caching (if enabled, so we prefer lookups here...)
    1510          if desktop:
    1511              _desktop = desktop
    1512              user = None
    1513              display = None
    1514          else:
    1515              _desktop = '%s@%s' % (user, display)
    1516
    1517          if not _desktop in self._X2GoClient__list_desktops(session_uuid):
    1518              _orig_desktop = _desktop
    1519              _desktop = '%s.0' % _desktop
    1520
    1521          return self.session_registry(session_uuid).share_desktop(desktop=_desktop, share_mode=share_mode, check_desktop_list=check_desktop_list, **sessionopts)
    1522      __share_desktop_session = share_desktop_session
    1523
    1524 -    def resume_session(self, session_uuid=None, session_name=None, match_profile_name=None, **sessionopts):
    1525          """\
    1526          Resume or continue a suspended / running X2Go session on a
    1527          remote X2Go server (as specified when L{register_session} was
    1528          called).
    1529
    1530          @param session_uuid: the X2Go session's UUID registry hash
    1531          @type session_uuid: C{str}
    1532          @param session_name: the server-side name of an X2Go session
    1533          @type session_name: C{str}
    1534          @param match_profile_name: only resume a session if this profile name matches
    1535          @type match_profile_name: C{str}
    1536          @param sessionopts: pass-through of options directly to the session instance's L{X2GoSession.resume()} method
    1537          @type sessionopts: C{dict}
    1538
    1539          @return: returns True if this method has been successful
    1540          @rtype: C{bool}
    1541
    1542          @raise X2GoClientException: if the method does not know what session to resume
    1543
    1544          """
    1545          try:
    1546              if session_uuid is None and session_name is None:
    1547                  raise x2go_exceptions.X2GoClientException('can\'t resume a session without either session_uuid or session_name')
    1548              if session_name is None and self.session_registry(session_uuid).session_name is None:
    1549                  raise x2go_exceptions.X2GoClientException('don\'t know which session to resume')
    1550              if session_uuid is None:
    1551                  session_uuid = self.session_registry.get_session_of_session_name(session_name=session_name, return_object=False, match_profile_name=match_profile_name)
    1552                  return self.session_registry(session_uuid).resume(session_list=self._X2GoClient__list_sessions(session_uuid=session_uuid), **sessionopts)
    1553              else:
    1554                  return self.session_registry(session_uuid).resume(session_name=session_name, session_list=self._X2GoClient__list_sessions(session_uuid=session_uuid), **sessionopts)
    1555          except x2go_exceptions.X2GoControlSessionException:
    1556              profile_name = self.get_session_profile_name(session_uuid)
    1557              if self.session_registry(session_uuid).connected: self.HOOK_on_control_session_death(profile_name)
    1558              self.disconnect_profile(profile_name)
    1559      __resume_session = resume_session
    1560
    1561 -    def suspend_session(self, session_uuid, session_name=None, match_profile_name=None, **sessionopts):
    1562          """\
    1563          Suspend an X2Go session.
    1564
    1565          Normally, you will use this method to suspend a registered session that you
    1566          have formerly started/resumed from within your recent
    1567          L{X2GoClient} instance. For this you simply call this method
    1568          using the session's C{session_uuid}, leave the C{session_name}
    1569          empty.
    1570
    1571          Alternatively, you can suspend a non-associated X2Go session:
    1572          To do this you simply neeed to register (with the L{register_session}
    1573          method) an X2Go session on the to-be-addressed remote X2Go server and
    1574          connect (L{connect_session}) to it. Then call this method with
    1575          the freshly obtained C{session_uuid} and the remote X2Go session
    1576          name (as shown e.g. in x2golistsessions output).
    1577
    1578          @param session_uuid: the X2Go session's UUID registry hash
    1579          @type session_uuid: C{str}
    1580          @param session_name: the server-side name of an X2Go session (for
    1581              non-associated session suspend)
    1582          @type session_name: C{str}
    1583          @param match_profile_name: only suspend a session if this profile name matches
    1584          @type match_profile_name: C{str}
    1585          @param sessionopts: pass-through of options directly to the session instance's L{X2GoSession.suspend()} method
    1586          @type sessionopts: C{dict}
    1587
    1588          @return: returns True if this method has been successful
    1589          @rtype: C{bool}
    1590
    1591          """
    1592          try:
    1593              if session_name is None:
    1594
    1595                  # make sure that the current list of shared folders is up-to-date before the session suspends
    1596                  self.get_shared_folders(session_uuid, check_list_mounts=True)
    1597
    1598                  return self.session_registry(session_uuid).suspend(**sessionopts)
    1599              else:
    1600                  if match_profile_name is None:
    1601                      running_sessions = self.session_registry.running_sessions()
    1602                  else:
    1603                      running_sessions = self.session_registry.running_sessions_of_profile_name(match_profile_name)
    1604                  for session in running_sessions:
    1605                      if session_name == session.get_session_name():
    1606                          return session.suspend()
    1607              return self.session_registry(session_uuid).control_session.suspend(session_name=session_name, **sessionopts)
    1608          except x2go_exceptions.X2GoControlSessionException:
    1609              profile_name = self.get_session_profile_name(session_uuid)
    1610              if self.session_registry(session_uuid).conntected: self.HOOK_on_control_session_death(profile_name)
    1611              self.disconnect_profile(profile_name)
    1612      __suspend_session = suspend_session
    1613
    1614 -    def terminate_session(self, session_uuid, session_name=None, match_profile_name=None, **sessionopts):
    1615          """\
    1616          Terminate an X2Go session.
    1617
    1618          Normally you will use this method to terminate a registered session that you
    1619          have formerly started/resumed from within your recent
    1620          L{X2GoClient} instance. For this you simply call this method
    1621          using the session's C{session_uuid}, leave the C{session_name}
    1622          empty.
    1623
    1624          Alternatively, you can terminate a non-associated X2Go session:
    1625          To do this you simply neeed to register (L{register_session})
    1626          an X2Go session on the to-be-addressed remote X2Go server and
    1627          connect (L{connect_session}) to it. Then call this method with
    1628          the freshly obtained C{session_uuid} and the remote X2Go session
    1629          name (as shown in e.g. x2golistsessions output).
    1630
    1631          @param session_uuid: the X2Go session's UUID registry hash
    1632          @type session_uuid: C{str}
    1633          @param session_name: the server-side name of an X2Go session
    1634          @type session_name: C{str}
    1635          @param match_profile_name: only terminate a session if this profile name matches
    1636          @type match_profile_name: C{str}
    1637          @param sessionopts: pass-through of options directly to the session instance's L{X2GoSession.terminate()} method
    1638          @type sessionopts: C{dict}
    1639
    1640          @return: returns True if this method has been successful
    1641          @rtype: C{bool}
    1642
    1643          """
    1644          try:
    1645              if session_name is None:
    1646
    1647                  # make sure that the current list of shared folders is up-to-date before the session terminates
    1648                  self.get_shared_folders(session_uuid, check_list_mounts=True)
    1649
    1650                  return self.session_registry(session_uuid).terminate(**sessionopts)
    1651              else:
    1652                  if match_profile_name is None:
    1653                      terminatable_sessions = self.session_registry.running_sessions() + self.session_registry.suspended_sessions()
    1654                  else:
    1655                      terminatable_sessions = self.session_registry.running_sessions_of_profile_name(match_profile_name) + self.session_registry.suspended_sessions_of_profile_name(match_profile_name)
    1656                  for session in terminatable_sessions:
    1657                      if session_name == session.get_session_name():
    1658                          return session.terminate()
    1659              return self.session_registry(session_uuid).control_session.terminate(session_name=session_name, **sessionopts)
    1660          except x2go_exceptions.X2GoControlSessionException:
    1661              profile_name = self.get_session_profile_name(session_uuid)
    1662              if self.session_registry(session_uuid).conntected: self.HOOK_on_control_session_death(profile_name)
    1663              self.disconnect_profile(profile_name)
    1664      __terminate_session = terminate_session
    1665
    1666 -    def get_session_profile_name(self, session_uuid):
    1667          """\
    1668          Retrieve the profile name of the session that has been registered
    1669          under C{session_uuid}.
    1670
    1671          For profile based sessions this will be the profile name as used
    1672          in x2goclient's »sessions« configuration file.
    1673
    1674          For non-profile based session this will either be a C{profile_name} that
    1675          was passed to L{register_session} or it will be the application that
    1676          instantiated this L{X2GoClient} instance.
    1677
    1678          @param session_uuid: the X2Go session's UUID registry hash
    1679          @type session_uuid: C{str}
    1680
    1681          @return: X2Go session profile name
    1682          @rtype: C{str}
    1683
    1684          """
    1685          return self.session_registry(session_uuid).get_profile_name()
    1686      __get_session_profile_name = get_session_profile_name
    1687
    1688 -    def get_session_profile_id(self, session_uuid):
    1689          """\
    1690          Retrieve the profile id of the session that has been registered
    1691          under C{session_uuid}.
    1692
    1693          For profile based sessions this will be the profile id as used
    1694          in x2goclient's »sessions« configuration node (section header of
    1695          a session profile in the config, normally a timestamp created on
    1696          session profile creation/modification).
    1697
    1698          For non-profile based sessions this will be a timestamp created on
    1699          X2Go session registration by C{register_session}.
    1700
    1701          @param session_uuid: the session profile name
    1702          @type session_uuid: C{str}
    1703
    1704          @return: the X2Go session profile's id
    1705          @rtype: C{str}
    1706
    1707          """
    1708          return self.session_registry(session_uuid).profile_id
    1709      __get_session_profile_id = get_session_profile_id
    1710
    1711 -    def session_ok(self, session_uuid):
    1712          """\
    1713          Test if the X2Go session registered as C{session_uuid} is
    1714          in a healthy state.
    1715
    1716          @param session_uuid: the X2Go session's UUID registry hash
    1717          @type session_uuid: C{str}
    1718
    1719          @return: C{True} if session is ok, C{False} otherwise
    1720          @rtype: C{bool}
    1721
    1722          """
    1723          return self.session_registry(session_uuid).session_ok()
    1724      __session_ok = session_ok
    1725
    1726 -    def is_session_connected(self, session_uuid):
    1727          """\
    1728          Test if the X2Go session registered as C{session_uuid} connected
    1729          to the X2Go server.
    1730
    1731          @param session_uuid: the X2Go session's UUID registry hash
    1732          @type session_uuid: C{str}
    1733
    1734          @return: C{True} if session is connected, C{False} otherwise
    1735          @rtype: C{bool}
    1736
    1737          """
    1738          return self.session_registry(session_uuid).is_connected()
    1739      __is_session_connected = is_session_connected
    1740
    1741 -    def is_profile_connected(self, profile_name):
    1742          """\
    1743          Test if the X2Go given session profile has open connections
    1744          to the X2Go server.
    1745
    1746          @param profile_name: a valid session profile name
    1747          @type profile_name: C{str}
    1748
    1749          @return: C{True} if profile has a connected session, C{False} otherwise
    1750          @rtype: C{bool}
    1751
    1752          """
    1753          return bool(self.client_connected_sessions_of_profile_name(profile_name=profile_name))
    1754      __is_profile_connected = is_profile_connected
    1755
    1756 -    def is_session_profile(self, profile_id_or_name):
    1757          """\
    1758          Test if the X2Go given session profile is configured in the client's C{sessions} file.
    1759
    1760          @param profile_id_or_name: test existence of this session profile name (or id)
    1761          @type profile_id_or_name: C{str}
    1762
    1763          @return: C{True} if session profile exists, C{False} otherwise
    1764          @rtype: C{bool}
    1765
    1766          """
    1767          return self.session_profiles.has_profile(profile_id_or_name)
    1768      __is_session_profile = is_session_profile
    1769
    1770 -    def is_session_running(self, session_uuid, session_name=None):
    1771          """\
    1772          Test if the X2Go session registered as C{session_uuid} is up
    1773          and running.
    1774
    1775          @param session_uuid: the X2Go session's UUID registry hash
    1776          @type session_uuid: C{str}
    1777          @param session_name: the server-side name of an X2Go session
    1778          @type session_name: C{str}
    1779
    1780          @return: C{True} if session is running, C{False} otherwise
    1781          @rtype: C{bool}
    1782
    1783          """
    1784          if session_name is None:
    1785              return self.session_registry(session_uuid).is_running()
    1786          else:
    1787              return session_name in [ s for s in self.server_running_sessions(session_uuid) ]
    1788      __is_session_running = is_session_running
    1789
    1790 -    def is_session_suspended(self, session_uuid, session_name=None):
    1791          """\
    1792          Test if the X2Go session registered as C{session_uuid}
    1793          is in suspended state.
    1794
    1795          @param session_uuid: the X2Go session's UUID registry hash
    1796          @type session_uuid: C{str}
    1797          @param session_name: the server-side name of an X2Go session
    1798          @type session_name: C{str}
    1799
    1800          @return: C{True} if session is suspended, C{False} otherwise
    1801          @rtype: C{bool}
    1802
    1803          """
    1804          if session_name is None:
    1805              return self.session_registry(session_uuid).is_suspended()
    1806          else:
    1807              return session_name in [ s for s in self.server_suspended_sessions(session_uuid) ]
    1808      __is_session_suspended = is_session_suspended
    1809
    1810 -    def has_session_terminated(self, session_uuid, session_name=None):
    1811          """\
    1812          Test if the X2Go session registered as C{session_uuid}
    1813          has terminated.
    1814
    1815          @param session_uuid: the X2Go session's UUID registry hash
    1816          @type session_uuid: C{str}
    1817          @param session_name: the server-side name of an X2Go session
    1818          @type session_name: C{str}
    1819
    1820          @return: C{True} if session has terminated, C{False} otherwise
    1821          @rtype: C{bool}
    1822
    1823          """
    1824          if session_name is None:
    1825              return self.session_registry(session_uuid).has_terminated()
    1826          else:
    1827              return session_name not in [ s for s in self.server_running_sessions(session_uuid)  + self.server_suspended_sessions(session_uuid) ]
    1828      __has_session_terminated = has_session_terminated
    1829
    1830 -    def is_folder_sharing_available(self, session_uuid=None, profile_name=None):
    1831          """\
    1832          Test if local folder sharing is available for X2Go session with unique ID <session_uuid> or
    1833          session profile <profile_name>.
    1834
    1835          @param session_uuid: the X2Go session's UUID registry hash
    1836          @type session_uuid: C{str}
    1837          @param profile_name: alternatively, the profile name can be used to perform this query
    1838          @type profile_name: C{str}
    1839
    1840          @return: returns C{True} if the profile/session supports local folder sharing
    1841          @rtype: C{bool}
    1842
    1843          """
    1844          if session_uuid is None and profile_name:
    1845              session_uuid = self._X2GoClient__get_master_session(profile_name, return_object=False)
    1846          if session_uuid:
    1847              try:
    1848                  return self.session_registry(session_uuid).is_folder_sharing_available()
    1849              except x2go_exceptions.X2GoSessionRegistryException:
    1850                  return False
    1851          else:
    1852              self.logger('Cannot find a terminal session for profile ,,%s\'\' that can be used to query folder sharing capabilities' % profile_name, loglevel=log.loglevel_INFO)
    1853              return False
    1854      __is_folder_sharing_available = is_folder_sharing_available
    1855      __profile_is_folder_sharing_available = is_folder_sharing_available
    1856      __session_is_folder_sharing_available = is_folder_sharing_available
    1857
    1858 -    def share_local_folder(self, session_uuid=None, local_path=None, profile_name=None, folder_name=None):
    1859          """\
    1860          Share a local folder with the X2Go session registered as C{session_uuid}.
    1861
    1862          When calling this method the given client-side folder is mounted
    1863          on the X2Go server (via sshfs) and (if in desktop mode) provided as a
    1864          desktop icon on your remote session's desktop.
    1865
    1866          @param session_uuid: the X2Go session's UUID registry hash
    1867          @type session_uuid: C{str}
    1868          @param local_path: the full path to an existing folder on the local (client-side)
    1869              file system
    1870          @type local_path: C{str}
    1871          @param folder_name: synonymous to C{local_path}
    1872          @type folder_name: C{str}
    1873          @param profile_name: alternatively, the profile name can be used to share local folders
    1874          @type profile_name: C{str}
    1875
    1876          @return: returns C{True} if the local folder has been successfully mounted
    1877          @rtype: C{bool}
    1878
    1879          """
    1880          # compat for Python-X2Go (<=0.1.1.6)
    1881          if folder_name: local_path = folder_name
    1882
    1883          if session_uuid is None and profile_name:
    1884              session_uuid = self._X2GoClient__get_master_session(profile_name, return_object=False)
    1885          if session_uuid:
    1886              try:
    1887                  return self.session_registry(session_uuid).share_local_folder(local_path=local_path)
    1888              except x2go_exceptions.X2GoSessionException:
    1889                  return False
    1890          else:
    1891              self.logger('Cannot find a terminal session for profile ,,%s\'\' to share a local folder with' % profile_name, loglevel=log.loglevel_WARN)
    1892              return False
    1893      __share_local_folder = share_local_folder
    1894      __share_local_folder_with_session = share_local_folder
    1895      __share_local_folder_with_profile = share_local_folder
    1896
    1897 -    def unshare_all_local_folders(self, session_uuid=None, profile_name=None):
    1898          """\
    1899          Unshare all local folders mounted in X2Go session registered as
    1900          C{session_uuid}.
    1901
    1902          When calling this method all client-side mounted folders on the X2Go
    1903          server (via sshfs) for session with ID <session_uuid> will get
    1904          unmounted.
    1905
    1906          @param session_uuid: the X2Go session's UUID registry hash
    1907          @type session_uuid: C{str}
    1908          @param profile_name: alternatively, the profile name can be used to unshare
    1909              mounted folders
    1910          @type profile_name: C{str}
    1911
    1912          @return: returns C{True} if all local folders could be successfully unmounted
    1913          @rtype: C{bool}
    1914
    1915          """
    1916          if session_uuid is None and profile_name:
    1917              session_uuid = self._X2GoClient__get_master_session(profile_name, return_object=False)
    1918          if session_uuid:
    1919              return self.session_registry(session_uuid).unshare_all_local_folders()
    1920          else:
    1921              self.logger('Cannot find a terminal session for profile ,,%s\'\' from which to unmount local folders' % profile_name, loglevel=log.loglevel_WARN)
    1922              return False
    1923      unshare_all_local_folders_from_session = unshare_all_local_folders
    1924      unshare_all_local_folders_from_profile = unshare_all_local_folders
    1925      __unshare_all_local_folders_from_session = unshare_all_local_folders
    1926      __unshare_all_local_folders_from_profile = unshare_all_local_folders
    1927
    1928 -    def unshare_local_folder(self, session_uuid=None, profile_name=None, local_path=None):
    1929          """\
    1930          Unshare local folder that is mounted in the X2Go session registered as
    1931          C{session_uuid}.
    1932
    1933          When calling this method the given client-side mounted folder on the X2Go
    1934          server (via sshfs) for session with ID <session_uuid> will get
    1935          unmounted.
    1936
    1937          @param session_uuid: the X2Go session's UUID registry hash
    1938          @type session_uuid: C{str}
    1939          @param profile_name: alternatively, the profile name can be used to unshare
    1940              mounted folders
    1941          @type profile_name: C{str}
    1942          @param local_path: the full path of a local folder that is mounted within X2Go
    1943              session with session ID <session_uuid> (or recognized via profile name) and that
    1944              shall be unmounted from that session.
    1945          @type local_path: C{str}
    1946
    1947          @return: returns C{True} if all local folders could be successfully unmounted
    1948          @rtype: C{bool}
    1949
    1950          """
    1951          if session_uuid is None and profile_name:
    1952              session_uuid = self._X2GoClient__get_master_session(profile_name, return_object=False)
    1953          if session_uuid:
    1954              return self.session_registry(session_uuid).unshare_local_folder(local_path=local_path)
    1955          else:
    1956              self.logger('Cannot find a terminal session for profile ,,%s\'\' from which to unmount local folders' % profile_name, loglevel=log.loglevel_WARN)
    1957              return False
    1958      unshare_local_folder_from_session = unshare_local_folder
    1959      unshare_local_folder_from_profile = unshare_local_folder
    1960      __unshare_local_folder_from_session = unshare_local_folder
    1961      __unshare_local_folder_from_profile = unshare_local_folder
    1962
    1963 -    def get_shared_folders(self, session_uuid=None, profile_name=None, check_list_mounts=False):
    1964          """\
    1965          Get a list of local folders mounted within X2Go session with session hash <session_uuid>
    1966          from this client.
    1967
    1968          @param session_uuid: the X2Go session's UUID registry hash
    1969          @type session_uuid: C{str}
    1970          @param profile_name: alternatively, the profile name can be used to get mounted folders of a session connected profile
    1971          @type profile_name: C{str}
    1972          @param check_list_mounts: query the server-side mount list for up-to-date information
    1973          @type check_list_mounts: C{bool}
    1974
    1975          @return: returns a C{list} of those local folder names that are mounted within X2Go session <session_uuid>.
    1976          @rtype: C{list}
    1977
    1978          """
    1979          if session_uuid is None and profile_name:
    1980              session_uuid = self._X2GoClient__get_master_session(profile_name, return_object=False)
    1981
    1982          if session_uuid and profile_name is None:
    1983              profile_name = self.session_registry(session_uuid).get_profile_name()
    1984
    1985          if session_uuid and profile_name:
    1986
    1987              mounts = None
    1988              if check_list_mounts:
    1989                  _mounts = self.list_mounts_by_profile_name(profile_name)
    1990                  mounts = []
    1991                  for mount_list in _mounts.values():
    1992                      mounts.extend(mount_list)
    1993
    1994              return self.session_registry(session_uuid).get_shared_folders(check_list_mounts=check_list_mounts, mounts=mounts)
    1995
    1996      session_get_shared_folders = get_shared_folders
    1997      profile_get_shared_folders = get_shared_folders
    1998      __session_get_shared_folders = get_shared_folders
    1999      __profile_get_shared_folders = get_shared_folders
    2000
    2001 -    def get_master_session(self, profile_name, return_object=True, return_session_name=False):
    2002          """\
    2003          Retrieve the master session of a specific profile.
    2004
    2005          @param profile_name: the profile name that we query the master session of
    2006          @type profile_name: C{str}
    2007          @param return_object: return L{X2GoSession} instance
    2008          @type return_object: C{bool}
    2009          @param return_session_name: return X2Go session name
    2010          @type return_session_name: C{bool}
    2011
    2012          @return: a session list (as UUID hashes, objects, profile names/IDs or session names)
    2013          @rtype: C{list}
    2014
    2015          """
    2016          return self.session_registry.get_master_session(profile_name, return_object=return_object, return_session_name=return_session_name)
    2017      profile_master_session = get_master_session
    2018      __get_master_session = get_master_session
    2019      __profile_master_session = profile_master_session
    2020
    2021      ###
    2022      ### Provide access to the X2GoClient's session registry
    2023      ###
    2024
    2025 -    def client_connected_sessions(self, return_objects=False, return_profile_names=False, return_profile_ids=False, return_session_names=False):
    2026          """\
    2027          Retrieve a list of X2Go sessions that this L{X2GoClient} instance is connected to.
    2028
    2029          @param return_objects: return as list of X2Go session objects
    2030          @type return_objects: C{bool}
    2031          @param return_profile_names: return as list of session profile names
    2032          @type return_profile_names: C{bool}
    2033          @param return_profile_ids: return as list of session profile IDs
    2034          @type return_profile_ids: C{bool}
    2035          @param return_session_names: return as list of session names
    2036          @type return_session_names: C{bool}
    2037
    2038          @return: list of connected sessions
    2039          @rtype: C{list}
    2040
    2041          """
    2042          return self.session_registry.connected_sessions(return_objects=return_objects, return_profile_names=return_profile_names, return_profile_ids=return_profile_ids, return_session_names=return_session_names)
    2043      __client_connected_sessions = client_connected_sessions
    2044
    2045      @property
    2046 -    def client_has_connected_sessions(self):
    2047          """\
    2048          Equals C{True} if there are any connected sessions with this L{X2GoClient} instance.
    2049
    2050          """
    2051          return self.session_registry.has_connected_sessions
    2052      __client_has_connected_sessions = client_has_connected_sessions
    2053
    2054 -    def client_associated_sessions(self, return_objects=False, return_profile_names=False, return_profile_ids=False, return_session_names=False):
    2055          """\
    2056          Retrieve a list of X2Go sessions associated to this L{X2GoClient} instance.
    2057
    2058          @param return_objects: return as list of X2Go session objects
    2059          @type return_objects: C{bool}
    2060          @param return_profile_names: return as list of session profile names
    2061          @type return_profile_names: C{bool}
    2062          @param return_profile_ids: return as list of session profile IDs
    2063          @type return_profile_ids: C{bool}
    2064          @param return_session_names: return as list of session names
    2065          @type return_session_names: C{bool}
    2066
    2067          @return: list of associated sessions
    2068          @rtype: C{list}
    2069
    2070          """
    2071          return self.session_registry.associated_sessions(return_objects=return_objects, return_profile_names=return_profile_names, return_profile_ids=return_profile_ids, return_session_names=return_session_names)
    2072      __client_associated_sessions = client_associated_sessions
    2073
    2074      @property
    2075 -    def client_has_associated_sessions(self):
    2076          """\
    2077          Equals C{True} if there are any associated sessions with this L{X2GoClient} instance.
    2078
    2079          """
    2080          return self.session_registry.has_associated_sessions
    2081      __client_has_associated_sessions = client_has_associated_sessions
    2082
    2083 -    def client_running_sessions(self, return_objects=False, return_profile_names=False, return_profile_ids=False, return_session_names=False):
    2084          """\
    2085          Retrieve a list of running X2Go sessions.
    2086
    2087          @param return_objects: return as list of X2Go session objects
    2088          @type return_objects: C{bool}
    2089          @param return_profile_names: return as list of session profile names
    2090          @type return_profile_names: C{bool}
    2091          @param return_profile_ids: return as list of session profile IDs
    2092          @type return_profile_ids: C{bool}
    2093          @param return_session_names: return as list of session names
    2094          @type return_session_names: C{bool}
    2095
    2096          @return: list of running sessions
    2097          @rtype: C{list}
    2098
    2099          """
    2100          return self.session_registry.running_sessions(return_objects=return_objects, return_profile_names=return_profile_names, return_profile_ids=return_profile_ids, return_session_names=return_session_names)
    2101      __client_running_sessions = client_running_sessions
    2102
    2103      @property
    2104 -    def client_has_running_sessions(self):
    2105          """\
    2106          Equals C{True} if there are any running sessions with this L{X2GoClient} instance.
    2107
    2108          """
    2109          return self.session_registry.has_running_sessions
    2110      __client_has_running_sessions = client_has_running_sessions
    2111
    2112 -    def client_suspended_sessions(self, return_objects=False, return_profile_names=False, return_profile_ids=False, return_session_names=False):
    2113          """\
    2114          Retrieve a list of suspended X2Go sessions.
    2115
    2116          @param return_objects: return as list of X2Go session objects
    2117          @type return_objects: C{bool}
    2118          @param return_profile_names: return as list of session profile names
    2119          @type return_profile_names: C{bool}
    2120          @param return_profile_ids: return as list of session profile IDs
    2121          @type return_profile_ids: C{bool}
    2122          @param return_session_names: return as list of session names
    2123          @type return_session_names: C{bool}
    2124
    2125          @return: list of suspended sessions
    2126          @rtype: C{list}
    2127
    2128          """
    2129          return self.session_registry.running_sessions(return_objects=return_objects, return_profile_names=return_profile_names, return_profile_ids=return_profile_ids, return_session_names=return_session_names)
    2130      __client_suspended_sessions = client_suspended_sessions
    2131
    2132      @property
    2133 -    def client_has_suspended_sessions(self):
    2134          """\
    2135          Equals C{True} if there are any suspended sessions with this L{X2GoClient} instance.
    2136
    2137          """
    2138          return self.session_registry.has_suspended_sessions
    2139      __client_has_suspended_sessions = client_has_suspended_sessions
    2140
    2141 -    def client_registered_sessions(self, return_objects=True, return_profile_names=False, return_profile_ids=False, return_session_names=False):
    2142          """\
    2143          Retrieve a list of registered X2Go sessions.
    2144
    2145          @param return_objects: return as list of X2Go session objects
    2146          @type return_objects: C{bool}
    2147          @param return_profile_names: return as list of session profile names
    2148          @type return_profile_names: C{bool}
    2149          @param return_profile_ids: return as list of session profile IDs
    2150          @type return_profile_ids: C{bool}
    2151          @param return_session_names: return as list of session names
    2152          @type return_session_names: C{bool}
    2153
    2154          @return: list of registered sessions
    2155          @rtype: C{list}
    2156
    2157          """
    2158          return self.session_registry.registered_sessions(return_objects=return_objects, return_profile_names=return_profile_names, return_profile_ids=return_profile_ids, return_session_names=return_session_names)
    2159      __client_registered_sessions = client_registered_sessions
    2160
    2161      @property
    2162 -    def client_control_sessions(self):
    2163          """\
    2164          Equals a list of all registered X2Go control sessions.
    2165
    2166          """
    2167          return self.session_registry.control_sessions
    2168      __client_control_sessions = client_control_sessions
    2169
    2170 -    def client_control_session_of_profile_name(self, profile_name):
    2171          """\
    2172          Retrieve control session for profile name <profile_name>.
    2173
    2174          @param profile_name: profile name
    2175          @type profile_name: C{str}
    2176
    2177          @return: control session instance
    2178          @rtype: C{X2GoControlSession} instance
    2179
    2180          """
    2181          return self.session_registry.control_session_of_profile_name(profile_name)
    2182      __client_control_session_of_profile_name = client_control_session_of_profile_name
    2183
    2184 -    def get_server_versions(self, profile_name, component=None, force=False):
    2185          """\
    2186          Query the server configured in session profile <profile_name> for the list of install X2Go components
    2187          and its versions.
    2188
    2189          @param profile_name: use the control session of this profile to query the X2Go server for its component list
    2190          @type profile_name: C{str}
    2191          @param component: only return the version of a specific component
    2192          @type component: C{str}
    2193          @param force: refresh component/version data by a query to the server
    2194          @type force: C{bool}
    2195
    2196          @return: dictionary of server components (as keys) and their versions (as values) or the version of the given <component>
    2197          @rtype: C{dict} or C{str}
    2198
    2199          @raise X2GoClientException: if component is not available on the X2Go Server.
    2200
    2201          """
    2202          control_session = self.client_control_session_of_profile_name(profile_name)
    2203          if component is None:
    2204              return control_session.get_server_versions(force=force)
    2205          else:
    2206              try:
    2207                  return control_session.get_server_versions(force=force)[component]
    2208              except KeyError:
    2209                  raise x2go_exceptions.X2GoClientException('No such component on X2Go Server')
    2210      __get_server_versions = get_server_versions
    2211      get_server_components = get_server_versions
    2212      __get_server_components = get_server_components
    2213
    2214 -    def get_server_features(self, profile_name, force=False):
    2215          """\
    2216          Query the server configured in session profile <profile_name> for the list of server-side
    2217          X2Go features.
    2218
    2219          @param profile_name: use the control session of this profile to query the X2Go server for its feature list
    2220          @type profile_name: C{str}
    2221          @param force: refresh feature list by a query to the server
    2222          @type force: C{bool}
    2223
    2224          @return: list of server feature names (as returned by server-side command ,,x2gofeaturelist''
    2225          @rtype: C{list}
    2226
    2227          """
    2228          control_session = self.client_control_session_of_profile_name(profile_name)
    2229          return control_session.get_server_features(force=force)
    2230      __get_server_features = get_server_features
    2231
    2232 -    def has_server_feature(self, profile_name, feature):
    2233          """\
    2234          Query the server configured in session profile <profile_name> for the availability
    2235          of a certain server feature.
    2236
    2237          @param profile_name: use the control session of this profile to query the X2Go server for its feature
    2238          @type profile_name: C{str}
    2239          @param feature: test the availability of this feature on the X2Go server
    2240          @type feature: C{str}
    2241
    2242          @return: C{True} if the feature is available on the queried server
    2243          @rtype: C{bool}
    2244
    2245          """
    2246          control_session = self.client_control_session_of_profile_name(profile_name)
    2247          return feature in control_session.get_server_features()
    2248      __has_server_feature = has_server_feature
    2249
    2250 -    def client_registered_session_of_name(self, session_name, return_object=False):
    2251          """\
    2252          Retrieve X2Go session of a given session name.
    2253
    2254          @param session_name: session name
    2255          @type session_name: C{str}
    2256
    2257          @return: session instance of the given name
    2258          @rtype: C{X2GoSession} or C{str}
    2259
    2260          """
    2261          return self.session_registry.get_session_of_session_name(session_name, return_object=return_object)
    2262      __client_registered_session_of_name = client_registered_session_of_name
    2263
    2264 -    def client_has_registered_session_of_name(self, session_name):
    2265          """\
    2266          Equals C{True} if there is a registered session of name <session_name>.
    2267
    2268          @param session_name: session name
    2269          @type session_name: C{str}
    2270
    2271          @return: C{True} if the given session is registered
    2272          @rtype: C{bool}
    2273
    2274          """
    2275          return self.client_registered_session_of_name(session_name) is not None
    2276      __client_has_registered_session_of_name = client_registered_session_of_name
    2277
    2278 -    def client_registered_sessions_of_profile_name(self, profile_name, return_objects=False, return_session_names=False):
    2279          """\
    2280          Retrieve registered X2Go sessions of profile name <profile_name>.
    2281
    2282          @param profile_name: profile name
    2283          @type profile_name: C{str}
    2284          @param return_objects: return as list of X2Go session objects
    2285          @type return_objects: C{bool}
    2286          @param return_session_names: return as list of session names
    2287          @type return_session_names: C{bool}
    2288
    2289          @return: list of registered sessions of profile name
    2290          @rtype: C{list}
    2291
    2292          """
    2293          return self.session_registry.registered_sessions_of_profile_name(profile_name, return_objects=return_objects, return_session_names=return_session_names)
    2294      __client_registered_sessions_of_profile_name = client_registered_sessions_of_profile_name
    2295
    2296 -    def client_connected_sessions_of_profile_name(self, profile_name, return_objects=False, return_session_names=False):
    2297          """\
    2298          Retrieve connected X2Go sessions of profile name <profile_name>.
    2299
    2300          @param profile_name: profile name
    2301          @type profile_name: C{str}
    2302          @param return_objects: return as list of X2Go session objects
    2303          @type return_objects: C{bool}
    2304          @param return_session_names: return as list of session names
    2305          @type return_session_names: C{bool}
    2306
    2307          @return: list of connected sessions of profile name
    2308          @rtype: C{list}
    2309
    2310          """
    2311          return self.session_registry.connected_sessions_of_profile_name(profile_name, return_objects=return_objects, return_session_names=return_session_names)
    2312      __client_connected_sessions_of_profile_name = client_connected_sessions_of_profile_name
    2313
    2314 -    def client_associated_sessions_of_profile_name(self, profile_name, return_objects=False, return_session_names=False):
    2315          """\
    2316          Retrieve associated X2Go sessions of profile name <profile_name>.
    2317
    2318          @param profile_name: profile name
    2319          @type profile_name: C{str}
    2320          @param return_objects: return as list of X2Go session objects
    2321          @type return_objects: C{bool}
    2322          @param return_session_names: return as list of session names
    2323          @type return_session_names: C{bool}
    2324
    2325          @return: list of associated sessions of profile name
    2326          @rtype: C{list}
    2327
    2328          """
    2329          return self.session_registry.associated_sessions_of_profile_name(profile_name, return_objects=return_objects, return_session_names=return_session_names)
    2330      __client_associated_sessions_of_profile_name = client_associated_sessions_of_profile_name
    2331
    2332 -    def client_pubapp_sessions_of_profile_name(self, profile_name, return_objects=False, return_session_names=False):
    2333          """\
    2334          Retrieve X2Go sessions of profile name <profile_name> that provide published applications.
    2335
    2336          @param profile_name: profile name
    2337          @type profile_name: C{str}
    2338          @param return_objects: return as list of X2Go session objects
    2339          @type return_objects: C{bool}
    2340          @param return_session_names: return as list of session names
    2341          @type return_session_names: C{bool}
    2342
    2343          @return: list of application publishing sessions of profile name
    2344          @rtype: C{list}
    2345
    2346          """
    2347          return self.session_registry.pubapp_sessions_of_profile_name(profile_name, return_objects=return_objects, return_session_names=return_session_names)
    2348      __client_pubapp_sessions_of_profile_name = client_pubapp_sessions_of_profile_name
    2349
    2350
    2351 -    def client_running_sessions_of_profile_name(self, profile_name, return_objects=False, return_session_names=False):
    2352          """\
    2353          Retrieve running X2Go sessions of profile name <profile_name>.
    2354
    2355          @param profile_name: profile name
    2356          @type profile_name: C{str}
    2357          @param return_objects: return as list of X2Go session objects
    2358          @type return_objects: C{bool}
    2359          @param return_session_names: return as list of session names
    2360          @type return_session_names: C{bool}
    2361
    2362          @return: list of running sessions of profile name
    2363          @rtype: C{list}
    2364
    2365          """
    2366          return self.session_registry.running_sessions_of_profile_name(profile_name, return_objects=return_objects, return_session_names=return_session_names)
    2367      __client_running_sessions_of_profile_name = client_running_sessions_of_profile_name
    2368
    2369 -    def client_suspended_sessions_of_profile_name(self, profile_name, return_objects=False, return_session_names=False):
    2370          """\
    2371          Retrieve suspended X2Go sessions of profile name <profile_name>.
    2372
    2373          @param profile_name: profile name
    2374          @type profile_name: C{str}
    2375          @param return_objects: return as list of X2Go session objects
    2376          @type return_objects: C{bool}
    2377          @param return_session_names: return as list of session names
    2378          @type return_session_names: C{bool}
    2379
    2380          @return: list of suspended sessions of profile name
    2381          @rtype: C{list}
    2382
    2383          """
    2384          return self.session_registry.suspended_sessions_of_profile_name(profile_name, return_objects=return_objects, return_session_names=return_session_names)
    2385      __client_suspended_sessions_of_profile_name = client_suspended_sessions_of_profile_name
    2386
    2387      ###
    2388      ### Provide access to the X2Go server's sessions DB
    2389      ###
    2390
    2391 -    def server_is_alive(self, session_uuid):
    2392          """\
    2393          Test if server that corresponds to the terminal session C{session_uuid} is alive.
    2394
    2395          If the session is not connected anymore the L{X2GoClient.HOOK_on_control_session_death()} gets called.
    2396
    2397          @param session_uuid: the X2Go session's UUID registry hash
    2398          @type session_uuid: C{str}
    2399
    2400          @return: C{True} if X2Go server connection for L{X2GoSession} instance with <session_uuid> is alive.
    2401          @rtype: C{bool}
    2402
    2403          @raise X2GoControlSessionException: if the session is not connected anymore; in that case the L{HOOK_on_control_session_death} gets called.
    2404
    2405          """
    2406          try:
    2407              return self.session_registry(session_uuid).is_alive()
    2408          except x2go_exceptions.X2GoControlSessionException:
    2409              profile_name = self.get_session_profile_name(session_uuid)
    2410              if self.session_registry(session_uuid).conntected: self.HOOK_on_control_session_death(profile_name)
    2411              self.disconnect_profile(profile_name)
    2412              return False
    2413      __server_is_alive = server_is_alive
    2414
    2415 -    def all_servers_are_alive(self):
    2416          """\
    2417          Test vitality of all connected X2Go servers.
    2418
    2419          @return: C{True} if all connected X2Go servers are alive.
    2420          @rtype: C{bool}
    2421
    2422          """
    2423          _all_alive = True
    2424          for session_uuid in self.client_connected_sessions():
    2425              _all_alive = _all_alive and self.server_is_alive(session_uuid)
    2426          return _all_alive
    2427      __all_servers_are_alive = all_servers_are_alive
    2428
    2429 -    def server_valid_x2gouser(self, session_uuid, username=None):
    2430          """\
    2431          Check if user is allowed to start an X2Go session on a remote server.
    2432
    2433          @param session_uuid: the X2Go session's UUID registry hash
    2434          @type session_uuid: C{str}
    2435          @param username: user name to test validity for
    2436          @type username: C{str}
    2437
    2438          @return: Is remote user allowed to start an X2Go session?
    2439          @rtype: C{str}
    2440
    2441          """
    2442          return self.session_registry(session_uuid).user_is_x2gouser(username=username)
    2443      __server_valid_x2gouser = server_valid_x2gouser
    2444
    2445 -    def server_running_sessions(self, session_uuid):
    2446          """\
    2447          Retrieve a list of session names of all server-side running sessions (including those not
    2448          instantiated by our L{X2GoClient} instance).
    2449
    2450          @param session_uuid: the X2Go session's UUID registry hash
    2451          @type session_uuid: C{str}
    2452
    2453          @return: list of session names
    2454          @rtype: C{list}
    2455
    2456          @raise X2GoClientException: if the session with UUID C{session_uuid} is not connected
    2457
    2458          """
    2459          if self._X2GoClient__is_session_connected(session_uuid):
    2460              session_list = self._X2GoClient__list_sessions(session_uuid)
    2461              return [ key for key in session_list.keys() if session_list[key].status == 'R' ]
    2462          else:
    2463              raise x2go_exceptions.X2GoClientException('X2Go session with UUID %s is not connected' % session_uuid)
    2464      __server_running_sessions = server_running_sessions
    2465
    2466 -    def server_has_running_sessions(self, session_uuid):
    2467          """\
    2468          Equals C{True} if the X2Go server has any running sessions.
    2469
    2470          @param session_uuid: the X2Go session's UUID registry hash
    2471          @type session_uuid: C{str}
    2472          @return: C{True}, if there are running sessions
    2473          @rtype: C{bool}
    2474
    2475          """
    2476          return len(self._X2GoClient__server_running_sessions(session_uuid)) > 0
    2477      __server_has_running_sessions = server_has_running_sessions
    2478
    2479 -    def server_has_running_session_of_name(self, session_uuid, session_name):
    2480          """\
    2481          Equals C{True} if the X2Go server has a running session of name <session_name>.
    2482
    2483          @param session_uuid: the X2Go session's UUID registry hash
    2484          @type session_uuid: C{str}
    2485          @param session_name: session name
    2486          @type session_name: C{str}
    2487
    2488          """
    2489          return session_name in self._X2GoClient__server_running_sessions(session_uuid)
    2490      __server_has_running_session_of_name = server_has_running_session_of_name
    2491
    2492 -    def server_suspended_sessions(self, session_uuid):
    2493          """\
    2494          Retrieve a list of session names of all server-side suspended sessions (including those not
    2495          instantiated by our L{X2GoClient} instance).
    2496
    2497          @param session_uuid: the X2Go session's UUID registry hash
    2498          @type session_uuid: C{str}
    2499
    2500          @return: list of session names
    2501          @rtype: C{list}
    2502
    2503          @raise X2GoClientException: if the session with UUID C{session_uuid} is not connected
    2504
    2505          """
    2506          if self._X2GoClient__is_session_connected(session_uuid):
    2507              session_list = self._X2GoClient__list_sessions(session_uuid)
    2508              return [ key for key in session_list.keys() if session_list[key].status == 'S' ]
    2509          else:
    2510              raise x2go_exceptions.X2GoClientException('X2Go session with UUID %s is not connected' % session_uuid)
    2511      __server_suspended_sessions = server_suspended_sessions
    2512
    2513 -    def server_has_suspended_sessions(self, session_uuid):
    2514          """\
    2515          Equals C{True} if the X2Go server has any suspended sessions.
    2516
    2517          @param session_uuid: the X2Go session's UUID registry hash
    2518          @type session_uuid: C{str}
    2519
    2520          """
    2521          return len(self._X2GoClient__server_suspended_sessions(session_uuid)) > 0
    2522      __server_has_suspended_sessions = server_has_suspended_sessions
    2523
    2524 -    def server_has_suspended_session_of_name(self, session_uuid, session_name):
    2525          """\
    2526          Equals C{True} if the X2Go server has a suspended session of name <session_name>.
    2527
    2528          @param session_uuid: the X2Go session's UUID registry hash
    2529          @type session_uuid: C{str}
    2530          @param session_name: session name
    2531          @type session_name: C{str}
    2532          @return: C{True}, if there are running sessions
    2533          @rtype: C{bool}
    2534
    2535          """
    2536          return session_name in self._X2GoClient__server_suspended_sessions(session_uuid)
    2537      __server_has_suspended_session_of_name = server_has_suspended_session_of_name
    2538
    2539      ###
    2540      ### CLIENT OPERATIONS ON SESSIONS (listing sessions, terminating non-associated sessions etc.)
    2541      ###
    2542
    2543 -    def clean_sessions(self, session_uuid, published_applications=False):
    2544          """\
    2545          Find running X2Go sessions that have previously been started by the
    2546          connected user on the remote X2Go server and terminate them.
    2547
    2548          Before calling this method you have to setup a pro forma remote X2Go session
    2549          with L{X2GoClient.register_session()} (even if you do not intend to open
    2550          a real X2Go session window on the remote server) and connect to this session (with
    2551          L{X2GoClient.connect_session()}.
    2552
    2553          @param session_uuid: the X2Go session's UUID registry hash
    2554          @type session_uuid: C{str}
    2555          @param published_applications: if C{True}, also terminate sessions that are published applications
    2556              provider
    2557          @type published_applications: C{bool}
    2558
    2559          """
    2560          _destroy_terminals = not ( self.auto_update_sessionregistry == True)
    2561          try:
    2562              session = self.session_registry(session_uuid)
    2563              session.clean_sessions(destroy_terminals=_destroy_terminals, published_applications=published_applications)
    2564          except x2go_exceptions.X2GoSessionRegistryException:
    2565              # silently ignore a non-registered session UUID (mostly occurs during disconnects)
    2566              pass
    2567      __clean_sessions = clean_sessions
    2568
    2569 -    def list_sessions(self, session_uuid=None,
    2570                        profile_name=None, profile_id=None,
    2571                        no_cache=False, refresh_cache=False,
    2572                        update_sessionregistry=True,
    2573                        register_sessions=False,
    2574                        raw=False):
    2575          """\
    2576          Use the X2Go session registered under C{session_uuid} to
    2577          retrieve a list of running or suspended X2Go sessions from the
    2578          connected X2Go server (for the authenticated user).
    2579
    2580          Before calling this method you have to setup a pro forma remote X2Go session
    2581          with L{X2GoClient.register_session()} (even if you do not intend to open
    2582          a real X2Go session window on the remote server) and connect to this session (with
    2583          L{X2GoClient.connect_session()}.
    2584
    2585          @param session_uuid: the X2Go session's UUID registry hash
    2586          @type session_uuid: C{str}
    2587          @param profile_name: use profile name instead of <session_uuid>
    2588          @type profile_name: C{str}
    2589          @param profile_id: use profile id instead of <profile_name> or <session_uuid>
    2590          @type profile_id: C{str}
    2591          @param no_cache: do not get the session list from cache, query the X2Go server directly
    2592          @type no_cache: C{bool}
    2593          @param refresh_cache: query the X2Go server directly and update the session list cache
    2594              with the new information
    2595          @type refresh_cache: C{bool}
    2596          @param update_sessionregistry: query the X2Go server directly and update the
    2597              session registry according to the obtained information
    2598          @type update_sessionregistry: C{bool}
    2599          @param register_sessions: query the X2Go server directly and register newly found X2Go session
    2600              as L{X2GoSession} instances associated to this L{X2GoClient} instance
    2601          @type register_sessions: C{bool}
    2602          @param raw: output the session list in X2Go's raw C{x2golistsessions} format
    2603          @type raw: C{bool}
    2604
    2605          @raise X2GoClientException: if the session profile specified by C{session_uuid}, C{profile_name} or C{profile_id} is not connected
    2606              or if none of the named parameters has been specified
    2607
    2608          """
    2609          if profile_id is not None:
    2610              profile_name = self.to_profile_name(profile_id)
    2611
    2612          if profile_name is not None:
    2613
    2614              _connected_sessions = self.client_connected_sessions_of_profile_name(profile_name, return_objects=True)
    2615              if _connected_sessions:
    2616                  # it does not really matter which session to use for getting a server-side session list
    2617                  # thus, we simply grab the first that comes in...
    2618                  session_uuid = _connected_sessions[0].get_uuid()
    2619              else:
    2620                  raise x2go_exceptions.X2GoClientException('profile ,,%s\'\' is not connected' % profile_name)
    2621
    2622          elif session_uuid is not None:
    2623              pass
    2624          else:
    2625              raise x2go_exceptions.X2GoClientException('must either specify session UUID or profile name')
    2626
    2627          if raw:
    2628              return self.session_registry(session_uuid).list_sessions(raw=raw)
    2629
    2630          if not self.use_listsessions_cache or not self.auto_update_listsessions_cache or no_cache:
    2631              _session_list = self.session_registry(session_uuid).list_sessions()
    2632          elif refresh_cache:
    2633              self.update_cache_by_session_uuid(session_uuid)
    2634              _session_list = self.listsessions_cache.list_sessions(session_uuid)
    2635          else:
    2636              # if there is no cache for this session_uuid available, make sure the cache gets updated
    2637              # before reading from it...
    2638              if self.use_listsessions_cache and (not self.listsessions_cache.is_cached(session_uuid=session_uuid, cache_type='sessions') or refresh_cache):
    2639                  self.__update_cache_by_session_uuid(session_uuid)
    2640              _session_list = self.listsessions_cache.list_sessions(session_uuid)
    2641
    2642          if update_sessionregistry:
    2643              self.update_sessionregistry_status_by_profile_name(profile_name=self.get_session_profile_name(session_uuid), session_list=_session_list)
    2644
    2645          if register_sessions:
    2646              self.session_registry.register_available_server_sessions(profile_name=self.get_session_profile_name(session_uuid),
    2647                                                                       session_list=_session_list)
    2648
    2649          return _session_list
    2650      __list_sessions = list_sessions
    2651
    2652 -    def list_desktops(self, session_uuid=None,
    2653                        profile_name=None, profile_id=None,
    2654                        no_cache=False, refresh_cache=False,
    2655                        exclude_session_types=[],
    2656                        raw=False):
    2657          """\
    2658          Use the X2Go session registered under C{session_uuid} to
    2659          retrieve a list of X2Go desktop sessions that are available
    2660          for desktop sharing.
    2661
    2662          Before calling this method you have to setup a pro forma remote X2Go session
    2663          with L{X2GoClient.register_session()} (even if you do not intend to open
    2664          a real X2Go session window on the remote server) and connect to this session (with
    2665          L{X2GoClient.connect_session()}.
    2666
    2667          @param session_uuid: the X2Go session's UUID registry hash
    2668          @type session_uuid: C{str}
    2669          @param profile_name: use profile name instead of <session_uuid>
    2670          @type profile_name: C{str}
    2671          @param profile_id: use profile id instead of <profile_name> or <session_uuid>
    2672          @type profile_id: C{str}
    2673          @param no_cache: do not get the desktop list from cache, query the X2Go server directly
    2674          @type no_cache: C{bool}
    2675          @param refresh_cache: query the X2Go server directly and update the desktop list cache
    2676              with the new information
    2677          @type refresh_cache: C{bool}
    2678          @param exclude_session_types: session types (e.g. "D", "R", "S" or "P") to be excluded from the
    2679              returned list of sharable desktops (this only works for sharing someone's own sessions, for
    2680              sharing other users' sessions, the X2Go Desktop Sharing decides on what is sharable and what not).
    2681          @type exclude_session_types: C{list}
    2682          @param raw: output the session list in X2Go's raw C{x2golistdesktops} format
    2683          @type raw: C{bool}
    2684
    2685          @return: a list of available desktops to be shared
    2686          @rtype: C{list}
    2687
    2688          @raise X2GoClientException: if the session profile specified by C{session_uuid}, C{profile_name} or C{profile_id} is not connected
    2689              or if none of the named parameters has been specified
    2690
    2691          """
    2692          if profile_id is not None:
    2693              profile_name = self.to_profile_name(profile_id)
    2694
    2695          if profile_name is not None:
    2696
    2697              _connected_sessions = self.client_connected_sessions_of_profile_name(profile_name, return_objects=True)
    2698              if _connected_sessions:
    2699                  # it does not really matter which session to use for getting a server-side session list
    2700                  # thus, we simply grab the first that comes in...
    2701                  session_uuid = _connected_sessions[0].get_uuid()
    2702              else:
    2703                  raise x2go_exceptions.X2GoClientException('profile ,,%s\'\' is not connected' % profile_name)
    2704
    2705          elif session_uuid is not None:
    2706              pass
    2707          else:
    2708              raise x2go_exceptions.X2GoClientException('must either specify session UUID or profile name')
    2709
    2710          if raw:
    2711              return self.session_registry(session_uuid).list_desktops(raw=raw)
    2712
    2713          if not self.use_listsessions_cache or not self.auto_update_listdesktops_cache or no_cache:
    2714              _desktop_list = self.session_registry(session_uuid).list_desktops()
    2715          else:
    2716              if self.use_listsessions_cache and (not self.listsessions_cache.is_cached(session_uuid=session_uuid, cache_type='desktops') or refresh_cache):
    2717                  self.__update_cache_by_session_uuid(session_uuid, update_sessions=False, update_desktops=True)
    2718              _desktop_list = self.listsessions_cache.list_desktops(session_uuid)
    2719
    2720          # attempt to exclude session types that are requested to be excluded
    2721          if exclude_session_types:
    2722
    2723              # create an X2GoServerSessionList* instance and operate on that
    2724              session_list = self.list_backend()
    2725              session_list.set_sessions(self._X2GoClient__list_sessions(session_uuid))
    2726
    2727              # search for a match among the listed sessions
    2728              for desktop in copy.deepcopy(_desktop_list):
    2729                  user = desktop.split('@')[0]
    2730                  if user == self.get_session_username(session_uuid):
    2731                      display = desktop.split('@')[1]
    2732                      session = session_list.get_session_with('display', display, hostname=self.get_session_server_hostname(session_uuid))
    2733                      if session is None: continue
    2734                      if session.get_session_type() in exclude_session_types:
    2735                          _desktop_list.remove(desktop)
    2736
    2737          return _desktop_list
    2738      __list_desktops = list_desktops
    2739
    2740 -    def list_mounts_by_profile_name(self, profile_name,
    2741                                      no_cache=False, refresh_cache=False,
    2742                                      raw=False):
    2743          """
    2744          For a given profil C{profile_name} to
    2745          retrieve its list of mounted client shares for that session.
    2746
    2747          @param profile_name: a valid profile name
    2748          @type profile_name: C{str}
    2749          @param no_cache: do not get the session list from cache, query the X2Go server directly
    2750          @type no_cache: C{bool}
    2751          @param raw: output the session list in X2Go's raw C{x2golistmounts} format
    2752          @type raw: C{bool}
    2753
    2754          @return: list of server-side mounted shares for a given profile name
    2755          @rtype: C{list}
    2756
    2757          """
    2758          sessions = [ s for s in self.client_running_sessions(return_objects=True) if s.get_profile_name() == profile_name ]
    2759
    2760          if raw:
    2761              _list_mounts = ""
    2762              for session in sessions:
    2763                  _list_mounts += self.__list_mounts(session_uuid=session(), no_cache=no_cache, refresh_cache=refresh_cache, raw=True)
    2764          else:
    2765              _list_mounts = {}
    2766              for session in sessions:
    2767                  _list_mounts.update(self.__list_mounts(session_uuid=session(), no_cache=no_cache, refresh_cache=refresh_cache, raw=False))
    2768          return _list_mounts
    2769      __list_mounts_by_profile_name = list_mounts_by_profile_name
    2770
    2771 -    def list_mounts(self, session_uuid,
    2772                      no_cache=False, refresh_cache=False,
    2773                      raw=False):
    2774          """\
    2775          Use the X2Go session registered under C{session_uuid} to
    2776          retrieve its list of mounted client shares for that session.
    2777
    2778          @param session_uuid: the X2Go session's UUID registry hash
    2779          @type session_uuid: C{str}
    2780          @param no_cache: do not get the session list from cache, query the X2Go server directly
    2781          @type no_cache: C{bool}
    2782          @param raw: output the session list in X2Go's raw C{x2golistmounts} format
    2783          @type raw: C{bool}
    2784
    2785          @return: list of server-side mounted shares for a given session UUID
    2786          @rtype: C{list}
    2787
    2788          """
    2789          if raw:
    2790              return self.session_registry(session_uuid).list_mounts(raw=raw)
    2791
    2792          if not self.use_listsessions_cache or not self.auto_update_listmounts_cache or no_cache:
    2793              _mounts_list = self.session_registry(session_uuid).list_mounts()
    2794          else:
    2795              if self.use_listsessions_cache and (not self.listsessions_cache.is_cached(session_uuid=session_uuid, cache_type='mounts') or refresh_cache):
    2796                  self.__update_cache_by_session_uuid(session_uuid, update_sessions=False, update_mounts=True)
    2797              _mounts_list = self.listsessions_cache.list_mounts(session_uuid)
    2798
    2799          return _mounts_list
    2800      __list_mounts = list_mounts
    2801
    2802      ###
    2803      ### Provide access to config file class objects
    2804      ###
    2805
    2806 -    def get_profiles(self):
    2807          """\
    2808          Returns the L{X2GoClient} instance's C{X2GoSessionProfiles*} object.
    2809
    2810          Use this method for object retrieval if you want to modify the »sessions«
    2811          configuration node (e.g. in ~/.x2goclient with the FILE backend) from within your
    2812          Python X2Go based application.
    2813
    2814          return: returns the client's session profiles instance
    2815          rtype: C{X2GoSessionProfiles*} instance
    2816
    2817          """
    2818          return self.session_profiles
    2819      __get_profiles = get_profiles
    2820      get_session_profiles = get_profiles
    2821      """Alias for L{get_profiles()}."""
    2822
    2823      @property
    2824 -    def profile_names(self):
    2825          """\
    2826          Equals a list of all profile names that are known to this L{X2GoClient} instance.
    2827
    2828          """
    2829          return self.session_profiles.profile_names
    2830      __profile_names = profile_names
    2831
    2832 -    def get_client_settings(self):
    2833          """\
    2834          Returns the L{X2GoClient} instance's C{X2GoClientSettings*} object.
    2835
    2836          Use this method for object retrieval if you want to modify the »settings«
    2837          configuration node (e.g. in ~/.x2goclient with the FILE backend) from within your
    2838          Python X2Go based application.
    2839
    2840          return: returns the client's settings configuration node
    2841          rtype: C{bool}
    2842
    2843          """
    2844          return self.client_settings
    2845      __get_client_settings = get_client_settings
    2846
    2847 -    def get_client_printing(self):
    2848          """\
    2849          Returns the L{X2GoClient} instance's C{X2GoClientPrinting*} object.
    2850
    2851          Use this method for object retrieval if you want to modify the printing
    2852          configuration node (e.g. in ~/.x2goclient with the FILE backend) from within your
    2853          Python X2Go based application.
    2854
    2855          return: returns the client's printing configuration node
    2856          rtype: C{bool}
    2857
    2858          """
    2859          return self.client_printing
    2860      __get_client_printing = get_client_printing
    2861
    2862      ###
    2863      ### Session profile oriented methods
    2864      ###
    2865
    2866 -    def get_profile_config(self, profile_id_or_name, parameter=None):
    2867          """\
    2868          Returns a dictionary with session options and values that represent
    2869          the session profile for C{profile_id_or_name}.
    2870
    2871          @param profile_id_or_name: name or id of an X2Go session profile as found
    2872              in the sessions configuration file
    2873          @type profile_id_or_name: C{str}
    2874          @param parameter: if specified, only the value for the given parameter is returned
    2875          @type parameter: C{str}
    2876
    2877          @return: a Python dictionary with session profile options
    2878          @rtype: C{dict} or C{bool}, C{int}, C{str}
    2879
    2880          """
    2881          return self.session_profiles.get_profile_config(profile_id_or_name, parameter=parameter)
    2882      __get_profile_config = get_profile_config
    2883      with_profile_config = get_profile_config
    2884
    2885 -    def set_profile_config(self, profile_id_or_name, parameter, value):
    2886          """\
    2887          Set individual session profile parameters for session profile C{profile_id_or_name}.
    2888
    2889          @param profile_id_or_name: name or id of an X2Go session profile as found
    2890              in the sessions configuration file
    2891          @type profile_id_or_name: C{str}
    2892          @param parameter: set this parameter with the given C{value}
    2893          @type parameter: C{str}
    2894          @param value: set this value for the given C{parameter}
    2895          @type value: C{bool}, C{int}, C{str}, C{list} or C{dict}
    2896
    2897          @return: returns C{True} if this operation has been successful
    2898          @rtype: C{dict}
    2899
    2900          """
    2901          self.session_profiles.update_value(profile_id_or_name, parameter, value)
    2902          self.session_profiles.write_user_config = True
    2903          self.session_profiles.write()
    2904      __set_profile_config = set_profile_config
    2905
    2906 -    def to_profile_id(self, profile_name):
    2907          """\
    2908          Retrieve the session profile ID of the session whose profile name
    2909          is C{profile_name}
    2910
    2911          @param profile_name: the session profile name
    2912          @type profile_name: C{str}
    2913
    2914          @return: the session profile's ID
    2915          @rtype: C{str}
    2916
    2917          """
    2918          return self.session_profiles.to_profile_id(profile_name)
    2919      __to_profile_id = to_profile_id
    2920
    2921 -    def to_profile_name(self, profile_id):
    2922          """\
    2923          Retrieve the session profile name of the session whose profile ID
    2924          is C{profile_id}
    2925
    2926          @param profile_id: the session profile ID
    2927          @type profile_id: C{str}
    2928
    2929          @return: the session profile's name
    2930          @rtype: C{str}
    2931
    2932          """
    2933          return self.session_profiles.to_profile_name(profile_id)
    2934      __to_profile_name = to_profile_name
    2935
    2936 -    def get_profile_metatype(self, profile_name):
    2937          """\
    2938          Evaluate a session profile and return a human readable meta type
    2939          (classification) for the session profile C{profile_name}.
    2940
    2941          @param profile_name: a profile name
    2942          @type profile_name: C{str}
    2943
    2944          @return: the profile's meta type
    2945          @rtype: C{str}
    2946
    2947          """
    2948          return self.session_profiles.get_profile_metatype(profile_name)
    2949      __get_profile_metatype = get_profile_metatype
    2950
    2951 -    def client_connected_profiles(self, return_profile_names=False):
    2952          """\
    2953          Retrieve a list of session profiles that are currently connected to an X2Go server.
    2954
    2955          @param return_profile_names: return as list of session profile names
    2956          @type return_profile_names: C{bool}
    2957          @return: a list of profile names or IDs
    2958          @rtype: C{list}
    2959
    2960          """
    2961          if return_profile_names:
    2962              return [ self.to_profile_name(p_id) for p_id in self.session_registry.connected_profiles() ]
    2963          else:
    2964              return self.session_registry.connected_profiles()
    2965      __client_connected_profiles = client_connected_profiles
    2966
    2967 -    def disconnect_profile(self, profile_name):
    2968          """\
    2969          Disconnect all L{X2GoSession} instances that relate to C{profile_name} by closing down their
    2970          Paramiko/SSH Transport thread.
    2971
    2972          @param profile_name: the X2Go session profile name
    2973          @type profile_name: C{str}
    2974          @return: a return value
    2975          @rtype: C{bool}
    2976
    2977          """
    2978          _retval = False
    2979          _session_uuid_list = []
    2980          # disconnect individual sessions and make a list of session UUIDs for later cleanup (s. below)
    2981          for s in self.session_registry.registered_sessions_of_profile_name(profile_name, return_objects=True):
    2982              _session_uuid_list.append(s.get_uuid())
    2983              _retval = s.disconnect() | _retval
    2984
    2985          # tell session registry to forget attached sessions completely on disconnect action
    2986          for uuid in _session_uuid_list:
    2987              self.session_registry.forget(uuid)
    2988
    2989          # clear cache, as well...
    2990          if self.use_listsessions_cache:
    2991              self.listsessions_cache.delete(profile_name)
    2992          return _retval
    2993      __disconnect_profile = disconnect_profile
    2994
    2995 -    def update_sessionregistry_status_by_profile_name(self, profile_name, session_list=None):
    2996          """\
    2997          Update the session registry stati by profile name.
    2998
    2999          @param profile_name: the X2Go session profile name
    3000          @type profile_name: C{str}
    3001          @param session_list: a manually passed on list of X2Go sessions
    3002          @type session_list: C{X2GoServerList*} instances
    3003
    3004          """
    3005          session_uuids = self.client_registered_sessions_of_profile_name(profile_name, return_objects=False)
    3006          if session_uuids:
    3007              if session_list is None:
    3008                  session_list = self._X2GoClient__list_sessions(session_uuids[0],
    3009                                                                 update_sessionregistry=False,
    3010                                                                 register_sessions=False,
    3011                                                                )
    3012              try:
    3013                  self.session_registry.update_status(profile_name=profile_name, session_list=session_list)
    3014              except x2go_exceptions.X2GoControlSessionException:
    3015                  if self.session_registry(session_uuids[0]).connected: self.HOOK_on_control_session_death(profile_name)
    3016                  self.disconnect_profile(profile_name)
    3017      __update_sessionregistry_status_by_profile_name = update_sessionregistry_status_by_profile_name
    3018
    3019 -    def update_sessionregistry_status_by_session_uuid(self, session_uuid):
    3020          """\
    3021          Update the session registry status of a specific L{X2GoSession} instance with
    3022          session identifier <session_uuid>.
    3023
    3024          @param session_uuid: the X2Go session's UUID registry hash
    3025          @type session_uuid: C{str}
    3026
    3027          """
    3028          session_list = self._X2GoClient__list_sessions(session_uuid, update_sessionregistry=False, register_sessions=False)
    3029          if session_list:
    3030              self.session_registry.update_status(session_uuid=session_uuid, session_list=session_list)
    3031      __update_sessionregistry_status_by_session_uuid = update_sessionregistry_status_by_session_uuid
    3032
    3033 -    def update_sessionregistry_status_all_profiles(self):
    3034          """\
    3035          Update the session registry stati of all session profiles.
    3036
    3037          """
    3038          for profile_name in self.client_connected_profiles(return_profile_names=True):
    3039              self.__update_sessionregistry_status_by_profile_name(profile_name)
    3040      __update_sessionregistry_status_all_profiles = update_sessionregistry_status_all_profiles
    3041
    3042
    3043 -    def update_cache_by_profile_name(self, profile_name, cache_types=('sessions'), update_sessions=None, update_desktops=None, update_mounts=None):
    3044          """\
    3045          Update the session list cache by profile name.
    3046
    3047          @param profile_name: the X2Go session profile name
    3048          @type profile_name: C{str}
    3049          @param cache_types: specify what cache type to update (available: C{sessions}, C{desktops}, C{mounts})
    3050          @type cache_types: C{tuple} or C{list}
    3051          @param update_sessions: instead of giving a list of cache types, plainly say C{True} here, if
    3052              you want to update sessions in the session list cache.
    3053          @type update_sessions: C{bool}
    3054          @param update_desktops: instead of giving a list of cache types, plainly say C{True} here, if
    3055              you want to update available desktops in the desktop list cache.
    3056          @type update_desktops: C{bool}
    3057          @param update_mounts: instead of giving a list of cache types, plainly say C{True} here, if
    3058              you want to update mounted shares in the mount list cache.
    3059          @type update_mounts: C{bool}
    3060
    3061          """
    3062          if self.listsessions_cache is not None:
    3063              _update_sessions = ('sessions' in cache_types) or update_sessions
    3064              _update_desktops = ('desktops' in cache_types) or update_desktops
    3065              _update_mounts = ('mounts' in cache_types) or update_mounts
    3066              try:
    3067                  self.listsessions_cache.update(profile_name, update_sessions=_update_sessions, update_desktops=_update_desktops, update_mounts=_update_mounts, )
    3068              except x2go_exceptions.X2GoControlSessionException:
    3069                  c_sessions = self.client_connected_sessions_of_profile_name(profile_name, return_objects=True)
    3070                  if len(c_sessions) and c_sessions[0].connected: self.HOOK_on_control_session_death(profile_name)
    3071                  self.disconnect_profile(profile_name)
    3072      __update_cache_by_profile_name = update_cache_by_profile_name
    3073
    3074 -    def update_cache_by_session_uuid(self, session_uuid, cache_types=('sessions'), update_sessions=None, update_desktops=None, update_mounts=None):
    3075          """\
    3076          Update the session list cache of a specific L{X2GoSession} instance with
    3077          session identifier <session_uuid>.
    3078
    3079          @param session_uuid: the X2Go session's UUID registry hash
    3080          @type session_uuid: C{str}
    3081          @param cache_types: specify what cache type to update (available: C{sessions}, C{desktops}, C{mounts})
    3082          @type cache_types: C{tuple} or C{list}
    3083          @param update_sessions: instead of giving a list of cache types, plainly say C{True} here, if
    3084              you want to update sessions in the session list cache.
    3085          @type update_sessions: C{bool}
    3086          @param update_desktops: instead of giving a list of cache types, plainly say C{True} here, if
    3087              you want to update available desktops in the desktop list cache.
    3088          @type update_desktops: C{bool}
    3089          @param update_mounts: instead of giving a list of cache types, plainly say C{True} here, if
    3090              you want to update mounted shares in the mount list cache.
    3091          @type update_mounts: C{bool}
    3092
    3093          """
    3094          profile_name = self.get_session_profile_name(session_uuid)
    3095          self.__update_cache_by_profile_name(profile_name,
    3096                                              cache_types=cache_types,
    3097                                              update_sessions=update_sessions,
    3098                                              update_desktops=update_desktops,
    3099                                              update_mounts=update_mounts,
    3100                                             )
    3101      __update_cache_by_session_uuid = update_cache_by_session_uuid
    3102
    3103 -    def update_cache_all_profiles(self, cache_types=('sessions'), update_sessions=None, update_desktops=None, update_mounts=None):
    3104          """\
    3105          Update the session list cache of all session profiles.
    3106
    3107          @param cache_types: specify what cache type to update (available: C{sessions}, C{desktops}, C{mounts})
    3108          @type cache_types: C{tuple} or C{list}
    3109          @param update_sessions: instead of giving a list of cache types, plainly say C{True} here, if
    3110              you want to update sessions in the session list cache.
    3111          @type update_sessions: C{bool}
    3112          @param update_desktops: instead of giving a list of cache types, plainly say C{True} here, if
    3113              you want to update available desktops in the desktop list cache.
    3114          @type update_desktops: C{bool}
    3115          @param update_mounts: instead of giving a list of cache types, plainly say C{True} here, if
    3116              you want to update mounted shares in the mount list cache.
    3117          @type update_mounts: C{bool}
    3118
    3119          """
    3120          if self.listsessions_cache is not None:
    3121              for profile_name in self.client_connected_profiles(return_profile_names=True):
    3122                  self.__update_cache_by_profile_name(profile_name,
    3123                                                      cache_types=cache_types,
    3124                                                      update_sessions=update_sessions,
    3125                                                      update_desktops=update_desktops,
    3126                                                      update_mounts=update_mounts,
    3127                                                     )
    3128
    3129              # remove profiles that are not connected any more from cache object
    3130              self.listsessions_cache.check_cache()
    3131
    3132      __update_cache_all_profiles = update_cache_all_profiles
    3133
    3134 -    def register_available_server_sessions_by_profile_name(self, profile_name, re_register=False, skip_pubapp_sessions=False):
    3135          """\
    3136          Register available sessions that are found on the X2Go server the profile
    3137          of name C{profile_name} is connected to.
    3138
    3139          @param profile_name: the X2Go session profile name
    3140          @type profile_name: C{str}
    3141          @param re_register: re-register available sessions, needs to be done after session profile changes
    3142          @type re_register: C{bool}
    3143          @param skip_pubapp_sessions: Do not auto-register published applications sessions.
    3144          @type skip_pubapp_sessions: C{bool}
    3145
    3146          """
    3147          if profile_name not in self.client_connected_profiles(return_profile_names=True):
    3148              return
    3149          session_list = self._X2GoClient__list_sessions(profile_name=profile_name,
    3150                                                         update_sessionregistry=False,
    3151                                                         register_sessions=False,
    3152                                                        )
    3153          try:
    3154              self.session_registry.register_available_server_sessions(profile_name, session_list=session_list, re_register=re_register, skip_pubapp_sessions=skip_pubapp_sessions)
    3155          except x2go_exceptions.X2GoControlSessionException, e:
    3156              c_sessions = self.client_connected_sessions_of_profile_name(profile_name, return_objects=True)
    3157              if len(c_sessions) and c_sessions[0].connected: self.HOOK_on_control_session_death(profile_name)
    3158              self.disconnect_profile(profile_name)
    3159              raise e
    3160      __register_available_server_sessions_by_profile_name = register_available_server_sessions_by_profile_name
    3161
    3162 -    def register_available_server_sessions_by_session_uuid(self, session_uuid, skip_pubapp_sessions=False):
    3163          """\
    3164          Register available sessions that are found on the X2Go server that the L{X2GoSession} instance
    3165          with session identifier <session_uuid> is connected to.
    3166
    3167          @param session_uuid: the X2Go session's UUID registry hash
    3168          @type session_uuid: C{str}
    3169          @param skip_pubapp_sessions: Do not auto-register published applications sessions.
    3170          @type skip_pubapp_sessions: C{bool}
    3171
    3172          """
    3173          profile_name = self.get_session_profile_name(session_uuid)
    3174          self.__register_available_server_sessions_by_profile_name(profile_name, skip_pubapp_sessions=skip_pubapp_sessions)
    3175      __register_available_server_sessions_by_session_uuid = register_available_server_sessions_by_session_uuid
    3176
    3177 -    def register_available_server_sessions_all_profiles(self, skip_pubapp_sessions=False):
    3178          """\
    3179          Register all available sessions found on an X2Go server for each session profile.
    3180
    3181          @param skip_pubapp_sessions: Do not auto-register published applications sessions.
    3182          @type skip_pubapp_sessions: C{bool}
    3183
    3184          """
    3185          for profile_name in self.client_connected_profiles(return_profile_names=True):
    3186              try:
    3187                  self.__register_available_server_sessions_by_profile_name(profile_name, skip_pubapp_sessions=skip_pubapp_sessions)
    3188              except x2go_exceptions.X2GoSessionRegistryException:
    3189                  pass
    3190      __register_available_server_sessions_all_profiles = register_available_server_sessions_all_profiles
    3191