RefactoringRope/Refactoring.py

branch
server_client_variant
changeset 163
6a9e7b37a18b
parent 162
55eaaed9d590
child 164
121d426d4ed7
diff -r 55eaaed9d590 -r 6a9e7b37a18b RefactoringRope/Refactoring.py
--- 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

eric ide

mercurial