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

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


The branch, release/0.4.0.x has been updated
       via  fc277361b4e764ef8f5a9b9c66fbd61b0c7cad40 (commit)
      from  9818ac0840cc6df753e4c354a8461b31f89c6af9 (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/session.py  |  244 +++++++++++++++++++++++++++++-------------------------
 2 files changed, 131 insertions(+), 115 deletions(-)

The diff of changes is:
diff --git a/debian/changelog b/debian/changelog
index 50fa388..156035b 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -53,6 +53,8 @@ python-x2go (0.2.1.0-0~x2go1) UNRELEASED; urgency=low
     - Catch exceptions where a user tries to resume a session that has
       just been removed from the session list on the server (race
       condition).
+    - Consolidating management of shared and unshared client-side
+      folders.
   * /debian/rules:
     + Allow package build on systems with missing dh_python2.
   * /debian/control:
diff --git a/x2go/session.py b/x2go/session.py
index 5027a64..a399514 100644
--- a/x2go/session.py
+++ b/x2go/session.py
@@ -317,7 +317,7 @@ class X2goSession(object):
         self.terminal_params = {}
         self.sshproxy_params = {}
         self.update_params(params)
-        self.shared_folders = []
+        self.shared_folders = {}
 
         self.session_environment = {}
         self.server_features = []
@@ -371,6 +371,59 @@ class X2goSession(object):
         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 __str__(self):
+        return self.__get_uuid()
+
+    def __repr__(self):
+        result = 'X2goSession('
+        for p in dir(self):
+            if '__' in p or not p in self.__dict__ or type(p) is types.InstanceType: continue
+            result += p + '=' + str(self.__dict__[p]) + ','
+        result = result.strip(',')
+        return result + ')'
+
+    def __call__(self):
+        return self.__get_uuid()
+
+    def __del__(self):
+        """\
+        Class destructor.
+
+        """
+        if self.has_control_session() and self.has_terminal_session():
+            self.get_control_session().dissociate(self.get_terminal_session())
+
+        if self.has_control_session():
+            if self.keep_controlsession_alive:
+                # regenerate this session instance for re-usage if this is the last session for a certain session profile
+                # and keep_controlsession_alive is set to True...
+                self.virgin = True
+                self.activated = False
+                self.connected = self.is_connected()
+                self.running = None
+                self.suspended = None
+                self.terminated = None
+                self._current_status = {
+                    'timestamp': time.time(),
+                    'server': self.server,
+                    'virgin': self.virgin,
+                    'connected': self.connected,
+                    'running': self.running,
+                    'suspended': self.suspended,
+                    'terminated': self.terminated,
+                    'faulty': self.faulty,
+                }
+                self._last_status = None
+                self.session_name = None
+
+            else:
+                self.get_control_session().__del__()
+                self.control_session = None
+
+        if self.has_terminal_session():
+            self.get_terminal_session().__del__()
+            self.terminal_session = None
+
     def get_client_instance(self):
         """\
         Return parent L{X2goClient} instance if avaiable.
@@ -649,59 +702,6 @@ class X2goSession(object):
             raise x2go_exceptions.X2goProfileException('Unknown session profile option: %s.' % option)
     __get_session_profile_option = get_session_profile_option
 
-    def __str__(self):
-        return self.__get_uuid()
-
-    def __repr__(self):
-        result = 'X2goSession('
-        for p in dir(self):
-            if '__' in p or not p in self.__dict__ or type(p) is types.InstanceType: continue
-            result += p + '=' + str(self.__dict__[p]) + ','
-        result = result.strip(',')
-        return result + ')'
-
-    def __call__(self):
-        return self.__get_uuid()
-
-    def __del__(self):
-        """\
-        Class destructor.
-
-        """
-        if self.has_control_session() and self.has_terminal_session():
-            self.get_control_session().dissociate(self.get_terminal_session())
-
-        if self.has_control_session():
-            if self.keep_controlsession_alive:
-                # regenerate this session instance for re-usage if this is the last session for a certain session profile
-                # and keep_controlsession_alive is set to True...
-                self.virgin = True
-                self.activated = False
-                self.connected = self.is_connected()
-                self.running = None
-                self.suspended = None
-                self.terminated = None
-                self._current_status = {
-                    'timestamp': time.time(),
-                    'server': self.server,
-                    'virgin': self.virgin,
-                    'connected': self.connected,
-                    'running': self.running,
-                    'suspended': self.suspended,
-                    'terminated': self.terminated,
-                    'faulty': self.faulty,
-                }
-                self._last_status = None
-                self.session_name = None
-
-            else:
-                self.get_control_session().__del__()
-                self.control_session = None
-
-        if self.has_terminal_session():
-            self.get_terminal_session().__del__()
-            self.terminal_session = None
-
     def update_params(self, params):
         """\
         This method can be used to modify L{X2goSession} parameters after the
@@ -2420,12 +2420,12 @@ class X2goSession(object):
 
         # 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 = copy.deepcopy(self._restore_exported_folders)
+            for folder in [ sf for sf in self.shared_folders.keys() if self.shared_folders[sf]['status'] in ('new', 'mounted') ]:
                 _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]
