Package x2go :: Module client

[frames] | no frames]

# Source Code for Module x2go.client

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