Mon, 10 Jun 2024 15:42:05 +0200
Introduced a remote server request handler base class to get rid of redundant code.
--- a/src/eric7/RemoteServer/EricRequestCategory.py Mon Jun 10 11:41:34 2024 +0200 +++ b/src/eric7/RemoteServer/EricRequestCategory.py Mon Jun 10 15:42:05 2024 +0200 @@ -20,9 +20,10 @@ Debugger = 2 Coverage = 3 - Echo = 253 - Server = 254 - Error = 255 # only sent by the server to report an issue + Echo = 252 + Server = 253 + Error = 254 # only sent by the server to report an issue + Generic = 255 # user/plugins may define own categories starting with this value UserCategory = 1024
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/eric7/RemoteServer/EricServerBaseRequestHandler.py Mon Jun 10 15:42:05 2024 +0200 @@ -0,0 +1,72 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2024 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Module implementing the request handler base class of the eric-ide server. +""" + +from .EricRequestCategory import EricRequestCategory + + +class EricServerBaseRequestHandler: + """ + Class implementing the request handler base class of the eric-ide server. + """ + + def __init__(self, server): + """ + Constructor + + @param server reference to the eric-ide server object + @type EricServer + """ + self._server = server + + self._category = EricRequestCategory.Generic + # must be changed by derived classes + + self._requestMethodMapping = {} + # must be filled by derived classes + + def handleRequest(self, request, params, reqestUuid): + """ + Public method handling the received file system requests. + + @param request request name + @type str + @param params dictionary containing the request parameters + @type dict + @param reqestUuid UUID of the associated request as sent by the eric IDE + @type str + """ + try: + result = self._requestMethodMapping[request](params) + if result is not None: + self._server.sendJson( + category=self._category, + reply=request, + params=result, + reqestUuid=reqestUuid, + ) + + except KeyError: + self.sendError(request=request, reqestUuid=reqestUuid) + + def sendError(self, request, reqestUuid=""): + """ + Public method to send an error report to the IDE. + + @param request request name + @type str + @param reqestUuid UUID of the associated request as sent by the eric IDE + (defaults to "", i.e. no UUID received) + @type str + """ + self._server.sendJson( + category=self._category, + reply=request, + params={"Error": f"Request type '{request}' is not supported."}, + reqestUuid=reqestUuid, + )
--- a/src/eric7/RemoteServer/EricServerCoverageRequestHandler.py Mon Jun 10 11:41:34 2024 +0200 +++ b/src/eric7/RemoteServer/EricServerCoverageRequestHandler.py Mon Jun 10 15:42:05 2024 +0200 @@ -13,9 +13,10 @@ from eric7.SystemUtilities import FileSystemUtilities from .EricRequestCategory import EricRequestCategory +from .EricServerBaseRequestHandler import EricServerBaseRequestHandler -class EricServerCoverageRequestHandler: +class EricServerCoverageRequestHandler(EricServerBaseRequestHandler): """ Class implementing the code coverage request handler of the eric-ide server. """ @@ -27,9 +28,11 @@ @param server reference to the eric-ide server object @type EricServer """ - self.__server = server + super().__init__(server) - self.__requestMethodMapping = { + self._category = EricRequestCategory.Coverage + + self._requestMethodMapping = { "LoadData": self.__loadCoverageData, "AnalyzeFile": self.__analyzeFile, "AnalyzeFiles": self.__analyzeFiles, @@ -38,32 +41,9 @@ self.__cover = None - def handleRequest(self, request, params, reqestUuid): - """ - Public method handling the received file system requests. - - @param request request name - @type str - @param params dictionary containing the request parameters - @type dict - @param reqestUuid UUID of the associated request as sent by the eric IDE - @type str - """ - try: - result = self.__requestMethodMapping[request](params) - self.__server.sendJson( - category=EricRequestCategory.Coverage, - reply=request, - params=result, - reqestUuid=reqestUuid, - ) - - except KeyError: - self.__server.sendJson( - category=EricRequestCategory.Coverage, - reply=request, - params={"Error": f"Request type '{request}' is not supported."}, - ) + ############################################################################ + ## Coverage related methods below + ############################################################################ def __loadCoverageData(self, params): """
--- a/src/eric7/RemoteServer/EricServerDebuggerRequestHandler.py Mon Jun 10 11:41:34 2024 +0200 +++ b/src/eric7/RemoteServer/EricServerDebuggerRequestHandler.py Mon Jun 10 15:42:05 2024 +0200 @@ -16,9 +16,10 @@ import types from .EricRequestCategory import EricRequestCategory +from .EricServerBaseRequestHandler import EricServerBaseRequestHandler -class EricServerDebuggerRequestHandler: +class EricServerDebuggerRequestHandler(EricServerBaseRequestHandler): """ Class implementing the debugger request handler of the eric-ide server. """ @@ -30,9 +31,11 @@ @param server reference to the eric-ide server object @type EricServer """ - self.__server = server + super().__init__(server) - self.__requestMethodMapping = { + self._category = EricRequestCategory.Debugger + + self._requestMethodMapping = { "StartClient": self.__startClient, "StopClient": self.__stopClient, "DebugClientCommand": self.__relayDebugClientCommand, @@ -65,38 +68,10 @@ data = types.SimpleNamespace( name="server", acceptHandler=self.__acceptDbgClientConnection ) - self.__server.getSelector().register( + self._server.getSelector().register( self.__socket, selectors.EVENT_READ, data=data ) - def handleRequest(self, request, params, reqestUuid): - """ - Public method handling the received debugger requests. - - @param request request name - @type str - @param params dictionary containing the request parameters - @type dict - @param reqestUuid UUID of the associated request as sent by the eric IDE - @type str - """ - try: - result = self.__requestMethodMapping[request](params) - if result: - self.__server.sendJson( - category=EricRequestCategory.Debugger, - reply=request, - params=result, - reqestUuid=reqestUuid, - ) - - except KeyError: - self.__server.sendJson( - category=EricRequestCategory.Debugger, - reply="DebuggerRequestError", - params={"Error": f"Request type '{request}' is not supported."}, - ) - ####################################################################### ## DebugServer like methods. ####################################################################### @@ -119,9 +94,7 @@ address=address, handler=self.__serviceDbgClientConnection, ) - self.__server.getSelector().register( - connection, selectors.EVENT_READ, data=data - ) + self._server.getSelector().register(connection, selectors.EVENT_READ, data=data) def __serviceDbgClientConnection(self, key): """ @@ -132,7 +105,7 @@ @type selectors.SelectorKey """ sock = key.fileobj - data = self.__server.receiveJsonCommand(sock) + data = self._server.receiveJsonCommand(sock) if data is None: # socket was closed by debug client @@ -155,7 +128,7 @@ # 2. pass on the data to the eric-ide jsonStr = json.dumps(data) # - print("Client Response:", jsonStr) - self.__server.sendJson( + self._server.sendJson( category=EricRequestCategory.Debugger, reply="DebugClientResponse", params={"response": jsonStr}, @@ -164,7 +137,7 @@ # 3. process debug client messages after relaying if method == "ResponseExit": for sock in list(self.__connections.values()): - if not self.__server.isSocketClosed(sock): + if not self._server.isSocketClosed(sock): self.__clientSocketDisconnected(sock) def __clientSocketDisconnected(self, sock): @@ -174,7 +147,7 @@ @param sock reference to the disconnected socket @type socket.socket """ - self.__server.getSelector().unregister(sock) + self._server.getSelector().unregister(sock) address = sock.getpeername() print( # noqa: M801 @@ -184,7 +157,7 @@ for debuggerId in list(self.__connections): if self.__connections[debuggerId] is sock: del self.__connections[debuggerId] - self.__server.sendJson( + self._server.sendJson( category=EricRequestCategory.Debugger, reply="DebugClientDisconnected", params={"debugger_id": debuggerId}, @@ -204,7 +177,7 @@ """ Private method to handle exiting of the main debug client. """ - self.__server.sendJson( + self._server.sendJson( category=EricRequestCategory.Debugger, reply="MainClientExited", params={"debugger_id": self.__mainClientId if self.__mainClientId else ""}, @@ -221,13 +194,13 @@ while self.__pendingConnections: sock = self.__pendingConnections.pop() commandDict = self.__prepareClientCommand("RequestShutdown", {}) - self.__server.sendJsonCommand(commandDict, sock) + self._server.sendJsonCommand(commandDict, sock) self.__shutdownSocket("", sock) while self.__connections: debuggerId, sock = self.__connections.popitem() commandDict = self.__prepareClientCommand("RequestShutdown", {}) - self.__server.sendJsonCommand(commandDict, sock) + self._server.sendJsonCommand(commandDict, sock) self.__shutdownSocket(debuggerId, sock) # reinitialize @@ -243,12 +216,12 @@ @param sock reference to the socket @type socket.socket """ - self.__server.getSelector().unregister(sock) + self._server.getSelector().unregister(sock) sock.shutdown(socket.SHUT_RDWR) sock.close() if debuggerId: - self.__server.sendJson( + self._server.sendJson( category=EricRequestCategory.Debugger, reply="DebugClientDisconnected", params={"debugger_id": debuggerId}, @@ -297,7 +270,7 @@ ipaddr, port = self.__socket.getsockname() args = [ params["interpreter"] if params["interpreter"] else sys.executable, - debugClient + debugClient, ] args.extend(params["arguments"]) args.extend([str(port), "True", ipaddr]) @@ -346,11 +319,11 @@ if debuggerId == "<<all>>": # broadcast to all connected debug clients for sock in self.__connections.values(): - self.__server.sendJsonCommand(jsonStr, sock) + self._server.sendJsonCommand(jsonStr, sock) else: try: # noqa: Y105 sock = self.__connections[debuggerId] - self.__server.sendJsonCommand(jsonStr, sock) + self._server.sendJsonCommand(jsonStr, sock) except KeyError: pass # - print(f"Command for unknown debugger ID '{debuggerId}' received.")
--- a/src/eric7/RemoteServer/EricServerFileSystemRequestHandler.py Mon Jun 10 11:41:34 2024 +0200 +++ b/src/eric7/RemoteServer/EricServerFileSystemRequestHandler.py Mon Jun 10 15:42:05 2024 +0200 @@ -17,9 +17,10 @@ from eric7.SystemUtilities import FileSystemUtilities from .EricRequestCategory import EricRequestCategory +from .EricServerBaseRequestHandler import EricServerBaseRequestHandler -class EricServerFileSystemRequestHandler: +class EricServerFileSystemRequestHandler(EricServerBaseRequestHandler): """ Class implementing the file system request handler of the eric-ide server. """ @@ -31,9 +32,11 @@ @param server reference to the eric-ide server object @type EricServer """ - self.__server = server + super().__init__(server) - self.__requestMethodMapping = { + self._category = EricRequestCategory.FileSystem + + self._requestMethodMapping = { "GetPathSep": self.__getPathSeparator, "Chdir": self.__chdir, "Getcwd": self.__getcwd, @@ -54,37 +57,30 @@ "ShutilRmtree": self.__shutilRmtree, } - def handleRequest(self, request, params, reqestUuid): + def sendError(self, request, reqestUuid=""): """ - Public method handling the received file system requests. + Public method to send an error report to the IDE. @param request request name @type str - @param params dictionary containing the request parameters - @type dict @param reqestUuid UUID of the associated request as sent by the eric IDE + (defaults to "", i.e. no UUID received) @type str """ - try: - result = self.__requestMethodMapping[request](params) - self.__server.sendJson( - category=EricRequestCategory.FileSystem, - reply=request, - params=result, - reqestUuid=reqestUuid, - ) + self._server.sendJson( + category=self._category, + reply=request, + params={ + "ok": False, + "error": f"Request type '{request}' is not supported.", + "info": list(self._requestMethodMapping.keys()), + }, + reqestUuid=reqestUuid, + ) - except KeyError: - self.__server.sendJson( - category=EricRequestCategory.FileSystem, - reply=request, - params={ - "ok": False, - "error": f"Request type '{request}' is not supported.", - "info": list(self.__requestMethodMapping.keys()), - }, - reqestUuid=reqestUuid, - ) + ############################################################################ + ## File system related methods below + ############################################################################ def __getPathSeparator(self, params): # noqa: U100 """