+                if folder in [ sf for sf in self.shared_folders.keys() if self.shared_folders[sf]['status'] == 'unmounted' ]:
+                    del _exported_folders[unicode(folder)]
             self._restore_exported_folders = _exported_folders
 
     def share_local_folder(self, local_path=None, folder_name=None, update_exported_folders=True):
@@ -2450,16 +2450,30 @@ class X2goSession(object):
         # compat for Python-X2Go (<=0.1.1.6)
         if folder_name: local_path=folder_name
 
+        retval = False
         if self.has_terminal_session():
             if self.is_folder_sharing_available() and self.is_master_session():
+
+                # for the sake of non-blocking I/O: let's pretend the action has already been successful
+                if self.shared_folders.has_key(unicode(local_path)):
+                    self.shared_folders[unicode(local_path)]['status'] = 'mounted'
+                else:
+                    self.shared_folders.update({ unicode(local_path): { 'status': 'new', 'mountpoint': '', }, })
                 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
-                return False
+                    retval = True
+                else:
+                    # remove local_path from folder again if the mounting process failed
+                    if self.shared_folders[unicode(local_path)]['status'] == 'new':
+                        del self.shared_folders[unicode(local_path)]
+                    else:
+                        self.shared_folders[unicode(local_path)]['status'] = 'unmounted'
+
         else:
             raise x2go_exceptions.X2goSessionException('this X2goSession object does not have any associated terminal')
+        return retval
+
     __share_local_folder = share_local_folder
 
     def share_all_local_folders(self, update_exported_folders=True):
@@ -2487,19 +2501,19 @@ class X2goSession(object):
                             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, update_exported_folders=True):
+    def unshare_local_folder(self, local_path=None, update_exported_folders=True):
         """\
-        Unshare all local folders mounted within this X2Go session.
+        Unshare a local folder that is 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 local_path: the full path to an existing folder on the local
+            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}
 
@@ -2510,36 +2524,31 @@ class X2goSession(object):
         @raise X2goSessionException: if this L{X2goSession} does not have an associated terminal session
 
         """
+        retval = False
         if self.has_terminal_session():
-            if self.is_folder_sharing_available() and self.is_master_session():
-                if force_all:
-                    retval = self.terminal_session.unshare_all_local_folders()
-                    if retval:
-                        self.shared_folders = []
-                    return retval
-                else:
+            if self.is_folder_sharing_available() and self.is_master_session() and local_path in self.shared_folders.keys():
+
+                # for the sake of non-blocking I/O: let's pretend the action has already been successful
+                self.shared_folders[unicode(local_path)]['status'] = 'unmounted'
+                if self.terminal_session.unshare_local_folder(local_path=local_path):
                     retval = True
-                    for _shared_folder in self.shared_folders:
-                        if self.terminal_session.unshare_local_folder(_shared_folder):
-                            self.shared_folders.remove(_shared_folder)
-                        else:
-                            retval = False
-                    if update_exported_folders:
-                        self._update_restore_exported_folders()
-                    return retval
+                else:
+                    # if unmounting failed restore the status with ,,mounted'', not sure if that works ok...
+                    self.shared_folders[unicode(local_path)]['status'] = 'mounted'
+
         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, update_exported_folders=True):
