src/eric7/Cooperation/Connection.py

branch
eric7
changeset 9221
bf71ee032bb4
parent 9209
b99e7fd55fd3
child 9413
80c06d472826
equal deleted inserted replaced
9220:e9e7eca7efee 9221:bf71ee032bb4
17 17
18 MaxBufferSize = 1024 * 1024 18 MaxBufferSize = 1024 * 1024
19 TransferTimeout = 30 * 1000 19 TransferTimeout = 30 * 1000
20 PongTimeout = 60 * 1000 20 PongTimeout = 60 * 1000
21 PingInterval = 5 * 1000 21 PingInterval = 5 * 1000
22 SeparatorToken = '|||' 22 SeparatorToken = "|||"
23 SeparatorToken_b = b'|||' 23 SeparatorToken_b = b"|||"
24 24
25 25
26 class Connection(QTcpSocket): 26 class Connection(QTcpSocket):
27 """ 27 """
28 Class representing a peer connection. 28 Class representing a peer connection.
29 29
30 @signal readyForUse() emitted when the connection is ready for use 30 @signal readyForUse() emitted when the connection is ready for use
31 @signal newMessage(user, message) emitted after a new message has 31 @signal newMessage(user, message) emitted after a new message has
32 arrived (string, string) 32 arrived (string, string)
33 @signal getParticipants() emitted after a get participants message has 33 @signal getParticipants() emitted after a get participants message has
34 arrived 34 arrived
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 )

eric ide

mercurial