[X2Go-Commits] python-x2go.git - release/0.4.0.x (branch) updated: 0.2.0.10-82-g8d835dc

X2Go dev team git-admin at x2go.org
Tue Jan 7 16:18:21 CET 2014


The branch, release/0.4.0.x has been updated
       via  8d835dcdec07d7f620a25cbcd4aafd88a1a044c7 (commit)
      from  19142c8cf8165b553780cfc33048df5ae11890ef (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
-----------------------------------------------------------------------

Summary of changes:
 debian/changelog                |    2 +
 x2go/backends/profiles/_file.py |   42 ++++++++++++--
 x2go/cache.py                   |    1 +
 x2go/client.py                  |   36 +++++++++++-
 x2go/defaults.py                |    2 +-
 x2go/registry.py                |   10 ++++
 x2go/session.py                 |  121 +++++++++++++++++++++++++++++----------
 x2go/utils.py                   |    1 +
 8 files changed, 178 insertions(+), 37 deletions(-)

The diff of changes is:
diff --git a/debian/changelog b/debian/changelog
index 3cd247b..871adcb 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -48,6 +48,8 @@ python-x2go (0.2.1.0-0~x2go1) UNRELEASED; urgency=low
       get_published_applications() of control sessions.
     - Implement some internal locking for X2goSession objects.
     - Add option to disable auto-registration of pubapp sessions.
+    - Implement functionality for restoring mounted shares on session
+      resumption / re-start. Sponsored by Dick Kniep, LinDix NL.
   * /debian/rules:
     + Allow package build on systems with missing dh_python2.
   * /debian/control:
diff --git a/x2go/backends/profiles/_file.py b/x2go/backends/profiles/_file.py
index 586f262..24c2912 100644
--- a/x2go/backends/profiles/_file.py
+++ b/x2go/backends/profiles/_file.py
@@ -28,6 +28,7 @@ __NAME__ = 'x2gosessionprofiles-pylib'
 
 import copy
 import types
+import re
 
 # Python X2Go modules
 from x2go.defaults import X2GO_SESSIONPROFILES_CONFIGFILES as _X2GO_SESSIONPROFILES_CONFIGFILES
@@ -177,12 +178,14 @@ class X2goSessionProfilesFILE(inifiles.X2goIniFile):
         # we have to handle the get_type method separately...
         return self.get_profile_option_type(key)
 
-    def get_profile_config(self, profile_id_or_name=None, profile_id=None):
+    def get_profile_config(self, profile_id_or_name=None, parameter=None, profile_id=None):
         """\
         The configuration options for a single session profile.
 
         @param profile_id_or_name: either profile ID or profile name is accepted
         @type profile_id_or_name: C{str}
+        @param parameter: if specified, only the value for the given parameter is returned
+        @type parameter: C{str}
         @param profile_id: profile ID (fast than specifying C{profile_id_or_name})
         @type profile_id: C{str}
 
@@ -194,6 +197,27 @@ class X2goSessionProfilesFILE(inifiles.X2goIniFile):
         _profile_config = {}
         for option in self.iniConfig.options(_profile_id):
             _profile_config[option] = self.get(_profile_id, option, key_type=self.get_profile_option_type(option))
+
+        if parameter is not None:
+            if parameter in _profile_config.keys():
+
+                value = _profile_config[parameter]
+
+                if parameter == 'export':
+                    _strvalue = value.replace(',', ';').strip().strip('"').strip().strip(';').strip()
+                    value = {}
+                    if _strvalue:
+                        _export_paths = _strvalue.split(';')
+                        for _path in _export_paths:
+                            if not re.match('.*:(0|1)$', _path): _path = '%s:1' % _path
+                            _auto_export_path = re.match('.*:1$', _path) and True or False
+                            _export_path = ':'.join(_path.split(':')[:-1])
+                            value[_export_path] = _auto_export_path
+
+                return value
+
+            else:
+                raise X2goProfileException('no such session profile parameter: %s' % parameter)
         return _profile_config
 
     def default_profile_config(self):
@@ -362,17 +386,27 @@ class X2goSessionProfilesFILE(inifiles.X2goIniFile):
         @type value: any type, depends on the session profile option
 
         """
-        profile_id = section
+        profile_id = self.check_profile_id_or_name(section)
         if key == 'name':
             profile_name = value
-            current_profile_name = self.get_value(section, key)
+            current_profile_name = self.get_value(profile_id, key)
             if not profile_name:
                 raise X2goProfileException('profile name for profile id %s may not be empty' % profile_id)
             else:
                 if profile_name != current_profile_name and profile_name in self.profile_names:
                     raise X2goProfileException('a profile of name ,,%s'' already exists' % profile_name)
             self._cached_profile_names = []
-        inifiles.X2goIniFile.update_value(self, section, key, value)
+
+        if key == 'export' and type(value) == types.DictType:
+
+            _strvalue = '"'
+            for folder in value.keys():
+                _strvalue += "%s:%s;" % (folder, int(value[folder]))
+            _strvalue += '"'
+            _strvalue = _strvalue.replace('""', '')
+            value = _strvalue
+
+        inifiles.X2goIniFile.update_value(self, profile_id, key, value)
 
     def check_profile_id_or_name(self, profile_id_or_name):
         """\
diff --git a/x2go/cache.py b/x2go/cache.py
index 5d90191..7c73692 100644
--- a/x2go/cache.py
+++ b/x2go/cache.py
@@ -149,6 +149,7 @@ class X2goListSessionsCache(object):
         @raise X2goControlSessionException: if the control session's C{list_mounts} method fails
         """
         try:
+            self.x2go_listsessions_cache[profile_name]['mounts'] = {}
             if self.x2go_listsessions_cache[profile_name]['sessions']:
                 for session_name in self.x2go_listsessions_cache[profile_name]['sessions']:
                     self.x2go_listsessions_cache[profile_name]['mounts'].update(control_session.list_mounts(session_name))
diff --git a/x2go/client.py b/x2go/client.py
index 1dd219b..142e970 100644
--- a/x2go/client.py
+++ b/x2go/client.py
@@ -1919,6 +1919,13 @@ class X2goClient(object):
         Get a list of local folders mounted within X2Go session with session hash <session_uuid>
         from this client.
 
+        @param session_uuid: the X2Go session's UUID registry hash
+        @type session_uuid: C{str}
+        @param profile_name: alternatively, the profile name can be used to get mounted folders of a session connected profile
+        @type profile_name: C{str}
+        @param check_list_mounts: query the server-side mount list for up-to-date information
+        @type check_list_mounts: C{bool}
+
         @return: returns a C{list} of those local folder names that are mounted within X2Go session <session_uuid>.
         @rtype: C{list}
 
@@ -2710,7 +2717,7 @@ class X2goClient(object):
     ### Session profile oriented methods
     ### 
 
-    def get_profile_config(self, profile_id_or_name):
+    def get_profile_config(self, profile_id_or_name, parameter=None):
         """\
         Returns a dictionary with session options and values that represent
         the session profile for C{profile_id_or_name}.
@@ -2718,15 +2725,38 @@ class X2goClient(object):
         @param profile_id_or_name: name or id of an X2Go session profile as found
             in the sessions configuration file
         @type profile_id_or_name: C{str}
+        @param parameter: if specified, only the value for the given parameter is returned
+        @type parameter: C{str}
 
         @return: a Python dictionary with session profile options
-        @rtype: C{dict}
+        @rtype: C{dict} or C{bool}, C{int}, C{str}
 
         """
-        return self.session_profiles.get_profile_config(profile_id_or_name)
+        return self.session_profiles.get_profile_config(profile_id_or_name, parameter=parameter)
     __get_profile_config = get_profile_config
     with_profile_config = get_profile_config
 
+    def set_profile_config(self, profile_id_or_name, parameter, value):
+        """\
+        Set individual session profile parameters for session profile C{profile_id_or_name}.
+
+        @param profile_id_or_name: name or id of an X2Go session profile as found
+            in the sessions configuration file
+        @type profile_id_or_name: C{str}
+        @param parameter: set this parameter with the given C{value}
+        @type parameter: C{str}
+        @param value: set this value for the given C{parameter}
+        @type value: C{bool}, C{int}, C{str}, C{list} or C{dict}
+
+        @return: returns C{True} if this operation has been successful
+        @rtype: C{dict}
+
+        """
+        self.session_profiles.update_value(profile_id_or_name, parameter, value)
+        self.session_profiles.write_user_config = True
+        self.session_profiles.write()
+    __set_profile_config = set_profile_config
+
     def to_profile_id(self, profile_name):
         """\
         Retrieve the session profile ID of the session whose profile name
diff --git a/x2go/defaults.py b/x2go/defaults.py
index b158bb2..58a0615 100644
--- a/x2go/defaults.py
+++ b/x2go/defaults.py
@@ -297,7 +297,7 @@ X2GO_SESSIONPROFILE_DEFAULTS = {
     'iconvto': 'UTF-8', 'iconvfrom': 'UTF-8', 'useiconv': False,
     'usesshproxy': False, 'sshproxyhost': 'proxyhost.mydomain', 'sshproxyport': 22, 'sshproxyuser': '', 'sshproxytunnel': 'localhost:44444:server.mydomain.private:22', 'sshproxykeyfile': '',
     'sshproxytype': 'SSH', 'sshproxysameuser': False, 'sshproxysamepass': False, 'sshproxyautologin': True,
-    'useexports': True, 'fstunnel': True, 'export': '',
+    'useexports': True, 'restoreexports': False, 'fstunnel': True, 'export': '',
     'usemimebox': False, 'mimeboxextensions': '', 'mimeboxaction': 'OPEN',
     'fullscreen': False,
     'width': 800,'height': 600, 'maxdim': False, 'dpi': 96, 'setdpi': False, 'xinerama': False, 'multidisp': False,
diff --git a/x2go/registry.py b/x2go/registry.py
index e7b6732..5b4d67f 100644
--- a/x2go/registry.py
+++ b/x2go/registry.py
@@ -332,6 +332,11 @@ class X2goSessionRegistry(object):
                 # unregister as master session
                 if _profile_name in self.master_sessions.keys():
                     if self.master_sessions[_profile_name] == self(_session_uuid):
+
+                        # save exported folders to session profile config if requested by session profile parameter ,,restoreexports''...
+                        if self.client_instance and self(_session_uuid).restore_shared_local_folders:
+                            self.client_instance.set_profile_config(_profile_name, 'export', self(_session_uuid)._restore_exported_folders)
+
                         self(_session_uuid).unset_master_session()
                         del self.master_sessions[_profile_name]
 
@@ -344,6 +349,11 @@ class X2goSessionRegistry(object):
                 # unregister as master session
                 if _profile_name in self.master_sessions.keys():
                     if self.master_sessions[_profile_name] == self(_session_uuid):
+
+                        # save exported folders to session profile config if requested by session profile parameter ,,restoreexports''...
+                        if self.client_instance and self(_session_uuid).restore_shared_local_folders:
+                            self.client_instance.set_profile_config(_profile_name, 'export', self(_session_uuid)._restore_exported_folders)
+
                         self(_session_uuid).unset_master_session()
                         del self.master_sessions[_profile_name]
 
diff --git a/x2go/session.py b/x2go/session.py
index da67aaf..31d7aea 100644
--- a/x2go/session.py
+++ b/x2go/session.py
@@ -89,7 +89,7 @@ _X2GO_SESSION_PARAMS = ('use_sshproxy', 'sshproxy_reuse_authinfo',
                         'auto_start_or_resume', 'auto_connect',
                         'printing', 'allow_mimebox',
                         'mimebox_extensions', 'mimebox_action',
-                        'allow_share_local_folders', 'share_local_folders',
+                        'allow_share_local_folders', 'share_local_folders', 'restore_shared_local_folders',
                         'control_backend', 'terminal_backend', 'info_backend', 'list_backend', 'proxy_backend', 'settings_backend', 'printing_backend',
                         'client_rootdir', 'sessions_rootdir', 'ssh_rootdir',
                         'keep_controlsession_alive', 'add_to_known_hosts', 'known_hosts', 'forward_sshagent',
@@ -145,6 +145,7 @@ class X2goSession(object):
                  mimebox_action='OPEN',
                  allow_share_local_folders=False,
                  share_local_folders=[],
+                 restore_shared_local_folders=False,
                  control_backend=_X2goControlSession,
                  terminal_backend=_X2goTerminalSession,
                  info_backend=_X2goServerSessionInfo,
@@ -194,6 +195,8 @@ class X2goSession(object):
         @type allow_share_local_folders: C{bool}
         @param share_local_folders: list of local folders to share with the remote X2Go session
         @type share_local_folders: C{list}
+        @param restore_shared_local_folders: store actual list of shared local folders after session has been suspended or terminated
+        @type restore_shared_local_folders: C{bool}
         @param control_backend: X2Go control session backend to use
         @type control_backend: C{class}
         @param terminal_backend: X2Go terminal session backend to use
@@ -276,6 +279,7 @@ class X2goSession(object):
         self.printing = printing
         self.allow_share_local_folders = allow_share_local_folders
         self.share_local_folders = share_local_folders
+        self.restore_shared_local_folders = restore_shared_local_folders
         self.allow_mimebox = allow_mimebox
         self.mimebox_extensions = mimebox_extensions
         self.mimebox_action = mimebox_action
@@ -364,6 +368,9 @@ class X2goSession(object):
         self._progress_status = 0
         self._lock = threading.Lock()
 
+        if self.client_instance and self.restore_shared_local_folders:
+            self._restore_exported_folders = self.client_instance.get_profile_config(self.profile_name, 'export')
+
     def get_client_instance(self):
         """\
         Return parent L{X2goClient} instance if avaiable.
@@ -569,9 +576,9 @@ class X2goSession(object):
             gevent.sleep(1)
 
         if wait:
-            gevent.spawn_later(wait, self.share_all_local_folders)
+            gevent.spawn_later(wait, self.share_all_local_folders, update_exported_folders=False)
         else:
-            gevent.spawn(self.share_all_local_folders)
+            gevent.spawn(self.share_all_local_folders, update_exported_folders=False)
     __set_master_session = set_master_session
 
     def unset_master_session(self):
@@ -581,7 +588,7 @@ class X2goSession(object):
         """
         # unmount shared folders
         if self.has_terminal_session():
-            self.unshare_all_local_folders()
+            self.unshare_all_local_folders(update_exported_folders=False)
         self.master_session = False
     __unset_master_session = unset_master_session
 
@@ -719,6 +726,10 @@ class X2goSession(object):
             del params['share_local_folders'] 
         except KeyError: pass
         try:
+            self.restore_shared_local_folders = params['restore_shared_local_folders']
+            del params['restore_shared_local_folders']
+        except KeyError: pass
+        try:
             self.allow_mimebox = params['allow_mimebox']
             del params['allow_mimebox']
         except KeyError: pass
@@ -1290,6 +1301,7 @@ class X2goSession(object):
         self.terminated = None
         self.faults = None
         self.active = False
+        self._lock.release()
         self.unset_master_session()
         try:
             self.update_status(force_update=True)
@@ -1894,7 +1906,7 @@ class X2goSession(object):
                 self._progress_status = 90
                 progress_event.set()
 
-                # if there is a client instance for X2Go sessions that the client instance will handle the mounting of shared folders
+                # if self.client_instance exists than the folder sharing is handled via the self.set_master_session() evoked by the session registry
                 if (not self.client_instance) and \
                    self._SUPPORTED_FOLDERSHARING and \
                    self.allow_share_local_folders:
@@ -2104,6 +2116,10 @@ class X2goSession(object):
         @raise X2goSessionException: if the session could not be suspended
 
         """
+        _store_shared_folders = {}
+        for folder in self.shared_folders:
+            _store_shared_folders.update({ folder: True })
+
         self._lock.acquire()
         try:
             _retval = self._suspend()
@@ -2111,6 +2127,7 @@ class X2goSession(object):
             raise
         finally:
             self._lock.release()
+
         return _retval
 
     def _suspend(self):
@@ -2137,12 +2154,12 @@ class X2goSession(object):
 
                 self.unset_master_session()
 
-                if self.terminal_session.suspend():
-
-                    self.session_cleanup()
-                    del self.terminal_session
-                    self.terminal_session = None
-                    return True
+                if self.has_terminal_session():
+                    if self.terminal_session.suspend():
+                        self.session_cleanup()
+                        del self.terminal_session
+                        self.terminal_session = None
+                        return True
 
             elif self.has_control_session() and self.session_name:
                 if self.control_session.suspend(session_name=self.session_name):
@@ -2181,6 +2198,7 @@ class X2goSession(object):
             raise
         finally:
             self._lock.release()
+
         return _retval
 
     def _terminate(self):
@@ -2207,11 +2225,12 @@ class X2goSession(object):
 
                 self.unset_master_session()
 
-                if self.terminal_session.terminate():
-                    self.session_cleanup()
-                    del self.terminal_session
-                    self.terminal_session = None
-                    return True
+                if self.has_terminal_session():
+                    if self.terminal_session.terminate():
+                        self.session_cleanup()
+                        del self.terminal_session
+                        self.terminal_session = None
+                        return True
 
             elif self.has_control_session() and self.session_name:
                 if self.control_session.terminate(session_name=self.session_name):
@@ -2397,7 +2416,19 @@ class X2goSession(object):
         return False
     __is_folder_sharing_available = is_folder_sharing_available
 
-    def share_local_folder(self, local_path=None, folder_name=None):
+    def _update_restore_exported_folders(self):
+
+        # remember exported folders for restoring them on session suspension/termination
+        if self.client_instance and self.restore_shared_local_folders:
+            _exported_folders = self.client_instance.get_profile_config(self.profile_name, 'export')
+            for folder in self.shared_folders:
+                _exported_folders.update({ unicode(folder): True })
+            for folder in _exported_folders.keys():
+                if (folder not in self.shared_folders) and _exported_folders[folder]:
+                    del _exported_folders[folder]
+            self._restore_exported_folders = _exported_folders
+
+    def share_local_folder(self, local_path=None, folder_name=None, update_exported_folders=True):
         """\
         Share a local folder with this registered X2Go session.
 
@@ -2406,6 +2437,8 @@ class X2goSession(object):
         @type local_path: C{str}
         @param folder_name: synonymous to C{local_path}
         @type folder_name: C{str}
+        @param update_exported_folders: do an update of the session profile option ,,export'' after the operation
+        @type update_exported_folders: C{bool}
 
         @return: returns C{True} if the local folder has been successfully mounted within
             this X2Go session
@@ -2419,18 +2452,26 @@ class X2goSession(object):
 
         if self.has_terminal_session():
             if self.is_folder_sharing_available() and self.is_master_session():
+                # append local_path to list of shared folders before mounting
+                self.shared_folders.append(local_path)
                 if self.terminal_session.share_local_folder(local_path=local_path):
-                    self.shared_folders.append(local_path)
+                    if update_exported_folders:
+                        self._update_restore_exported_folders()
                     return True
+                # if we failed remove the local_path element again...
+                self.shared_folders.remove(local_path)
                 return False
         else:
             raise x2go_exceptions.X2goSessionException('this X2goSession object does not have any associated terminal')
     __share_local_folder = share_local_folder
 
-    def share_all_local_folders(self):
+    def share_all_local_folders(self, update_exported_folders=True):
         """\
         Share all local folders configured to be mounted within this X2Go session.
 
+        @param update_exported_folders: do an update of the session profile option ,,export'' after the operation
+        @type update_exported_folders: C{bool}
+
         @return: returns C{True} if all local folders could be successfully mounted
             inside this X2Go session
         @rtype: C{bool}
@@ -2444,21 +2485,26 @@ class X2goSession(object):
                         _retval = True
                         for _folder in self.share_local_folders:
                             try:
-                                _retval = self.share_local_folder(_folder) and _retval
+                                _retval = self.share_local_folder(_folder, update_exported_folders=False) and _retval
                             except x2go_exceptions.X2goUserException, e:
                                 self.logger('%s' % str(e), loglevel=log.loglevel_WARN)
+                        if update_exported_folders:
+                            self._update_restore_exported_folders()
+
                 else:
                     self.HOOK_foldersharing_not_available()
         return _retval
     __share_all_local_folders = share_all_local_folders
 
-    def unshare_all_local_folders(self, force_all=False):
+    def unshare_all_local_folders(self, force_all=False, update_exported_folders=True):
         """\
         Unshare all local folders mounted within this X2Go session.
 
         @param force_all: Really unmount _all_ shared folders, including the print spool folder and
             the MIME box spool dir (not recommended).
         @type force_all: C{bool}
+        @param update_exported_folders: do an update of the session profile option ,,export'' after the operation
+        @type update_exported_folders: C{bool}
 
         @return: returns C{True} if all local folders could be successfully unmounted
             inside this X2Go session
@@ -2471,19 +2517,23 @@ class X2goSession(object):
             if self.is_folder_sharing_available() and self.is_master_session():
                 if force_all:
                     self.shared_folders = []
-                    return self.terminal_session.unshare_all_local_folders()
+                    retval = self.terminal_session.unshare_all_local_folders()
+                    return retval
                 else:
+                    _shared_folders = copy.deepcopy(self.shared_folders)
+                    self.shared_folders = []
                     retval = 0
-                    for _shared_folder in self.shared_folders:
+                    for _shared_folder in _shared_folders:
                         retval = retval | self.terminal_session.unshare_local_folder(_shared_folder)
-                    self.shared_folders = []
+                    if update_exported_folders:
+                        self._update_restore_exported_folders()
                     return retval
         else:
             raise x2go_exceptions.X2goSessionException('this X2goSession object does not have any associated terminal')
         return False
     __unshare_all_local_folders = unshare_all_local_folders
 
-    def unshare_local_folder(self, local_path=None):
+    def unshare_local_folder(self, local_path=None, update_exported_folders=True):
         """\
         Unshare a local folder that is mounted within this X2Go session.
 
@@ -2491,6 +2541,9 @@ class X2goSession(object):
             file system that is mounted in this X2Go session and shall be
             unmounted
         @type local_path: C{str}
+        @param update_exported_folders: do an update of the session profile option ,,export'' after the operation
+        @type update_exported_folders: C{bool}
+
         @return: returns C{True} if all local folders could be successfully unmounted
             inside this X2Go session
         @rtype: C{bool}
@@ -2500,10 +2553,18 @@ class X2goSession(object):
         """
         if self.has_terminal_session():
             if self.is_folder_sharing_available() and self.is_master_session() and local_path in self.shared_folders:
+                # update shared_folders before(!) unmounting...
                 self.shared_folders.remove(local_path)
-                return self.terminal_session.unshare_local_folder(local_path=local_path)
+                _retval = self.terminal_session.unshare_local_folder(local_path=local_path)
+                # unmounting failed? Re-add local_patch to shared_folders for now...
+                if not _retval:
+                    self.shared_folders.append(local_path)
+                if _retval and update_exported_folders:
+                    self._update_restore_exported_folders()
         else:
             raise x2go_exceptions.X2goSessionException('this X2goSession object does not have any associated terminal')
+
+        return _retval
     __unshare_local_folder = unshare_local_folder
 
     def get_shared_folders(self, check_list_mounts=False, mounts=None):
@@ -2531,21 +2592,22 @@ class X2goSession(object):
                 _found = False
 
                 for mount in mounts:
+                    if _found: continue
                     mount = mount.split('|')[1]
                     if _X2GOCLIENT_OS == 'Windows':
+
                         _driveletter, _path = os.path.splitdrive(shared_folder)
                         _mount_point = '_windrive_%s%s' % (_driveletter[0], _path.replace('\\', '_'))
                         _mount_point = _mount_point.replace(' ', '_')
 
                         if mount.lower().endswith(_mount_point.lower()):
                             _found = True
-                            break
+
                     else:
                         _mount_point = shared_folder.replace('/', '_')
                         _mount_point = _mount_point.replace(' ', '_')
                         if mount.endswith(_mount_point):
                             _found = True
-                            break
 
                 if not _found:
                     unshared_folders.append(shared_folder)
@@ -2553,11 +2615,12 @@ class X2goSession(object):
             for unshared_folder in unshared_folders:
                 try:
                     self.shared_folders.remove(unshared_folder)
+                    self._update_restore_exported_folders()
                     self.logger('Detected server-side unsharing of client-side folder for profile %s: %s:' % (self.get_profile_name(), shared_folder), loglevel=log.loglevel_INFO)
                 except IndexError:
                     pass
 
-        return self.shared_folders
+        return [ unicode(s) for s in self.shared_folders ]
     __get_shared_folders = get_shared_folders
 
     def is_locked(self):
diff --git a/x2go/utils.py b/x2go/utils.py
index 0a25fd3..ab98120 100644
--- a/x2go/utils.py
+++ b/x2go/utils.py
@@ -186,6 +186,7 @@ def _convert_SessionProfileOptions_2_SessionParams(options):
             'speed': 'link',
             'sshport': 'port',
             'useexports': 'allow_share_local_folders',
+            'restoreexports': 'restore_shared_local_folders',
             'usemimebox': 'allow_mimebox',
             'mimeboxextensions': 'mimebox_extensions',
             'mimeboxaction': 'mimebox_action',


hooks/post-receive
-- 
python-x2go.git (Python X2Go Client API)

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "python-x2go.git" (Python X2Go Client API).




More information about the x2go-commits mailing list