src/eric7/RemoteServerInterface/EricServerFileSystemInterface.py

branch
server
changeset 10546
300487f5f517
parent 10539
4274f189ff78
child 10548
d3e21f44887b
--- a/src/eric7/RemoteServerInterface/EricServerFileSystemInterface.py	Fri Feb 02 14:55:14 2024 +0100
+++ b/src/eric7/RemoteServerInterface/EricServerFileSystemInterface.py	Mon Feb 05 11:15:47 2024 +0100
@@ -7,6 +7,7 @@
 Module implementing the file system interface to the eric-ide server.
 """
 
+import base64
 import contextlib
 
 from PyQt6.QtCore import QEventLoop, QObject
@@ -14,6 +15,7 @@
 from eric7.RemoteServer.EricRequestCategory import EricRequestCategory
 
 
+# TODO: sanitize all file name with FileSystemUtilities.plainFileName()
 class EricServerFileSystemInterface(QObject):
     """
     Class implementing the file system interface to the eric-ide server.
@@ -153,6 +155,142 @@
         loop.exec()
         return listedDirectory, separator, listing
 
+    def stat(self, filename, stNames):
+        """
+        Public method to get the status of a file.
+
+        @param filename name of the file
+        @type str
+        @param stNames list of 'stat_result' members to retrieve
+        @type list of str
+        @return dictionary containing the requested status data
+        @rtype dict
+        @exception OSError raised in case the server reported an issue
+        """
+        loop = QEventLoop()
+        ok = False
+        error = ""
+        stResult = {}
+
+        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 ok, error, stResult
+
+            if reply == "Stat":
+                ok = params["ok"]
+                if ok:
+                    stResult = params["result"]
+                else:
+                    error = params["error"]
+                loop.quit()
+
+        self.__serverInterface.sendJson(
+            category=EricRequestCategory.FileSystem,
+            request="Stat",
+            params={"filename": filename, "st_names": stNames},
+            callback=callback,
+        )
+
+        loop.exec()
+        if not ok:
+            raise OSError(error)
+
+        return stResult
+
+    def exists(self, name):
+        """
+        Public method the existence of a file or directory.
+
+        @param name name of the file or directory
+        @type str
+        @return flag indicating the file existence
+        @rtype bool
+        """
+        loop = QEventLoop()
+        nameExists = False
+
+        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 nameExists
+
+            if reply == "Exists":
+                nameExists = params["exists"]
+                loop.quit()
+
+        self.__serverInterface.sendJson(
+            category=EricRequestCategory.FileSystem,
+            request="Exists",
+            params={"name": name},
+            callback=callback,
+        )
+
+        loop.exec()
+        return nameExists
+
+    def access(self, name, modes):
+        """
+        Public method to test the given access rights to a file or directory.
+
+        The modes to check for are 'read', 'write' or 'execute' or any combination.
+
+        @param name name of the file or directory
+        @type str
+        @param modes list of modes to check for
+        @type str or list of str
+        @return flag indicating the user has the asked for permissions
+        @rtype bool
+        """
+        if not modes:
+            raise ValueError(
+                "At least one of 'read', 'write' or 'execute' must be specified."
+            )
+
+        if isinstance(modes, str):
+            # convert to a list with one element
+            modes = [modes]
+
+        loop = QEventLoop()
+        accessOK = False
+
+        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 accessOK
+
+            if reply == "Access":
+                accessOK = params["ok"]
+                loop.quit()
+
+        self.__serverInterface.sendJson(
+            category=EricRequestCategory.FileSystem,
+            request="Access",
+            params={"name": name, "modes":modes},
+            callback=callback,
+        )
+
+        loop.exec()
+        return accessOK
+
     def mkdir(self, directory):
         """
         Public method to create a new directory on the eric-ide server.
@@ -319,27 +457,103 @@
     ## Methods for reading and writing files
     #######################################################################
 
-    def readFile(self, filename):
+    def readFile(self, filename, create=False):
         """
         Public method to read a file from the eric-ide server.
 
         @param filename name of the file to read
         @type str
-        @return tuple containing an OK flag, the read data and an error string in
-            case of an issue
-        @rtype tuple of (bool, str, str)
+        @param create flag indicating to create an empty file, if it does not exist
+            (defaults to False)
+        @type bool (optional)
+        @return bytes data read from the eric-ide server
+        @rtype bytes
+        @exception OSError raised in case the server reported an issue
         """
-        # TODO: 'readFile()' not implemented yet
+        loop = QEventLoop()
+        ok = False
+        error = ""
+        bText = b""
+
+        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 ok, error, bText
 
-    def writeFile(self, filename, data):
+            if reply == "ReadFile":
+                ok = params["ok"]
+                if ok:
+                    bText = base64.b85decode(
+                        bytes(params["filedata"], encoding="ascii")
+                    )
+                else:
+                    error = params["error"]
+                loop.quit()
+
+        self.__serverInterface.sendJson(
+            category=EricRequestCategory.FileSystem,
+            request="ReadFile",
+            params={"filename": filename, "create": create},
+            callback=callback,
+        )
+
+        loop.exec()
+        if not ok:
+            raise OSError(error)
+
+        return bText
+
+    def writeFile(self, filename, data, withBackup=False):
         """
         Public method to write the data to a file on the eric-ide server.
 
         @param filename name of the file to write
         @type str
         @param data data to be written
-        @type str
-        @return tuple containing an OK flag and an error string in case of an issue
-        @rtype tuple of (bool, str)
+        @type bytes
+        @param withBackup flag indicating to create a backup file first
+            (defaults to False)
+        @type bool (optional)
+        @exception OSError raised in case the server reported an issue
         """
-        # TODO: 'writeFile()' not implemented yet
+        loop = QEventLoop()
+        ok = False
+        error = ""
+
+        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 ok, error
+
+            if reply == "WriteFile":
+                ok = params["ok"]
+                with contextlib.suppress(KeyError):
+                    error = params["error"]
+                loop.quit()
+
+        self.__serverInterface.sendJson(
+            category=EricRequestCategory.FileSystem,
+            request="WriteFile",
+            params={
+                "filename": filename,
+                "filedata": str(base64.b85encode(data), encoding="ascii"),
+                "with_backup": withBackup,
+            },
+            callback=callback,
+        )
+
+        loop.exec()
+        if not ok:
+            raise OSError(error)

eric ide

mercurial