Tue, 12 Sep 2017 18:55:25 +0200
Refactored some JSON handling code into server and client base classes.
# -*- coding: utf-8 -*- # Copyright (c) 2017 Detlev Offenbach <detlev@die-offenbachs.de> # """ Module implementing the refactoring client interface to rope. """ from __future__ import unicode_literals import sys import os sys.path.insert(0, os.path.dirname(__file__)) if sys.version_info[0] >= 3: path = os.path.join(os.path.dirname(__file__), 'rope_py3') else: path = os.path.join(os.path.dirname(__file__), 'rope_py2') sys.path.insert(0, path) ##try: ## bytes = unicode ## import StringIO as io # __IGNORE_EXCEPTION__ ##except NameError: ## import io # __IGNORE_WARNING__ ## ##import socket ##import select ##import traceback ##import time ##import json import rope.base.project from JsonClient import JsonClient class RefactoringClient(JsonClient): """ Class implementing the refactoring client interface to rope. """ def __init__(self, host, port, projectPath): """ Constructor @param host ip address the background service is listening @type str @param port port of the background service @type int @param projectPath path to the project @type str """ super(RefactoringClient, self).__init__(host, port) ## self.__connection = socket.create_connection((host, port)) from FileSystemCommands import RefactoringClientFileSystemCommands self.__fsCommands = RefactoringClientFileSystemCommands(self) self.__projectpath = projectPath self.__project = rope.base.project.Project( self.__projectpath, fscommands=self.__fsCommands) def handleCall(self, method, params): """ Public method to handle a method call from the server. @param method requested method name @type str @param params dictionary with method specific parameters @type dict """ ## if "filename" in params and sys.version_info[0] == 2: ## params["filename"] = params["filename"].encode( ## sys.getfilesystemencoding()) if method == "ping": self.sendJson("pong", {}) ## ## def sendJson(self, command, params): ## """ ## Public 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' ## self.__connection.sendall(cmd.encode('utf8', 'backslashreplace')) ## ## def __receiveJson(self): ## """ ## Private method to receive a JSON encode command and data from the ## server. ## """ ## line = self.__connection.recv(1024 * 1024, socket.MSG_PEEK) # 1M buffer ## ## eol = line.find(b'\n') ## ## if eol >= 0: ## size = eol + 1 ## ## # Now we know how big the line is, read it for real. ## line = self.__connection.recv(size).decode( ## 'utf8', 'backslashreplace') ## try: ## commandDict = json.loads(line.strip()) ## except (TypeError, ValueError) as err: ## self.sendJson("ClientException", { ## "ExceptionType": "ProtocolError", ## "ExceptionValue": str(err), ## "ProtocolData": line.strip(), ## }) ## return ## ## method = commandDict["method"] ## params = commandDict["params"] ## self.handleCall(method, params) ## ## def run(self): ## """ ## Public method implementing the main loop of the client. ## """ ## try: ## while True: ## try: ## rrdy, wrdy, xrdy = select.select( ## [self.__connection], [], []) ## except (select.error, KeyboardInterrupt, socket.error): ## # just carry on ## continue ## ## if self.__connection in rrdy: ## self.__receiveJson() ## ## except Exception: ## exctype, excval, exctb = sys.exc_info() ## tbinfofile = io.StringIO() ## traceback.print_tb(exctb, None, tbinfofile) ## tbinfofile.seek(0) ## tbinfo = tbinfofile.read() ## del exctb ## self.sendJson("ClientException", { ## "ExceptionType": str(exctype), ## "ExceptionValue": str(excval), ## "Traceback": tbinfo, ## }) ## ## # Give time to process latest response on server side ## time.sleep(0.5) ## self.__connection.shutdown(socket.SHUT_RDWR) ## self.__connection.close() if __name__ == '__main__': if len(sys.argv) != 4: print('Host, port and project path parameters are missing. Abort.') sys.exit(1) host, port, projectPath = sys.argv[1:] client = RefactoringClient(host, int(port), projectPath) # Start the main loop client.run() # # eflag: noqa = M801