RefactoringRope/RefactoringClient.py

branch
server_client_variant
changeset 163
6a9e7b37a18b
parent 162
55eaaed9d590
child 164
121d426d4ed7
equal deleted inserted replaced
162:55eaaed9d590 163:6a9e7b37a18b
17 path = os.path.join(os.path.dirname(__file__), 'rope_py3') 17 path = os.path.join(os.path.dirname(__file__), 'rope_py3')
18 else: 18 else:
19 path = os.path.join(os.path.dirname(__file__), 'rope_py2') 19 path = os.path.join(os.path.dirname(__file__), 'rope_py2')
20 sys.path.insert(0, path) 20 sys.path.insert(0, path)
21 21
22 try: 22 ##try:
23 bytes = unicode 23 ## bytes = unicode
24 import StringIO as io # __IGNORE_EXCEPTION__ 24 ## import StringIO as io # __IGNORE_EXCEPTION__
25 except NameError: 25 ##except NameError:
26 import io # __IGNORE_WARNING__ 26 ## import io # __IGNORE_WARNING__
27 27 ##
28 import socket 28 ##import socket
29 import select 29 ##import select
30 import traceback 30 ##import traceback
31 import time 31 ##import time
32 import json 32 ##import json
33 33
34 import rope.base.project 34 import rope.base.project
35 35
36 from JsonClient import JsonClient
36 37
37 class RefactoringClient(object): 38
39 class RefactoringClient(JsonClient):
38 """ 40 """
39 Class implementing the refactoring client interface to rope. 41 Class implementing the refactoring client interface to rope.
40 """ 42 """
41 def __init__(self, host, port, projectPath): 43 def __init__(self, host, port, projectPath):
42 """ 44 """
47 @param port port of the background service 49 @param port port of the background service
48 @type int 50 @type int
49 @param projectPath path to the project 51 @param projectPath path to the project
50 @type str 52 @type str
51 """ 53 """
52 self.__connection = socket.create_connection((host, port)) 54 super(RefactoringClient, self).__init__(host, port)
55 ## self.__connection = socket.create_connection((host, port))
53 56
54 from FileSystemCommands import RefactoringClientFileSystemCommands 57 from FileSystemCommands import RefactoringClientFileSystemCommands
55 self.__fsCommands = RefactoringClientFileSystemCommands(self) 58 self.__fsCommands = RefactoringClientFileSystemCommands(self)
56 59
57 self.__projectpath = projectPath 60 self.__projectpath = projectPath
58 self.__project = rope.base.project.Project( 61 self.__project = rope.base.project.Project(
59 self.__projectpath, fscommands=self.__fsCommands) 62 self.__projectpath, fscommands=self.__fsCommands)
60 63
61 def __processJson(self, jsonStr): 64 def handleCall(self, method, params):
62 """ 65 """
63 Public method to handle a command serialized as a JSON string. 66 Public method to handle a method call from the server.
64 67
65 @param jsonStr string containing the command received from the IDE 68 @param method requested method name
66 @type str 69 @type str
70 @param params dictionary with method specific parameters
71 @type dict
67 """ 72 """
68 try: 73 ## if "filename" in params and sys.version_info[0] == 2:
69 commandDict = json.loads(jsonStr.strip()) 74 ## params["filename"] = params["filename"].encode(
70 except (TypeError, ValueError) as err: 75 ## sys.getfilesystemencoding())
71 self.sendJson("ClientException", {
72 "ExceptionType": "ProtocolError",
73 "ExceptionValue": str(err),
74 "ProtocolData": jsonStr.strip(),
75 })
76 return
77
78 method = commandDict["method"]
79 params = commandDict["params"]
80 if "filename" in params and sys.version_info[0] == 2:
81 params["filename"] = params["filename"].encode(
82 sys.getfilesystemencoding())
83 76
84 if method == "ping": 77 if method == "ping":
85 self.sendJson("pong", {}) 78 self.sendJson("pong", {})
86 79 ##
87 def sendJson(self, command, params): 80 ## def sendJson(self, command, params):
88 """ 81 ## """
89 Public method to send a single refactoring command to the client. 82 ## Public method to send a single refactoring command to the client.
90 83 ##
91 @param command command name to be sent 84 ## @param command command name to be sent
92 @type str 85 ## @type str
93 @param params dictionary of named parameters for the command 86 ## @param params dictionary of named parameters for the command
94 @type dict 87 ## @type dict
95 """ 88 ## """
96 import json 89 ## import json
97 90 ##
98 commandDict = { 91 ## commandDict = {
99 "jsonrpc": "2.0", 92 ## "jsonrpc": "2.0",
100 "method": command, 93 ## "method": command,
101 "params": params, 94 ## "params": params,
102 } 95 ## }
103 cmd = json.dumps(commandDict) + '\n' 96 ## cmd = json.dumps(commandDict) + '\n'
104 self.__connection.sendall(cmd.encode('utf8', 'backslashreplace')) 97 ## self.__connection.sendall(cmd.encode('utf8', 'backslashreplace'))
105 98 ##
106 def __receiveJson(self): 99 ## def __receiveJson(self):
107 """ 100 ## """
108 Private method to receive a JSON encode command and data from the 101 ## Private method to receive a JSON encode command and data from the
109 server. 102 ## server.
110 """ 103 ## """
111 line = self.__connection.recv(1024 * 1024, socket.MSG_PEEK) # 1M buffer 104 ## line = self.__connection.recv(1024 * 1024, socket.MSG_PEEK) # 1M buffer
112 105 ##
113 eol = line.find(b'\n') 106 ## eol = line.find(b'\n')
114 107 ##
115 if eol >= 0: 108 ## if eol >= 0:
116 size = eol + 1 109 ## size = eol + 1
117 110 ##
118 # Now we know how big the line is, read it for real. 111 ## # Now we know how big the line is, read it for real.
119 line = self.__connection.recv(size).decode( 112 ## line = self.__connection.recv(size).decode(
120 'utf8', 'backslashreplace') 113 ## 'utf8', 'backslashreplace')
121 self.__processJson(line) 114 ## try:
122 115 ## commandDict = json.loads(line.strip())
123 def run(self): 116 ## except (TypeError, ValueError) as err:
124 """ 117 ## self.sendJson("ClientException", {
125 Public method implementing the main loop of the client. 118 ## "ExceptionType": "ProtocolError",
126 """ 119 ## "ExceptionValue": str(err),
127 try: 120 ## "ProtocolData": line.strip(),
128 while True: 121 ## })
129 try: 122 ## return
130 rrdy, wrdy, xrdy = select.select( 123 ##
131 [self.__connection], [], []) 124 ## method = commandDict["method"]
132 except (select.error, KeyboardInterrupt, socket.error): 125 ## params = commandDict["params"]
133 # just carry on 126 ## self.handleCall(method, params)
134 continue 127 ##
135 128 ## def run(self):
136 if self.__connection in rrdy: 129 ## """
137 self.__receiveJson() 130 ## Public method implementing the main loop of the client.
138 131 ## """
139 except Exception: 132 ## try:
140 exctype, excval, exctb = sys.exc_info() 133 ## while True:
141 tbinfofile = io.StringIO() 134 ## try:
142 traceback.print_tb(exctb, None, tbinfofile) 135 ## rrdy, wrdy, xrdy = select.select(
143 tbinfofile.seek(0) 136 ## [self.__connection], [], [])
144 tbinfo = tbinfofile.read() 137 ## except (select.error, KeyboardInterrupt, socket.error):
145 del exctb 138 ## # just carry on
146 self.sendJson("ClientException", { 139 ## continue
147 "ExceptionType": str(exctype), 140 ##
148 "ExceptionValue": str(excval), 141 ## if self.__connection in rrdy:
149 "Traceback": tbinfo, 142 ## self.__receiveJson()
150 }) 143 ##
151 144 ## except Exception:
152 # Give time to process latest response on server side 145 ## exctype, excval, exctb = sys.exc_info()
153 time.sleep(0.5) 146 ## tbinfofile = io.StringIO()
154 self.__connection.shutdown(socket.SHUT_RDWR) 147 ## traceback.print_tb(exctb, None, tbinfofile)
155 self.__connection.close() 148 ## tbinfofile.seek(0)
149 ## tbinfo = tbinfofile.read()
150 ## del exctb
151 ## self.sendJson("ClientException", {
152 ## "ExceptionType": str(exctype),
153 ## "ExceptionValue": str(excval),
154 ## "Traceback": tbinfo,
155 ## })
156 ##
157 ## # Give time to process latest response on server side
158 ## time.sleep(0.5)
159 ## self.__connection.shutdown(socket.SHUT_RDWR)
160 ## self.__connection.close()
156 161
157 if __name__ == '__main__': 162 if __name__ == '__main__':
158 if len(sys.argv) != 4: 163 if len(sys.argv) != 4:
159 print('Host, port and project path parameters are missing. Abort.') 164 print('Host, port and project path parameters are missing. Abort.')
160 sys.exit(1) 165 sys.exit(1)

eric ide

mercurial