+        return retval
+    __unshare_local_folder = unshare_local_folder
+
+    def unshare_all_local_folders(self, force_all=False, update_exported_folders=True):
         """\
-        Unshare a local folder that is mounted within this X2Go session.
+        Unshare all local folders mounted within this X2Go session.
 
-        @param local_path: the full path to an existing folder on the local
-            file system that is mounted in this X2Go session and shall be
-            unmounted
-        @type local_path: C{str}
+        @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}
 
@@ -2550,19 +2559,25 @@ class X2goSession(object):
         @raise X2goSessionException: if this L{X2goSession} does not have an associated terminal session
 
         """
-        retval = False
         if self.has_terminal_session():
-            if self.is_folder_sharing_available() and self.is_master_session() and local_path in self.shared_folders:
-                if self.terminal_session.unshare_local_folder(local_path=local_path):
-                    self.shared_folders.remove(local_path)
+            if self.is_folder_sharing_available() and self.is_master_session():
+                if force_all:
+                    retval = self.terminal_session.unshare_all_local_folders()
+                    if retval:
+                        self.shared_folders = {}
+                    return retval
+                else:
                     retval = True
-                if retval and update_exported_folders:
-                    self._update_restore_exported_folders()
+                    _shared_folders = copy.deepcopy(self.shared_folders)
+                    for _folder in _shared_folders.keys():
+                        retval = self.unshare_local_folder(_folder, update_exported_folders=False) and retval
+                    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 retval
-    __unshare_local_folder = unshare_local_folder
+        return False
+    __unshare_all_local_folders = unshare_all_local_folders
 
     def get_shared_folders(self, check_list_mounts=False, mounts=None):
         """\
@@ -2585,11 +2600,9 @@ class X2goSession(object):
                 mounts = self.list_mounts()
             _defacto_mounts = [ unicode(m.split('|')[1].split('/')[-1]) for m in mounts ]
 
-            _expected_mounts = {}
-            for shared_folder in self.shared_folders:
+            for shared_folder in self.shared_folders.keys():
 
                 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(' ', '_')
@@ -2598,30 +2611,31 @@ class X2goSession(object):
                     _mount_point = shared_folder.replace('/', '_')
                     _mount_point = _mount_point.replace(' ', '_')
 
-                _expected_mounts[unicode(_mount_point)] = shared_folder
+                self.shared_folders[shared_folder]['status'] = 'mounted'
+                self.shared_folders[shared_folder]['mountpoint'] = unicode(_mount_point)
 
-            ### such a feature as below would be nice but the mapping between a mountpoint and the related
-            ### local folder path is not bijective
-            #
-            # add any new found mount reported by the server
-            #for m in _defacto_mounts:
-            #    if m not in _expected_mounts.keys():
-            #        self.shared_folders.append(_expected_mounts[m])
+            for m in _defacto_mounts:
+                for sf in self.shared_folders.keys():
+                    if self.shared_folders[sf]['mountpoint'] == m:
+                        self.shared_folders[sf]['status'] = 'mounted'
+                        break
 
             unshared_folders = False
-            for m in _expected_mounts.keys():
+            for sf in self.shared_folders.keys():
+                m = self.shared_folders[sf]['mountpoint']
                 if m not in _defacto_mounts:
                     try:
-                        self.shared_folders.remove(_expected_mounts[m])
-                        unshared_folders = True
-                        self.logger('Detected server-side unsharing of client-side folder for profile %s: %s:' % (self.get_profile_name(), _expected_mounts[m]), loglevel=log.loglevel_INFO)
+                        if self.shared_folders[sf]['status'] != 'new':
+                            self.shared_folders[sf]['status'] = 'unmounted'
+                            unshared_folders = True
+                        self.logger('Detected server-side unsharing of client-side folder for profile %s: %s:' % (self.get_profile_name(), sf), loglevel=log.loglevel_INFO)
                     except IndexError:
                         pass
 
             if unshared_folders:
                 self._update_restore_exported_folders()
 
-        return [ unicode(s) for s in self.shared_folders ]
+        return [ unicode(sf) for sf in self.shared_folders if self.shared_folders[sf]['status'] in ('new', 'mounted') ]
     __get_shared_folders = get_shared_folders
 
     def is_locked(self):


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