--- a/RefactoringRope/Refactoring.py Mon Sep 11 19:55:45 2017 +0200 +++ b/RefactoringRope/Refactoring.py Tue Sep 12 18:55:25 2017 +0200 @@ -24,21 +24,21 @@ import rope.base.libutils import rope.base.exceptions -from PyQt5.QtCore import pyqtSlot, QProcess from PyQt5.QtWidgets import QMenu, QApplication, QDialog, QAction from PyQt5.Qsci import QsciScintilla -from PyQt5.QtNetwork import QTcpServer, QHostAddress from E5Gui.E5Application import e5App from E5Gui import E5MessageBox from E5Gui.E5Action import E5Action +from .JsonServer import JsonServer + import Utilities import Preferences # TODO: rename this (and the module) to RefactoringServer once done -class Refactoring(QTcpServer): +class Refactoring(JsonServer): """ Class implementing the refactoring interface to rope. """ @@ -61,32 +61,8 @@ self.__mainMenu = None self.__helpDialog = None - self.__refactoringProcess = None - self.__refactoringConnection = None - - # Rope objects - # TODO: move this to RefactoringClient -## self.__project = None - from FileSystemCommands import E5FileSystemCommands self.__fsCommands = E5FileSystemCommands(self.__e5project) - - # setup the network interface - networkInterface = Preferences.getDebugger("NetworkInterface") - if networkInterface == "all" or '.' in networkInterface: - # IPv4 - self.__hostAddress = '127.0.0.1' - else: - # IPv6 - self.__hostAddress = '::1' - self.listen(QHostAddress(self.__hostAddress)) - - self.newConnection.connect(self.__handleNewConnection) - - port = self.serverPort() - ## Note: Need the port if started external in debugger: - print('Refactoring server listening on: {0:d}'.format(port)) - # __IGNORE_WARNING__ def initActions(self): """ @@ -2242,18 +2218,14 @@ else: interpreter = "" if interpreter: - process = self.__startRefactoringClient(interpreter) - if process is None: + ok = self.__startRefactoringClient(interpreter) + if not ok: self.__ui.appendToStderr(self.tr( "Project language '{0}' is not supported because" " the configured interpreter could not be started." " Refactoring is disabled." ).format(self.__projectLanguage)) else: - self.__refactoringProcess = process -## import rope.base.project -## self.__project = rope.base.project.Project( -## self.__projectpath, fscommands=self.__fsCommands) for act in self.actions: act.setEnabled(True) else: @@ -2270,10 +2242,7 @@ for act in self.actions: act.setEnabled(False) - self.__stopRefactoringClient() -## if self.__project is not None: -## self.__project.close() -## self.__project = None + self.stopClient() self.__projectopen = False self.__projectpath = '' @@ -2359,83 +2328,18 @@ ## Methods below handle the network connection ####################################################################### - @pyqtSlot() - def __handleNewConnection(self): - """ - Private slot for new incomming connections from the refactoring client. - """ - if self.__refactoringConnection is not None: - self.__refactoringConnection.close() - self.__refactoringConnection = None - - connection = self.nextPendingConnection() - if not connection.isValid(): - return - - self.__refactoringConnection = connection - connection.readyRead.connect(self.__receiveJson) - connection.disconnected.connect(self.__handleDisconnect) - - self.__sendJson("ping", {}) - - @pyqtSlot() - def __handleDisconnect(self): - """ - Private slot handling a disconnect of the refactoring client. - """ - if self.__refactoringConnection is not None: - self.__refactoringConnection.close() - - self.__refactoringConnection = None - - @pyqtSlot() - def __receiveJson(self): - """ - Private slot handling received data from the refactoring client. + def handleCall(self, method, params): """ - while self.__refactoringConnection and \ - self.__refactoringConnection.canReadLine(): - data = self.__refactoringConnection.readLine() - jsonLine = bytes(data).decode() - - print("Refactoring Server: ", jsonLine) ##debug - - self.__processJson(jsonLine) - continue - - def __processJson(self, jsonStr): - """ - Private method to process the JSON serialized client data. + Public method to handle a method call from the client. - @param jsonStr string containing the data structure received - from the refactoring client - @type str - """ - import json + Note: This is an empty implementation that must be overridden in + derived classes. - try: - clientDict = json.loads(jsonStr.strip()) - except (TypeError, ValueError) as err: - E5MessageBox.critical( - None, - self.tr("Refactoring Protocol Error"), - self.tr("""<p>The response received from the refactoring""" - """ client could not be decoded. Please report""" - """ this issue with the received data to the""" - """ eric bugs email address.</p>""" - """<p>Error: {0}</p>""" - """<p>Data:<br/>{0}</p>""").format( - str(err), Utilities.html_encode(jsonStr.strip())), - E5MessageBox.StandardButtons( - E5MessageBox.Ok)) - return - - method = clientDict["method"] - params = clientDict["params"] - - print("Method:", method) - print("Params:", params) - + @param method requested method name + @type str + @param params dictionary with method specific parameters + @type dict + """ if method == "pong": pass @@ -2475,56 +2379,16 @@ elif method == "FileSystemCommand": self.__fsCommands.processFileSystemCommand(params) - def __sendJson(self, command, params): - """ - Private method to send a single refactoring command to the client. - - @param command command name to be sent - @type str - @param params dictionary of named parameters for the command - @type dict - """ - import json - - commandDict = { - "jsonrpc": "2.0", - "method": command, - "params": params, - } - cmd = json.dumps(commandDict) + '\n' - if self.__refactoringConnection is not None: - self.__refactoringConnection.write( - cmd.encode('utf8', 'backslashreplace')) - def __startRefactoringClient(self, interpreter): """ Private method to start the refactoring client. @param interpreter interpreter to be used for the refactoring client @type str - @return reference to the refactoring client process + @return flag indicating a successful client start + @rtype bool """ - if interpreter == "" or not Utilities.isinpath(interpreter): - return None - client = os.path.join(os.path.dirname(__file__), "RefactoringClient.py") - proc = QProcess() - proc.setProcessChannelMode(QProcess.ForwardedChannels) - args = [client, self.__hostAddress, str(self.serverPort()), - self.__projectpath] - proc.start(interpreter, args) - if not proc.waitForStarted(10000): - proc = None - - return proc - - def __stopRefactoringClient(self): - """ - Private method to stop the refactoring client process. - """ - self.__refactoringProcess.close() - self.__refactoringProcess = None - -# -# eflag: noqa = M801 + ok = self.startClient(interpreter, client, [self.__projectpath]) + return ok