src/eric7/RemoteServerInterface/EricServerDebuggerInterface.py

branch
server
changeset 10555
08e853c0c77b
child 10561
be23a662d709
diff -r d80184d38152 -r 08e853c0c77b src/eric7/RemoteServerInterface/EricServerDebuggerInterface.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/RemoteServerInterface/EricServerDebuggerInterface.py	Fri Feb 09 19:54:15 2024 +0100
@@ -0,0 +1,190 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2024 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing the file system interface to the eric-ide server.
+"""
+
+from PyQt6.QtCore import QEventLoop, QObject, pyqtSignal, pyqtSlot
+
+from eric7.EricWidgets import EricMessageBox
+from eric7.EricWidgets.EricApplication import ericApp
+from eric7.RemoteServer.EricRequestCategory import EricRequestCategory
+from eric7.SystemUtilities import FileSystemUtilities
+
+
+# TODO: sanitize all file names with FileSystemUtilities.plainFileName()
+class EricServerDebuggerInterface(QObject):
+    """
+    Class implementing the file system interface to the eric-ide server.
+    """
+
+    debugClientResponse = pyqtSignal(str)
+
+    def __init__(self, serverInterface):
+        """
+        Constructor
+
+        @param serverInterface reference to the eric-ide server interface
+        @type EricServerInterface
+        """
+        super().__init__(parent=serverInterface)
+
+        self.__serverInterface = serverInterface
+
+        self.__replyMethodMapping = {
+            "DebuggerRequestError": self.__handleDbgRequestError,
+            "DebugClientResponse": self.__handleDbgClientResponse,
+            "DebugClientDisconnected": self.__handleDbgClientDisconnected,
+            "LastDebugClientExited": self.__handleLastDbgClientExited,
+        }
+
+        # connect some signals
+        self.__serverInterface.remoteDebuggerReply.connect(self.__handleDebuggerReply)
+
+    def sendClientCommand(self, debuggerId, jsonCommand):
+        """
+        Public method to rely a debug client command via the eric-ide server.
+
+        @param debuggerId id of the debug client to send the command to
+        @type str
+        @param jsonCommand JSON encoded command dictionary to be relayed
+        @type str
+        """
+        self.__serverInterface.sendJson(
+            category=EricRequestCategory.Debugger,
+            request="DebugClientCommand",
+            params={"debugger_id": debuggerId, "command": jsonCommand},
+        )
+
+    @pyqtSlot(str, dict)
+    def __handleDebuggerReply(self, reply, params):
+        """
+        Private slot to handle a debugger reply from the eric-ide server.
+
+        @param reply name of the server reply
+        @type str
+        @param params dictionary containing the reply data
+        @type dict
+        """
+        try:
+            self.__replyMethodMapping[reply](params)
+        except KeyError:
+            EricMessageBox.critical(
+                None,
+                self.tr("Unknown Server Reply"),
+                self.tr(
+                    "<p>The eric-ide server debugger interface sent the unknown reply"
+                    " <b>{0}</b>.</p>"
+                ).format(reply),
+            )
+
+    #######################################################################
+    ## Methods for handling of debug client replies.
+    #######################################################################
+
+    def __handleDbgRequestError(self, params):
+        """
+        Private method to handle an error reported by the debugger interface of
+        the eric-ide server.
+
+        @param params dictionary containing the reply data
+        @type dict
+        """
+        EricMessageBox.warning(
+            None,
+            self.tr("Debug Client Command"),
+            self.tr(
+                "<p>The IDE received an error message.</p><p>Error: {0}</p>"
+            ).format(params["Error"]),
+        )
+
+    def __handleDbgClientResponse(self, params):
+        """
+        Private method to handle a response from a debug client connected to the
+        eric-ide server.
+
+        @param params dictionary containing the reply data
+        @type dict
+        """
+        self.debugClientResponse.emit(params["response"])
+
+    def __handleDbgClientDisconnected(self, params):
+        """
+        Private method to handle a debug client disconnect report of the
+        eric-ide server.
+
+        @param params dictionary containing the reply data
+        @type dict
+        """
+        ericApp().getObject("DebugServer").signalClientDisconnected(
+            params["debugger_id"]
+        )
+
+    def __handleLastDbgClientExited(self, params):
+        """
+        Private method to handle a report of the eric-ide server, that the last
+        debug client has disconnected.
+
+        @param params dictionary containing the reply data
+        @type dict
+        """
+        ericApp().getObject("DebugServer").signalLastClientExited()
+
+    #######################################################################
+    ## Methods for sending debug server commands to the eric-ide server.
+    #######################################################################
+
+    def startClient(self, interpreter, originalPathString, args, workingDir=""):
+        """
+        Public method to send a command to start a debug client.
+
+        @param interpreter path of the remote interpreter to be used
+        @type str
+        @param originalPathString original PATH environment variable
+        @type str
+        @param args list of command line parameters for the debug client
+        @type list of str
+        @param workingDir directory to start the debugger client in (defaults to "")
+        @type str (optional)
+        """
+        self.__serverInterface.sendJson(
+            category=EricRequestCategory.Debugger,
+            request="StartClient",
+            params={
+                "interpreter": FileSystemUtilities.plainFileName(interpreter),
+                "path": originalPathString,
+                "arguments": args,
+                "working_dir": FileSystemUtilities.plainFileName(workingDir),
+            },
+        )
+
+    def stopClient(self):
+        """
+        Public method to stop the debug client synchronously.
+        """
+        if self.__serverInterface.isServerConnected():
+            loop = QEventLoop()
+
+            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
+                """
+                if reply == "StopClient":
+                    loop.quit()
+
+            self.__serverInterface.sendJson(
+                category=EricRequestCategory.Debugger,
+                request="StopClient",
+                params={},
+                callback=callback,
+            )
+
+            loop.exec()

eric ide

mercurial