37 @signal editorCommand(hash, fn, message) emitted after an editor command |
37 @signal editorCommand(hash, fn, message) emitted after an editor command |
38 has arrived (string, string, string) |
38 has arrived (string, string, string) |
39 @signal rejected(message) emitted after a connection has been rejected |
39 @signal rejected(message) emitted after a connection has been rejected |
40 (string) |
40 (string) |
41 """ |
41 """ |
|
42 |
42 WaitingForGreeting = 0 |
43 WaitingForGreeting = 0 |
43 ReadingGreeting = 1 |
44 ReadingGreeting = 1 |
44 ReadyForUse = 2 |
45 ReadyForUse = 2 |
45 |
46 |
46 PlainText = 0 |
47 PlainText = 0 |
47 Ping = 1 |
48 Ping = 1 |
48 Pong = 2 |
49 Pong = 2 |
49 Greeting = 3 |
50 Greeting = 3 |
50 GetParticipants = 4 |
51 GetParticipants = 4 |
51 Participants = 5 |
52 Participants = 5 |
52 Editor = 6 |
53 Editor = 6 |
53 Undefined = 99 |
54 Undefined = 99 |
54 |
55 |
55 ProtocolMessage = "MESSAGE" |
56 ProtocolMessage = "MESSAGE" |
56 ProtocolPing = "PING" |
57 ProtocolPing = "PING" |
57 ProtocolPong = "PONG" |
58 ProtocolPong = "PONG" |
58 ProtocolGreeting = "GREETING" |
59 ProtocolGreeting = "GREETING" |
59 ProtocolGetParticipants = "GET_PARTICIPANTS" |
60 ProtocolGetParticipants = "GET_PARTICIPANTS" |
60 ProtocolParticipants = "PARTICIPANTS" |
61 ProtocolParticipants = "PARTICIPANTS" |
61 ProtocolEditor = "EDITOR" |
62 ProtocolEditor = "EDITOR" |
62 |
63 |
63 readyForUse = pyqtSignal() |
64 readyForUse = pyqtSignal() |
64 newMessage = pyqtSignal(str, str) |
65 newMessage = pyqtSignal(str, str) |
65 getParticipants = pyqtSignal() |
66 getParticipants = pyqtSignal() |
66 participants = pyqtSignal(list) |
67 participants = pyqtSignal(list) |
67 editorCommand = pyqtSignal(str, str, str) |
68 editorCommand = pyqtSignal(str, str, str) |
68 rejected = pyqtSignal(str) |
69 rejected = pyqtSignal(str) |
69 |
70 |
70 def __init__(self, parent=None): |
71 def __init__(self, parent=None): |
71 """ |
72 """ |
72 Constructor |
73 Constructor |
73 |
74 |
74 @param parent referenec to the parent object (QObject) |
75 @param parent referenec to the parent object (QObject) |
75 """ |
76 """ |
76 super().__init__(parent) |
77 super().__init__(parent) |
77 |
78 |
78 self.__greetingMessage = self.tr("undefined") |
79 self.__greetingMessage = self.tr("undefined") |
79 self.__username = self.tr("unknown") |
80 self.__username = self.tr("unknown") |
80 self.__serverPort = 0 |
81 self.__serverPort = 0 |
81 self.__state = Connection.WaitingForGreeting |
82 self.__state = Connection.WaitingForGreeting |
82 self.__currentDataType = Connection.Undefined |
83 self.__currentDataType = Connection.Undefined |
86 self.__pingTimer = QTimer(self) |
87 self.__pingTimer = QTimer(self) |
87 self.__pingTimer.setInterval(PingInterval) |
88 self.__pingTimer.setInterval(PingInterval) |
88 self.__pongTime = QTime() |
89 self.__pongTime = QTime() |
89 self.__buffer = QByteArray() |
90 self.__buffer = QByteArray() |
90 self.__client = None |
91 self.__client = None |
91 |
92 |
92 self.readyRead.connect(self.__processReadyRead) |
93 self.readyRead.connect(self.__processReadyRead) |
93 self.disconnected.connect(self.__disconnected) |
94 self.disconnected.connect(self.__disconnected) |
94 self.__pingTimer.timeout.connect(self.__sendPing) |
95 self.__pingTimer.timeout.connect(self.__sendPing) |
95 self.connected.connect(self.__sendGreetingMessage) |
96 self.connected.connect(self.__sendGreetingMessage) |
96 |
97 |
97 def name(self): |
98 def name(self): |
98 """ |
99 """ |
99 Public method to get the connection name. |
100 Public method to get the connection name. |
100 |
101 |
101 @return connection name (string) |
102 @return connection name (string) |
102 """ |
103 """ |
103 return self.__username |
104 return self.__username |
104 |
105 |
105 def serverPort(self): |
106 def serverPort(self): |
106 """ |
107 """ |
107 Public method to get the server port. |
108 Public method to get the server port. |
108 |
109 |
109 @return server port (integer) |
110 @return server port (integer) |
110 """ |
111 """ |
111 return self.__serverPort |
112 return self.__serverPort |
112 |
113 |
113 def setClient(self, client): |
114 def setClient(self, client): |
114 """ |
115 """ |
115 Public method to set the reference to the cooperation client. |
116 Public method to set the reference to the cooperation client. |
116 |
117 |
117 @param client reference to the cooperation client (CooperationClient) |
118 @param client reference to the cooperation client (CooperationClient) |
118 """ |
119 """ |
119 self.__client = client |
120 self.__client = client |
120 |
121 |
121 def setGreetingMessage(self, message, serverPort): |
122 def setGreetingMessage(self, message, serverPort): |
122 """ |
123 """ |
123 Public method to set the greeting message. |
124 Public method to set the greeting message. |
124 |
125 |
125 @param message greeting message (string) |
126 @param message greeting message (string) |
126 @param serverPort port number to include in the message (integer) |
127 @param serverPort port number to include in the message (integer) |
127 """ |
128 """ |
128 self.__greetingMessage = "{0}:{1}".format(message, serverPort) |
129 self.__greetingMessage = "{0}:{1}".format(message, serverPort) |
129 |
130 |
130 def sendMessage(self, message): |
131 def sendMessage(self, message): |
131 """ |
132 """ |
132 Public method to send a message. |
133 Public method to send a message. |
133 |
134 |
134 @param message message to be sent (string) |
135 @param message message to be sent (string) |
135 @return flag indicating a successful send (boolean) |
136 @return flag indicating a successful send (boolean) |
136 """ |
137 """ |
137 if message == "": |
138 if message == "": |
138 return False |
139 return False |
139 |
140 |
140 msg = QByteArray(message.encode("utf-8")) |
141 msg = QByteArray(message.encode("utf-8")) |
141 data = QByteArray("{0}{1}{2}{1}".format( |
142 data = ( |
142 Connection.ProtocolMessage, SeparatorToken, msg.size()) |
143 QByteArray( |
143 .encode("utf-8")) + msg |
144 "{0}{1}{2}{1}".format( |
|
145 Connection.ProtocolMessage, SeparatorToken, msg.size() |
|
146 ).encode("utf-8") |
|
147 ) |
|
148 + msg |
|
149 ) |
144 return self.write(data) == data.size() |
150 return self.write(data) == data.size() |
145 |
151 |
146 def timerEvent(self, evt): |
152 def timerEvent(self, evt): |
147 """ |
153 """ |
148 Protected method to handle timer events. |
154 Protected method to handle timer events. |
149 |
155 |
150 @param evt reference to the timer event (QTimerEvent) |
156 @param evt reference to the timer event (QTimerEvent) |
151 """ |
157 """ |
152 if evt.timerId() == self.__transferTimerId: |
158 if evt.timerId() == self.__transferTimerId: |
153 self.abort() |
159 self.abort() |
154 self.killTimer(self.__transferTimerId) |
160 self.killTimer(self.__transferTimerId) |
155 self.__transferTimerId = 0 |
161 self.__transferTimerId = 0 |
156 |
162 |
157 def __processReadyRead(self): |
163 def __processReadyRead(self): |
158 """ |
164 """ |
159 Private slot to handle the readyRead signal. |
165 Private slot to handle the readyRead signal. |
160 """ |
166 """ |
161 if self.__state == Connection.WaitingForGreeting: |
167 if self.__state == Connection.WaitingForGreeting: |
163 return |
169 return |
164 if self.__currentDataType != Connection.Greeting: |
170 if self.__currentDataType != Connection.Greeting: |
165 self.abort() |
171 self.abort() |
166 return |
172 return |
167 self.__state = Connection.ReadingGreeting |
173 self.__state = Connection.ReadingGreeting |
168 |
174 |
169 if self.__state == Connection.ReadingGreeting: |
175 if self.__state == Connection.ReadingGreeting: |
170 if not self.__hasEnoughData(): |
176 if not self.__hasEnoughData(): |
171 return |
177 return |
172 |
178 |
173 self.__buffer = QByteArray( |
179 self.__buffer = QByteArray(self.read(self.__numBytesForCurrentDataType)) |
174 self.read(self.__numBytesForCurrentDataType)) |
|
175 if self.__buffer.size() != self.__numBytesForCurrentDataType: |
180 if self.__buffer.size() != self.__numBytesForCurrentDataType: |
176 self.abort() |
181 self.abort() |
177 return |
182 return |
178 |
183 |
179 try: |
184 try: |
180 user, serverPort = ( |
185 user, serverPort = str(self.__buffer, encoding="utf-8").split(":") |
181 str(self.__buffer, encoding="utf-8").split(":")) |
|
182 except ValueError: |
186 except ValueError: |
183 self.abort() |
187 self.abort() |
184 return |
188 return |
185 self.__serverPort = int(serverPort) |
189 self.__serverPort = int(serverPort) |
186 |
190 |
187 hostInfo = QHostInfo.fromName(self.peerAddress().toString()) |
191 hostInfo = QHostInfo.fromName(self.peerAddress().toString()) |
188 self.__username = "{0}@{1}@{2}".format( |
192 self.__username = "{0}@{1}@{2}".format( |
189 user, |
193 user, hostInfo.hostName(), self.peerPort() |
190 hostInfo.hostName(), |
|
191 self.peerPort() |
|
192 ) |
194 ) |
193 self.__currentDataType = Connection.Undefined |
195 self.__currentDataType = Connection.Undefined |
194 self.__numBytesForCurrentDataType = 0 |
196 self.__numBytesForCurrentDataType = 0 |
195 self.__buffer.clear() |
197 self.__buffer.clear() |
196 |
198 |
197 if not self.isValid(): |
199 if not self.isValid(): |
198 self.abort() |
200 self.abort() |
199 return |
201 return |
200 |
202 |
201 bannedName = "{0}@{1}".format( |
203 bannedName = "{0}@{1}".format( |
202 user, |
204 user, |
203 hostInfo.hostName(), |
205 hostInfo.hostName(), |
204 ) |
206 ) |
205 Preferences.syncPreferences() |
207 Preferences.syncPreferences() |
206 if bannedName in Preferences.getCooperation("BannedUsers"): |
208 if bannedName in Preferences.getCooperation("BannedUsers"): |
207 self.rejected.emit(self.tr( |
209 self.rejected.emit( |
208 "* Connection attempted by banned user '{0}'.") |
210 self.tr("* Connection attempted by banned user '{0}'.").format( |
209 .format(bannedName)) |
211 bannedName |
|
212 ) |
|
213 ) |
210 self.abort() |
214 self.abort() |
211 return |
215 return |
212 |
216 |
213 if (self.__serverPort != self.peerPort() and |
217 if self.__serverPort != self.peerPort() and not Preferences.getCooperation( |
214 not Preferences.getCooperation("AutoAcceptConnections")): |
218 "AutoAcceptConnections" |
|
219 ): |
215 # don't ask for reverse connections or |
220 # don't ask for reverse connections or |
216 # if we shall accept automatically |
221 # if we shall accept automatically |
217 res = EricMessageBox.yesNo( |
222 res = EricMessageBox.yesNo( |
218 None, |
223 None, |
219 self.tr("New Connection"), |
224 self.tr("New Connection"), |
220 self.tr("""<p>Accept connection from """ |
225 self.tr( |
221 """<strong>{0}@{1}</strong>?</p>""").format( |
226 """<p>Accept connection from """ |
222 user, hostInfo.hostName()), |
227 """<strong>{0}@{1}</strong>?</p>""" |
223 yesDefault=True) |
228 ).format(user, hostInfo.hostName()), |
|
229 yesDefault=True, |
|
230 ) |
224 if not res: |
231 if not res: |
225 self.abort() |
232 self.abort() |
226 return |
233 return |
227 |
234 |
228 if self.__client is not None: |
235 if self.__client is not None: |
229 chatWidget = self.__client.chatWidget() |
236 chatWidget = self.__client.chatWidget() |
230 if chatWidget is not None and not chatWidget.isVisible(): |
237 if chatWidget is not None and not chatWidget.isVisible(): |
231 ericApp().getObject( |
238 ericApp().getObject("UserInterface").activateCooperationViewer() |
232 "UserInterface").activateCooperationViewer() |
239 |
233 |
|
234 if not self.__isGreetingMessageSent: |
240 if not self.__isGreetingMessageSent: |
235 self.__sendGreetingMessage() |
241 self.__sendGreetingMessage() |
236 |
242 |
237 self.__pingTimer.start() |
243 self.__pingTimer.start() |
238 self.__pongTime = QTime.currentTime() |
244 self.__pongTime = QTime.currentTime() |
239 self.__state = Connection.ReadyForUse |
245 self.__state = Connection.ReadyForUse |
240 self.readyForUse.emit() |
246 self.readyForUse.emit() |
241 |
247 |
242 while self.bytesAvailable(): |
248 while self.bytesAvailable(): |
243 if ( |
249 if ( |
244 self.__currentDataType == Connection.Undefined and |
250 self.__currentDataType == Connection.Undefined |
245 not self.__readProtocolHeader() |
251 and not self.__readProtocolHeader() |
246 ): |
252 ): |
247 return |
253 return |
248 |
254 |
249 if not self.__hasEnoughData(): |
255 if not self.__hasEnoughData(): |
250 return |
256 return |
251 |
257 |
252 self.__processData() |
258 self.__processData() |
253 |
259 |
254 def __sendPing(self): |
260 def __sendPing(self): |
255 """ |
261 """ |
256 Private slot to send a ping message. |
262 Private slot to send a ping message. |
257 """ |
263 """ |
258 if self.__pongTime.msecsTo(QTime.currentTime()) > PongTimeout: |
264 if self.__pongTime.msecsTo(QTime.currentTime()) > PongTimeout: |
259 self.abort() |
265 self.abort() |
260 return |
266 return |
261 |
267 |
262 self.write(QByteArray("{0}{1}1{1}p".format( |
268 self.write( |
263 Connection.ProtocolPing, SeparatorToken).encode("utf-8"))) |
269 QByteArray( |
264 |
270 "{0}{1}1{1}p".format(Connection.ProtocolPing, SeparatorToken).encode( |
|
271 "utf-8" |
|
272 ) |
|
273 ) |
|
274 ) |
|
275 |
265 def __sendGreetingMessage(self): |
276 def __sendGreetingMessage(self): |
266 """ |
277 """ |
267 Private slot to send a greeting message. |
278 Private slot to send a greeting message. |
268 """ |
279 """ |
269 greeting = QByteArray(self.__greetingMessage.encode("utf-8")) |
280 greeting = QByteArray(self.__greetingMessage.encode("utf-8")) |
270 data = QByteArray("{0}{1}{2}{1}".format( |
281 data = ( |
271 Connection.ProtocolGreeting, SeparatorToken, greeting.size()) |
282 QByteArray( |
272 .encode("utf-8")) + greeting |
283 "{0}{1}{2}{1}".format( |
|
284 Connection.ProtocolGreeting, SeparatorToken, greeting.size() |
|
285 ).encode("utf-8") |
|
286 ) |
|
287 + greeting |
|
288 ) |
273 if self.write(data) == data.size(): |
289 if self.write(data) == data.size(): |
274 self.__isGreetingMessageSent = True |
290 self.__isGreetingMessageSent = True |
275 |
291 |
276 def __readDataIntoBuffer(self, maxSize=MaxBufferSize): |
292 def __readDataIntoBuffer(self, maxSize=MaxBufferSize): |
277 """ |
293 """ |
278 Private method to read some data into the buffer. |
294 Private method to read some data into the buffer. |
279 |
295 |
280 @param maxSize maximum size of data to read (integer) |
296 @param maxSize maximum size of data to read (integer) |
281 @return size of data read (integer) |
297 @return size of data read (integer) |
282 """ |
298 """ |
283 if maxSize > MaxBufferSize: |
299 if maxSize > MaxBufferSize: |
284 return 0 |
300 return 0 |
285 |
301 |
286 numBytesBeforeRead = self.__buffer.size() |
302 numBytesBeforeRead = self.__buffer.size() |
287 if numBytesBeforeRead == MaxBufferSize: |
303 if numBytesBeforeRead == MaxBufferSize: |
288 self.abort() |
304 self.abort() |
289 return 0 |
305 return 0 |
290 |
306 |
291 while self.bytesAvailable() and self.__buffer.size() < maxSize: |
307 while self.bytesAvailable() and self.__buffer.size() < maxSize: |
292 self.__buffer.append(self.read(1)) |
308 self.__buffer.append(self.read(1)) |
293 if self.__buffer.endsWith(SeparatorToken_b): |
309 if self.__buffer.endsWith(SeparatorToken_b): |
294 break |
310 break |
295 |
311 |
296 return self.__buffer.size() - numBytesBeforeRead |
312 return self.__buffer.size() - numBytesBeforeRead |
297 |
313 |
298 def __dataLengthForCurrentDataType(self): |
314 def __dataLengthForCurrentDataType(self): |
299 """ |
315 """ |
300 Private method to get the data length for the current data type. |
316 Private method to get the data length for the current data type. |
301 |
317 |
302 @return data length (integer) |
318 @return data length (integer) |
303 """ |
319 """ |
304 if (self.bytesAvailable() <= 0 or |
320 if ( |
305 self.__readDataIntoBuffer() <= 0 or |
321 self.bytesAvailable() <= 0 |
306 not self.__buffer.endsWith(SeparatorToken_b)): |
322 or self.__readDataIntoBuffer() <= 0 |
|
323 or not self.__buffer.endsWith(SeparatorToken_b) |
|
324 ): |
307 return 0 |
325 return 0 |
308 |
326 |
309 self.__buffer.chop(len(SeparatorToken_b)) |
327 self.__buffer.chop(len(SeparatorToken_b)) |
310 number = self.__buffer.toInt()[0] |
328 number = self.__buffer.toInt()[0] |
311 self.__buffer.clear() |
329 self.__buffer.clear() |
312 return number |
330 return number |
313 |
331 |
314 def __readProtocolHeader(self): |
332 def __readProtocolHeader(self): |
315 """ |
333 """ |
316 Private method to read the protocol header. |
334 Private method to read the protocol header. |
317 |
335 |
318 @return flag indicating a successful read (boolean) |
336 @return flag indicating a successful read (boolean) |
319 """ |
337 """ |
320 if self.__transferTimerId: |
338 if self.__transferTimerId: |
321 self.killTimer(self.__transferTimerId) |
339 self.killTimer(self.__transferTimerId) |
322 self.__transferTimerId = 0 |
340 self.__transferTimerId = 0 |
323 |
341 |
324 if self.__readDataIntoBuffer() <= 0: |
342 if self.__readDataIntoBuffer() <= 0: |
325 self.__transferTimerId = self.startTimer(TransferTimeout) |
343 self.__transferTimerId = self.startTimer(TransferTimeout) |
326 return False |
344 return False |
327 |
345 |
328 self.__buffer.chop(len(SeparatorToken)) |
346 self.__buffer.chop(len(SeparatorToken)) |
329 protocolHeader = str(self.__buffer, encoding="utf-8") |
347 protocolHeader = str(self.__buffer, encoding="utf-8") |
330 if protocolHeader == Connection.ProtocolPing: |
348 if protocolHeader == Connection.ProtocolPing: |
331 self.__currentDataType = Connection.Ping |
349 self.__currentDataType = Connection.Ping |
332 elif protocolHeader == Connection.ProtocolPong: |
350 elif protocolHeader == Connection.ProtocolPong: |
343 self.__currentDataType = Connection.Editor |
361 self.__currentDataType = Connection.Editor |
344 else: |
362 else: |
345 self.__currentDataType = Connection.Undefined |
363 self.__currentDataType = Connection.Undefined |
346 self.abort() |
364 self.abort() |
347 return False |
365 return False |
348 |
366 |
349 self.__buffer.clear() |
367 self.__buffer.clear() |
350 self.__numBytesForCurrentDataType = ( |
368 self.__numBytesForCurrentDataType = self.__dataLengthForCurrentDataType() |
351 self.__dataLengthForCurrentDataType()) |
|
352 return True |
369 return True |
353 |
370 |
354 def __hasEnoughData(self): |
371 def __hasEnoughData(self): |
355 """ |
372 """ |
356 Private method to check, if enough data is available. |
373 Private method to check, if enough data is available. |
357 |
374 |
358 @return flag indicating availability of enough data (boolean) |
375 @return flag indicating availability of enough data (boolean) |
359 """ |
376 """ |
360 if self.__transferTimerId: |
377 if self.__transferTimerId: |
361 self.killTimer(self.__transferTimerId) |
378 self.killTimer(self.__transferTimerId) |
362 self.__transferTimerId = 0 |
379 self.__transferTimerId = 0 |
363 |
380 |
364 if self.__numBytesForCurrentDataType <= 0: |
381 if self.__numBytesForCurrentDataType <= 0: |
365 self.__numBytesForCurrentDataType = ( |
382 self.__numBytesForCurrentDataType = self.__dataLengthForCurrentDataType() |
366 self.__dataLengthForCurrentDataType()) |
383 |
367 |
384 if ( |
368 if (self.bytesAvailable() < self.__numBytesForCurrentDataType or |
385 self.bytesAvailable() < self.__numBytesForCurrentDataType |
369 self.__numBytesForCurrentDataType <= 0): |
386 or self.__numBytesForCurrentDataType <= 0 |
|
387 ): |
370 self.__transferTimerId = self.startTimer(TransferTimeout) |
388 self.__transferTimerId = self.startTimer(TransferTimeout) |
371 return False |
389 return False |
372 |
390 |
373 return True |
391 return True |
374 |
392 |
375 def __processData(self): |
393 def __processData(self): |
376 """ |
394 """ |
377 Private method to process the received data. |
395 Private method to process the received data. |
378 """ |
396 """ |
379 self.__buffer = QByteArray( |
397 self.__buffer = QByteArray(self.read(self.__numBytesForCurrentDataType)) |
380 self.read(self.__numBytesForCurrentDataType)) |
|
381 if self.__buffer.size() != self.__numBytesForCurrentDataType: |
398 if self.__buffer.size() != self.__numBytesForCurrentDataType: |
382 self.abort() |
399 self.abort() |
383 return |
400 return |
384 |
401 |
385 if self.__currentDataType == Connection.PlainText: |
402 if self.__currentDataType == Connection.PlainText: |
386 self.newMessage.emit( |
403 self.newMessage.emit(self.__username, str(self.__buffer, encoding="utf-8")) |
387 self.__username, str(self.__buffer, encoding="utf-8")) |
|
388 elif self.__currentDataType == Connection.Ping: |
404 elif self.__currentDataType == Connection.Ping: |
389 self.write(QByteArray("{0}{1}1{1}p".format( |
405 self.write( |
390 Connection.ProtocolPong, SeparatorToken).encode("utf-8"))) |
406 QByteArray( |
|
407 "{0}{1}1{1}p".format( |
|
408 Connection.ProtocolPong, SeparatorToken |
|
409 ).encode("utf-8") |
|
410 ) |
|
411 ) |
391 elif self.__currentDataType == Connection.Pong: |
412 elif self.__currentDataType == Connection.Pong: |
392 self.__pongTime = QTime.currentTime() |
413 self.__pongTime = QTime.currentTime() |
393 elif self.__currentDataType == Connection.GetParticipants: |
414 elif self.__currentDataType == Connection.GetParticipants: |
394 self.getParticipants.emit() |
415 self.getParticipants.emit() |
395 elif self.__currentDataType == Connection.Participants: |
416 elif self.__currentDataType == Connection.Participants: |
398 participantsList = [] |
419 participantsList = [] |
399 else: |
420 else: |
400 participantsList = msg.split(SeparatorToken) |
421 participantsList = msg.split(SeparatorToken) |
401 self.participants.emit(participantsList[:]) |
422 self.participants.emit(participantsList[:]) |
402 elif self.__currentDataType == Connection.Editor: |
423 elif self.__currentDataType == Connection.Editor: |
403 hashStr, fn, msg = ( |
424 hashStr, fn, msg = str(self.__buffer, encoding="utf-8").split( |
404 str(self.__buffer, encoding="utf-8").split(SeparatorToken)) |
425 SeparatorToken |
|
426 ) |
405 self.editorCommand.emit(hashStr, fn, msg) |
427 self.editorCommand.emit(hashStr, fn, msg) |
406 |
428 |
407 self.__currentDataType = Connection.Undefined |
429 self.__currentDataType = Connection.Undefined |
408 self.__numBytesForCurrentDataType = 0 |
430 self.__numBytesForCurrentDataType = 0 |
409 self.__buffer.clear() |
431 self.__buffer.clear() |
410 |
432 |
411 def sendGetParticipants(self): |
433 def sendGetParticipants(self): |
412 """ |
434 """ |
413 Public method to request a list of participants. |
435 Public method to request a list of participants. |
414 """ |
436 """ |
415 self.write(QByteArray( |
437 self.write( |
416 "{0}{1}1{1}l".format( |
438 QByteArray( |
417 Connection.ProtocolGetParticipants, SeparatorToken |
439 "{0}{1}1{1}l".format( |
418 ).encode("utf-8") |
440 Connection.ProtocolGetParticipants, SeparatorToken |
419 )) |
441 ).encode("utf-8") |
420 |
442 ) |
|
443 ) |
|
444 |
421 def sendParticipants(self, participants): |
445 def sendParticipants(self, participants): |
422 """ |
446 """ |
423 Public method to send the list of participants. |
447 Public method to send the list of participants. |
424 |
448 |
425 @param participants list of participants (list of strings of |
449 @param participants list of participants (list of strings of |
426 "host:port") |
450 "host:port") |
427 """ |
451 """ |
428 message = (SeparatorToken.join(participants) if participants |
452 message = SeparatorToken.join(participants) if participants else "<empty>" |
429 else "<empty>") |
|
430 msg = QByteArray(message.encode("utf-8")) |
453 msg = QByteArray(message.encode("utf-8")) |
431 data = QByteArray("{0}{1}{2}{1}".format( |
454 data = ( |
432 Connection.ProtocolParticipants, SeparatorToken, msg.size()) |
455 QByteArray( |
433 .encode("utf-8")) + msg |
456 "{0}{1}{2}{1}".format( |
|
457 Connection.ProtocolParticipants, SeparatorToken, msg.size() |
|
458 ).encode("utf-8") |
|
459 ) |
|
460 + msg |
|
461 ) |
434 self.write(data) |
462 self.write(data) |
435 |
463 |
436 def sendEditorCommand(self, projectHash, filename, message): |
464 def sendEditorCommand(self, projectHash, filename, message): |
437 """ |
465 """ |
438 Public method to send an editor command. |
466 Public method to send an editor command. |
439 |
467 |
440 @param projectHash hash of the project (string) |
468 @param projectHash hash of the project (string) |
441 @param filename project relative universal file name of |
469 @param filename project relative universal file name of |
442 the sending editor (string) |
470 the sending editor (string) |
443 @param message editor command to be sent (string) |
471 @param message editor command to be sent (string) |
444 """ |
472 """ |
445 msg = QByteArray("{0}{1}{2}{1}{3}".format( |
473 msg = QByteArray( |
446 projectHash, SeparatorToken, filename, message).encode("utf-8")) |
474 "{0}{1}{2}{1}{3}".format( |
447 data = QByteArray("{0}{1}{2}{1}".format( |
475 projectHash, SeparatorToken, filename, message |
448 Connection.ProtocolEditor, SeparatorToken, msg.size()) |
476 ).encode("utf-8") |
449 .encode("utf-8")) + msg |
477 ) |
|
478 data = ( |
|
479 QByteArray( |
|
480 "{0}{1}{2}{1}".format( |
|
481 Connection.ProtocolEditor, SeparatorToken, msg.size() |
|
482 ).encode("utf-8") |
|
483 ) |
|
484 + msg |
|
485 ) |
450 self.write(data) |
486 self.write(data) |
451 |
487 |
452 def __disconnected(self): |
488 def __disconnected(self): |
453 """ |
489 """ |
454 Private slot to handle the connection being dropped. |
490 Private slot to handle the connection being dropped. |
455 """ |
491 """ |
456 self.__pingTimer.stop() |
492 self.__pingTimer.stop() |
457 if self.__state == Connection.WaitingForGreeting: |
493 if self.__state == Connection.WaitingForGreeting: |
458 self.rejected.emit(self.tr( |
494 self.rejected.emit( |
459 "* Connection to {0}:{1} refused.").format( |
495 self.tr("* Connection to {0}:{1} refused.").format( |
460 self.peerName(), self.peerPort())) |
496 self.peerName(), self.peerPort() |
|
497 ) |
|
498 ) |