diff -r 2114cc7275e8 -r a596cf392291 src/eric7/RemoteServerInterface/EricServerFileSystemInterface.py --- a/src/eric7/RemoteServerInterface/EricServerFileSystemInterface.py Sat Feb 17 19:46:33 2024 +0100 +++ b/src/eric7/RemoteServerInterface/EricServerFileSystemInterface.py Sun Feb 18 12:23:14 2024 +0100 @@ -9,12 +9,11 @@ import base64 import contextlib -import fnmatch import os import re import stat -from PyQt6.QtCore import QEventLoop, QObject +from PyQt6.QtCore import QEventLoop, QObject, pyqtSlot from eric7.RemoteServer.EricRequestCategory import EricRequestCategory from eric7.SystemUtilities import FileSystemUtilities @@ -37,6 +36,11 @@ super().__init__(parent=serverInterface) self.__serverInterface = serverInterface + self.__serverInterface.connectionStateChanged.connect( + self.__connectionStateChanged + ) + + self.__serverPathSep = self.__getPathSep() def __hasMagic(self, pathname): """ @@ -52,6 +56,54 @@ match = self._MagicCheck.search(pathname) return match is not None + @pyqtSlot(bool) + def __connectionStateChanged(self, connected): + """ + Private slot handling a change of the server connection state. + + @param connected flag indicating a connected state + @type bool + """ + if connected: + if not bool(self.__serverPathSep): + self.__serverPathSep = self.__getPathSep() + else: + self.__serverPathSep = "" + + def __getPathSep(self): + """ + Private method to get the path separator of the connected server. + """ + loop = QEventLoop() + sep = "" + + def callback(reply, params): + """ + Function to handle the server reply + + @param reply name of the server reply + @type str + @param params dictionary containing the reply data + @type dict + """ + nonlocal sep + + if reply == "GetPathSep": + sep = params["separator"] + loop.quit() + + if self.__serverInterface.isServerConnected(): + self.__serverInterface.sendJson( + category=EricRequestCategory.FileSystem, + request="GetPathSep", + params={}, + callback=callback, + ) + + loop.exec() + + return sep + def getcwd(self): """ Public method to get the current working directory of the eric-ide server. @@ -663,6 +715,101 @@ return False, "Not connected to an 'eric-ide' server." ####################################################################### + ## Methods for splitting or joining remote path names. + ## + ## These are simplified variants of the os.path functions. If the + ## 'eric-ide' server is not connected, the os.path functions are used. + ####################################################################### + + def separator(self): + """ + Public method to return the server side path separator string. + + @return path separator + @rtype str + """ + return self.__serverPathSep + + def join(self, a, *p): + """ + Public method to join two or more path name components using the path separator + of the server side. + + @param a first path component + @type str + @param *p list of additional path components + @type list of str + @return joined path name + @rtype str + """ + if self.__serverInterface.isServerConnected(): + path = a + for b in p: + if b.startswith(self.__serverPathSep): + path = b + elif not path or path.endswith(self.__serverPathSep): + path += b + else: + path += self.__serverPathSep + b + return path + + else: + return os.path.join(a, *p) + + def split(self, p): + """ + Public method to split a path name. + + @param p path name to be split + @type str + @return tuple containing head and tail, where tail is everything after the last + path separator. + @rtype tuple of (str, str) + """ + if self.__serverInterface.isServerConnected(): + i = p.rfind(self.__serverPathSep) + 1 + head, tail = p[:i], p[i:] + if head and head != self.__serverPathSep * len(head): + head = head.rstrip(self.__serverPathSep) + return head, tail + + else: + return os.path.split(p) + + def splitext(self, p): + """ + Public method to split a path name into a root part and an extension. + + @param p path name to be split + @type str + @return tuple containing the root part and the extension + @rtype tuple of (str, str) + """ + return os.path.splitext(p) + + def dirname(self, p): + """ + Public method to extract the directory component of a path name. + + @param p path name + @type str + @return directory component + @rtype str + """ + return self.split(p)[0] + + def basename(self, p): + """ + Public method to extract the final component of a path name. + + @param p path name + @type str + @return final component + @rtype str + """ + return self.split(p)[1] + + ####################################################################### ## Methods for reading and writing files #######################################################################