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) |