Network/IRC/IrcChannelWidget.py

changeset 2992
dbdf27746da5
parent 2960
9453efa25fd5
child 3020
542e97d4ecb3
child 3057
10516539f238
equal deleted inserted replaced
2991:226481ff40d1 2992:dbdf27746da5
7 Module implementing the IRC channel widget. 7 Module implementing the IRC channel widget.
8 """ 8 """
9 9
10 import re 10 import re
11 11
12 from PyQt4.QtCore import pyqtSlot, pyqtSignal, QDateTime, QPoint, QFileInfo, QTimer, QUrl 12 from PyQt4.QtCore import pyqtSlot, pyqtSignal, QDateTime, QPoint, QFileInfo, \
13 from PyQt4.QtGui import QWidget, QListWidgetItem, QIcon, QPainter, QMenu, QApplication, \ 13 QTimer, QUrl
14 QInputDialog, QLineEdit, QTextCursor, QDesktopServices 14 from PyQt4.QtGui import QWidget, QListWidgetItem, QIcon, QPainter, QMenu, \
15 QApplication, QInputDialog, QLineEdit, QTextCursor, QDesktopServices
15 16
16 from E5Gui import E5MessageBox, E5FileDialog 17 from E5Gui import E5MessageBox, E5FileDialog
17 from E5Gui.E5Application import e5App 18 from E5Gui.E5Application import e5App
18 19
19 from .Ui_IrcChannelWidget import Ui_IrcChannelWidget 20 from .Ui_IrcChannelWidget import Ui_IrcChannelWidget
50 def __init__(self, name, parent=None): 51 def __init__(self, name, parent=None):
51 """ 52 """
52 Constructor 53 Constructor
53 54
54 @param name string with user name and privilege prefix (string) 55 @param name string with user name and privilege prefix (string)
55 @param parent reference to the parent widget (QListWidget or QListWidgetItem) 56 @param parent reference to the parent widget (QListWidget or
57 QListWidgetItem)
56 """ 58 """
57 super().__init__(name, parent) 59 super().__init__(name, parent)
58 60
59 self.__privilege = IrcUserItem.Normal 61 self.__privilege = IrcUserItem.Normal
60 self.__name = name 62 self.__name = name
178 Class implementing the IRC channel widget. 180 Class implementing the IRC channel widget.
179 181
180 @signal sendData(str) emitted to send a message to the channel 182 @signal sendData(str) emitted to send a message to the channel
181 @signal sendCtcpReply(str, str) emitted to send a CTCP reply 183 @signal sendCtcpReply(str, str) emitted to send a CTCP reply
182 @signal channelClosed(str) emitted after the user has left the channel 184 @signal channelClosed(str) emitted after the user has left the channel
183 @signal openPrivateChat(str) emitted to open a "channel" for private messages 185 @signal openPrivateChat(str) emitted to open a "channel" for private
186 messages
184 """ 187 """
185 sendData = pyqtSignal(str) 188 sendData = pyqtSignal(str)
186 sendCtcpReply = pyqtSignal(str, str) 189 sendCtcpReply = pyqtSignal(str, str)
187 channelClosed = pyqtSignal(str) 190 channelClosed = pyqtSignal(str)
188 openPrivateChat = pyqtSignal(str) 191 openPrivateChat = pyqtSignal(str)
204 self.setupUi(self) 207 self.setupUi(self)
205 208
206 self.__ui = e5App().getObject("UserInterface") 209 self.__ui = e5App().getObject("UserInterface")
207 self.__ircWidget = parent 210 self.__ircWidget = parent
208 211
209 self.editTopicButton.setIcon(UI.PixmapCache.getIcon("ircEditTopic.png")) 212 self.editTopicButton.setIcon(
213 UI.PixmapCache.getIcon("ircEditTopic.png"))
210 self.editTopicButton.hide() 214 self.editTopicButton.hide()
211 215
212 height = self.usersList.height() + self.messages.height() 216 height = self.usersList.height() + self.messages.height()
213 self.splitter.setSizes([height * 0.3, height * 0.7]) 217 self.splitter.setSizes([height * 0.3, height * 0.7])
214 218
227 self.__hidden = True 231 self.__hidden = True
228 232
229 self.__patterns = [ 233 self.__patterns = [
230 # :foo_!n=foo@foohost.bar.net PRIVMSG #eric-ide :some long message 234 # :foo_!n=foo@foohost.bar.net PRIVMSG #eric-ide :some long message
231 # :foo_!n=foo@foohost.bar.net PRIVMSG bar_ :some long message 235 # :foo_!n=foo@foohost.bar.net PRIVMSG bar_ :some long message
232 (re.compile(r":([^!]+)!([^ ]+)\sPRIVMSG\s([^ ]+)\s:(.*)"), self.__message), 236 (re.compile(r":([^!]+)!([^ ]+)\sPRIVMSG\s([^ ]+)\s:(.*)"),
237 self.__message),
233 # :foo_!n=foo@foohost.bar.net JOIN :#eric-ide 238 # :foo_!n=foo@foohost.bar.net JOIN :#eric-ide
234 (re.compile(r":([^!]+)!([^ ]+)\sJOIN\s:?([^ ]+)"), self.__userJoin), 239 (re.compile(r":([^!]+)!([^ ]+)\sJOIN\s:?([^ ]+)"),
240 self.__userJoin),
235 # :foo_!n=foo@foohost.bar.net PART #eric-ide :part message 241 # :foo_!n=foo@foohost.bar.net PART #eric-ide :part message
236 (re.compile(r":([^!]+).*\sPART\s([^ ]+)\s:(.*)"), self.__userPart), 242 (re.compile(r":([^!]+).*\sPART\s([^ ]+)\s:(.*)"), self.__userPart),
237 # :foo_!n=foo@foohost.bar.net PART #eric-ide 243 # :foo_!n=foo@foohost.bar.net PART #eric-ide
238 (re.compile(r":([^!]+).*\sPART\s([^ ]+)\s*"), self.__userPart), 244 (re.compile(r":([^!]+).*\sPART\s([^ ]+)\s*"), self.__userPart),
239 # :foo_!n=foo@foohost.bar.net QUIT :quit message 245 # :foo_!n=foo@foohost.bar.net QUIT :quit message
244 (re.compile(r":([^!]+).*\sNICK\s:(.*)"), self.__userNickChange), 250 (re.compile(r":([^!]+).*\sNICK\s:(.*)"), self.__userNickChange),
245 # :foo_!n=foo@foohost.bar.net MODE #eric-ide +o foo_ 251 # :foo_!n=foo@foohost.bar.net MODE #eric-ide +o foo_
246 (re.compile(r":([^!]+).*\sMODE\s([^ ]+)\s([+-][ovO]+)\s([^ ]+).*"), 252 (re.compile(r":([^!]+).*\sMODE\s([^ ]+)\s([+-][ovO]+)\s([^ ]+).*"),
247 self.__setUserPrivilege), 253 self.__setUserPrivilege),
248 # :cameron.freenode.net MODE #eric-ide +ns 254 # :cameron.freenode.net MODE #eric-ide +ns
249 (re.compile(r":([^ ]+)\sMODE\s([^ ]+)\s(.+)"), self.__updateChannelModes), 255 (re.compile(r":([^ ]+)\sMODE\s([^ ]+)\s(.+)"),
250 # :foo_!n=foo@foohost.bar.net TOPIC #eric-ide :eric - The Python IDE 256 self.__updateChannelModes),
257 # :foo_!n=foo@foohost.bar.net TOPIC #eric-ide :eric - Python IDE
251 (re.compile(r":.*\sTOPIC\s([^ ]+)\s:(.*)"), self.__setTopic), 258 (re.compile(r":.*\sTOPIC\s([^ ]+)\s:(.*)"), self.__setTopic),
252 # :sturgeon.freenode.net 301 foo_ bar :Gone away for now 259 # :sturgeon.freenode.net 301 foo_ bar :Gone away for now
253 (re.compile(r":.*\s301\s([^ ]+)\s([^ ]+)\s:(.+)"), self.__userAway), 260 (re.compile(r":.*\s301\s([^ ]+)\s([^ ]+)\s:(.+)"),
261 self.__userAway),
254 # :sturgeon.freenode.net 315 foo_ #eric-ide :End of /WHO list. 262 # :sturgeon.freenode.net 315 foo_ #eric-ide :End of /WHO list.
255 (re.compile(r":.*\s315\s[^ ]+\s([^ ]+)\s:(.*)"), self.__whoEnd), 263 (re.compile(r":.*\s315\s[^ ]+\s([^ ]+)\s:(.*)"), self.__whoEnd),
256 # :zelazny.freenode.net 324 foo_ #eric-ide +cnt 264 # :zelazny.freenode.net 324 foo_ #eric-ide +cnt
257 (re.compile(r":.*\s324\s.*\s([^ ]+)\s(.+)"), self.__channelModes), 265 (re.compile(r":.*\s324\s.*\s([^ ]+)\s(.+)"), self.__channelModes),
258 # :zelazny.freenode.net 328 foo_ #eric-ide :http://www.buggeroff.com/ 266 # :zelazny.freenode.net 328 foo_ #eric-ide :http://www.bugger.com/
259 (re.compile(r":.*\s328\s.*\s([^ ]+)\s:(.+)"), self.__channelUrl), 267 (re.compile(r":.*\s328\s.*\s([^ ]+)\s:(.+)"), self.__channelUrl),
260 # :zelazny.freenode.net 329 foo_ #eric-ide 1353001005 268 # :zelazny.freenode.net 329 foo_ #eric-ide 1353001005
261 (re.compile(r":.*\s329\s.*\s([^ ]+)\s(.+)"), self.__channelCreated), 269 (re.compile(r":.*\s329\s.*\s([^ ]+)\s(.+)"),
270 self.__channelCreated),
262 # :zelazny.freenode.net 332 foo_ #eric-ide :eric support channel 271 # :zelazny.freenode.net 332 foo_ #eric-ide :eric support channel
263 (re.compile(r":.*\s332\s.*\s([^ ]+)\s:(.*)"), self.__setTopic), 272 (re.compile(r":.*\s332\s.*\s([^ ]+)\s:(.*)"), self.__setTopic),
264 # :zelazny.freenode.net foo_ 333 #eric-ide foo 1353089020 273 # :zelazny.freenode.net foo_ 333 #eric-ide foo 1353089020
265 (re.compile(r":.*\s333\s.*\s([^ ]+)\s([^ ]+)\s(\d+)"), self.__topicCreated), 274 (re.compile(r":.*\s333\s.*\s([^ ]+)\s([^ ]+)\s(\d+)"),
266 # :cameron.freenode.net 352 detlev_ #eric-ide ~foo foohost.bar.net cameron.freenode.net foo_ H :0 Foo Bar 275 self.__topicCreated),
267 (re.compile(r":.*\s352\s[^ ]+\s([^ ]+)\s([^ ]+)\s([^ ]+)\s[^ ]+\s([^ ]+)" 276 # :cameron.freenode.net 352 detlev_ #eric-ide ~foo foohost.bar.net
268 r"\s([^ ]+)\s:\d+\s(.*)"), self.__whoEntry), 277 # cameron.freenode.net foo_ H :0 Foo Bar
278 (re.compile(
279 r":.*\s352\s[^ ]+\s([^ ]+)\s([^ ]+)\s([^ ]+)\s[^ ]+\s([^ ]+)"
280 r"\s([^ ]+)\s:\d+\s(.*)"), self.__whoEntry),
269 # :zelazny.freenode.net 353 foo_ @ #eric-ide :@user1 +user2 user3 281 # :zelazny.freenode.net 353 foo_ @ #eric-ide :@user1 +user2 user3
270 (re.compile(r":.*\s353\s.*\s.\s([^ ]+)\s:(.*)"), self.__userList), 282 (re.compile(r":.*\s353\s.*\s.\s([^ ]+)\s:(.*)"), self.__userList),
271 # :sturgeon.freenode.net 354 foo_ 42 ChanServ H@ 283 # :sturgeon.freenode.net 354 foo_ 42 ChanServ H@
272 (re.compile(r":.*\s354\s[^ ]+\s42\s([^ ]+)\s(.*)"), self.__autoWhoEntry), 284 (re.compile(r":.*\s354\s[^ ]+\s42\s([^ ]+)\s(.*)"),
285 self.__autoWhoEntry),
273 # :zelazny.freenode.net 366 foo_ #eric-ide :End of /NAMES list. 286 # :zelazny.freenode.net 366 foo_ #eric-ide :End of /NAMES list.
274 (re.compile(r":.*\s366\s.*\s([^ ]+)\s:(.*)"), self.__ignore), 287 (re.compile(r":.*\s366\s.*\s([^ ]+)\s:(.*)"), self.__ignore),
275 # :sturgeon.freenode.net 704 foo_ index :Help topics available to users: 288 # :sturgeon.freenode.net 704 foo_ index :Help topics available:
276 (re.compile(r":.*\s70[456]\s[^ ]+\s([^ ]+)\s:(.*)"), self.__help), 289 (re.compile(r":.*\s70[456]\s[^ ]+\s([^ ]+)\s:(.*)"), self.__help),
277 290
278 # WHOIS replies 291 # WHOIS replies
279 # :sturgeon.freenode.net 311 foo_ bar ~bar barhost.foo.net * :Bar User 292 # :sturgeon.freenode.net 311 foo_ bar ~bar barhost.foo.net * :Bar
280 (re.compile(r":.*\s311\s[^ ]+\s([^ ]+)\s([^ ]+)\s([^ ]+)\s\*\s:(.*)"), 293 (re.compile(
281 self.__whoIsUser), 294 r":.*\s311\s[^ ]+\s([^ ]+)\s([^ ]+)\s([^ ]+)\s\*\s:(.*)"),
295 self.__whoIsUser),
282 # :sturgeon.freenode.net 319 foo_ bar :@#eric-ide 296 # :sturgeon.freenode.net 319 foo_ bar :@#eric-ide
283 (re.compile(r":.*\s319\s[^ ]+\s([^ ]+)\s:(.*)"), self.__whoIsChannels), 297 (re.compile(r":.*\s319\s[^ ]+\s([^ ]+)\s:(.*)"),
284 # :sturgeon.freenode.net 312 foo_ bar sturgeon.freenode.net :London, UK 298 self.__whoIsChannels),
285 (re.compile(r":.*\s312\s[^ ]+\s([^ ]+)\s([^ ]+)\s:(.*)"), self.__whoIsServer), 299 # :sturgeon.freenode.net 312 foo_ bar sturgeon.freenode.net :London
300 (re.compile(r":.*\s312\s[^ ]+\s([^ ]+)\s([^ ]+)\s:(.*)"),
301 self.__whoIsServer),
286 # :sturgeon.freenode.net 671 foo_ bar :is using a secure connection 302 # :sturgeon.freenode.net 671 foo_ bar :is using a secure connection
287 (re.compile(r":.*\s671\s[^ ]+\s([^ ]+)\s:.*"), self.__whoIsSecure), 303 (re.compile(r":.*\s671\s[^ ]+\s([^ ]+)\s:.*"), self.__whoIsSecure),
288 # :sturgeon.freenode.net 317 foo_ bar 3758 1355046912 :seconds idle, signon time 304 # :sturgeon.freenode.net 317 foo_ bar 3758 1355046912 :seconds
305 # idle, signon time
289 (re.compile(r":.*\s317\s[^ ]+\s([^ ]+)\s(\d+)\s(\d+)\s:.*"), 306 (re.compile(r":.*\s317\s[^ ]+\s([^ ]+)\s(\d+)\s(\d+)\s:.*"),
290 self.__whoIsIdle), 307 self.__whoIsIdle),
291 # :sturgeon.freenode.net 330 foo_ bar bar :is logged in as 308 # :sturgeon.freenode.net 330 foo_ bar bar :is logged in as
292 (re.compile(r":.*\s330\s[^ ]+\s([^ ]+)\s([^ ]+)\s:.*"), self.__whoIsAccount), 309 (re.compile(r":.*\s330\s[^ ]+\s([^ ]+)\s([^ ]+)\s:.*"),
310 self.__whoIsAccount),
293 # :sturgeon.freenode.net 318 foo_ bar :End of /WHOIS list. 311 # :sturgeon.freenode.net 318 foo_ bar :End of /WHOIS list.
294 (re.compile(r":.*\s318\s[^ ]+\s([^ ]+)\s:(.*)"), self.__whoIsEnd), 312 (re.compile(r":.*\s318\s[^ ]+\s([^ ]+)\s:(.*)"), self.__whoIsEnd),
295 # :sturgeon.freenode.net 307 foo_ bar :is an identified user 313 # :sturgeon.freenode.net 307 foo_ bar :is an identified user
296 (re.compile(r":.*\s307\s[^ ]+\s([^ ]+)\s:(.*)"), self.__whoIsIdentify), 314 (re.compile(r":.*\s307\s[^ ]+\s([^ ]+)\s:(.*)"),
315 self.__whoIsIdentify),
297 # :sturgeon.freenode.net 320 foo_ bar :is an identified user 316 # :sturgeon.freenode.net 320 foo_ bar :is an identified user
298 (re.compile(r":.*\s320\s[^ ]+\s([^ ]+)\s:(.*)"), self.__whoIsIdentify), 317 (re.compile(r":.*\s320\s[^ ]+\s([^ ]+)\s:(.*)"),
318 self.__whoIsIdentify),
299 # :sturgeon.freenode.net 310 foo_ bar :is available for help 319 # :sturgeon.freenode.net 310 foo_ bar :is available for help
300 (re.compile(r":.*\s310\s[^ ]+\s([^ ]+)\s:(.*)"), self.__whoIsHelper), 320 (re.compile(r":.*\s310\s[^ ]+\s([^ ]+)\s:(.*)"),
301 # :sturgeon.freenode.net 338 foo_ bar real.ident@real.host 12.34.56.78 :Actual user@host, Actual IP 321 self.__whoIsHelper),
322 # :sturgeon.freenode.net 338 foo_ bar real.ident@real.host
323 # 12.34.56.78 :Actual user@host, Actual IP
302 (re.compile(r":.*\s338\s[^ ]+\s([^ ]+)\s([^ ]+)\s([^ ]+)\s:.*"), 324 (re.compile(r":.*\s338\s[^ ]+\s([^ ]+)\s([^ ]+)\s([^ ]+)\s:.*"),
303 self.__whoIsActually), 325 self.__whoIsActually),
304 # :sturgeon.freenode.net 313 foo_ bar :is an IRC Operator 326 # :sturgeon.freenode.net 313 foo_ bar :is an IRC Operator
305 (re.compile(r":.*\s313\s[^ ]+\s([^ ]+)\s:(.*)"), self.__whoIsOperator), 327 (re.compile(r":.*\s313\s[^ ]+\s([^ ]+)\s:(.*)"),
306 # :sturgeon.freenode.net 378 foo_ bar :is connecting from *@mnch-4d044d5a.pool.mediaWays.net 77.4.77.90 328 self.__whoIsOperator),
329 # :sturgeon.freenode.net 378 foo_ bar :is connecting from
330 # *@mnch-4d044d5a.pool.mediaWays.net 77.4.77.90
307 (re.compile(r":.*\s378\s[^ ]+\s([^ ]+)\s:.*\s([^ ]+)\s([^ ]+)"), 331 (re.compile(r":.*\s378\s[^ ]+\s([^ ]+)\s:.*\s([^ ]+)\s([^ ]+)"),
308 self.__whoIsConnection), 332 self.__whoIsConnection),
309 ] 333 ]
310 334
311 self.__autoWhoTemplate = "WHO {0} %tnf,42" 335 self.__autoWhoTemplate = "WHO {0} %tnf,42"
312 self.__autoWhoTimer = QTimer() 336 self.__autoWhoTimer = QTimer()
313 self.__autoWhoTimer.setSingleShot(True) 337 self.__autoWhoTimer.setSingleShot(True)
329 ircTimestamp(), self.__userName, Utilities.html_encode(msg))) 353 ircTimestamp(), self.__userName, Utilities.html_encode(msg)))
330 if msg.startswith("/"): 354 if msg.startswith("/"):
331 if self.__private: 355 if self.__private:
332 E5MessageBox.information(self, 356 E5MessageBox.information(self,
333 self.trUtf8("Send Message"), 357 self.trUtf8("Send Message"),
334 self.trUtf8("""Messages starting with a '/' are not allowed""" 358 self.trUtf8(
335 """ in private chats.""")) 359 """Messages starting with a '/' are not allowed"""
360 """ in private chats."""))
336 else: 361 else:
337 msgList = msg.split(None, 1) 362 msgList = msg.split(None, 1)
338 cmd = msgList[0][1:].upper() 363 cmd = msgList[0][1:].upper()
339 if cmd == "MSG": 364 if cmd == "MSG":
340 cmd = "PRIVMSG" 365 cmd = "PRIVMSG"
341 msgList[0] = cmd 366 msgList[0] = cmd
342 self.sendData.emit(" ".join(msgList)) 367 self.sendData.emit(" ".join(msgList))
343 else: 368 else:
344 if self.__private: 369 if self.__private:
345 self.sendData.emit("PRIVMSG " + self.__privatePartner + " :" + msg) 370 self.sendData.emit(
371 "PRIVMSG " + self.__privatePartner + " :" + msg)
346 else: 372 else:
347 self.sendData.emit("PRIVMSG " + self.__name + " :" + msg) 373 self.sendData.emit(
374 "PRIVMSG " + self.__name + " :" + msg)
348 self.messageEdit.clear() 375 self.messageEdit.clear()
349 self.unsetMarkerLine() 376 self.unsetMarkerLine()
350 377
351 def requestLeave(self): 378 def requestLeave(self):
352 """ 379 """
353 Public method to leave the channel. 380 Public method to leave the channel.
354 """ 381 """
355 ok = E5MessageBox.yesNo(self, 382 ok = E5MessageBox.yesNo(self,
356 self.trUtf8("Leave IRC channel"), 383 self.trUtf8("Leave IRC channel"),
357 self.trUtf8("""Do you really want to leave the IRC channel <b>{0}</b>?""")\ 384 self.trUtf8(
385 """Do you really want to leave the IRC channel <b>{0}</b>?""")
358 .format(self.__name)) 386 .format(self.__name))
359 if ok: 387 if ok:
360 if not self.__private: 388 if not self.__private:
361 self.sendData.emit("PART " + self.__name + " :" + self.__partMessage) 389 self.sendData.emit(
390 "PART " + self.__name + " :" + self.__partMessage)
362 self.channelClosed.emit(self.__name) 391 self.channelClosed.emit(self.__name)
363 392
364 def name(self): 393 def name(self):
365 """ 394 """
366 Public method to get the name of the channel. 395 Public method to get the name of the channel.
467 if match.group(4).startswith("\x01"): 496 if match.group(4).startswith("\x01"):
468 return self.__handleCtcp(match) 497 return self.__handleCtcp(match)
469 498
470 self.addMessage(match.group(1), match.group(4)) 499 self.addMessage(match.group(1), match.group(4))
471 if self.__private and not self.topicLabel.text(): 500 if self.__private and not self.topicLabel.text():
472 self.setPrivateInfo("{0} - {1}".format(match.group(1), match.group(2))) 501 self.setPrivateInfo(
502 "{0} - {1}".format(match.group(1), match.group(2)))
473 return True 503 return True
474 504
475 return False 505 return False
476 506
477 def addMessage(self, sender, msg): 507 def addMessage(self, sender, msg):
487 Preferences.getIrc("ChannelMessageColour"), 517 Preferences.getIrc("ChannelMessageColour"),
488 Preferences.getIrc("NickColour"), 518 Preferences.getIrc("NickColour"),
489 ircTimestamp(), sender, ircFilter(msg))) 519 ircTimestamp(), sender, ircFilter(msg)))
490 if Preferences.getIrc("ShowNotifications"): 520 if Preferences.getIrc("ShowNotifications"):
491 if Preferences.getIrc("NotifyMessage"): 521 if Preferences.getIrc("NotifyMessage"):
492 self.__ui.showNotification(UI.PixmapCache.getPixmap("irc48.png"), 522 self.__ui.showNotification(
523 UI.PixmapCache.getPixmap("irc48.png"),
493 self.trUtf8("Channel Message"), msg) 524 self.trUtf8("Channel Message"), msg)
494 elif Preferences.getIrc("NotifyNick") and \ 525 elif Preferences.getIrc("NotifyNick") and \
495 self.__userName.lower() in msg.lower(): 526 self.__userName.lower() in msg.lower():
496 self.__ui.showNotification(UI.PixmapCache.getPixmap("irc48.png"), 527 self.__ui.showNotification(
528 UI.PixmapCache.getPixmap("irc48.png"),
497 self.trUtf8("Nick mentioned"), msg) 529 self.trUtf8("Nick mentioned"), msg)
498 530
499 def addUsers(self, users): 531 def addUsers(self, users):
500 """ 532 """
501 Public method to add users to the channel. 533 Public method to add users to the channel.
515 @return flag indicating whether the message was handled (boolean) 547 @return flag indicating whether the message was handled (boolean)
516 """ 548 """
517 if match.group(3).lower() == self.__name.lower(): 549 if match.group(3).lower() == self.__name.lower():
518 if self.__userName != match.group(1): 550 if self.__userName != match.group(1):
519 IrcUserItem(match.group(1), self.usersList) 551 IrcUserItem(match.group(1), self.usersList)
520 msg = self.trUtf8("{0} has joined the channel {1} ({2}).").format( 552 msg = self.trUtf8(
521 match.group(1), self.__name, match.group(2)) 553 "{0} has joined the channel {1} ({2}).").format(
522 self.__addManagementMessage(IrcChannelWidget.JoinIndicator, msg) 554 match.group(1), self.__name, match.group(2))
555 self.__addManagementMessage(
556 IrcChannelWidget.JoinIndicator, msg)
523 else: 557 else:
524 msg = self.trUtf8("You have joined the channel {0} ({1}).").format( 558 msg = self.trUtf8(
525 self.__name, match.group(2)) 559 "You have joined the channel {0} ({1}).").format(
526 self.__addManagementMessage(IrcChannelWidget.JoinIndicator, msg) 560 self.__name, match.group(2))
561 self.__addManagementMessage(
562 IrcChannelWidget.JoinIndicator, msg)
527 if Preferences.getIrc("ShowNotifications") and \ 563 if Preferences.getIrc("ShowNotifications") and \
528 Preferences.getIrc("NotifyJoinPart"): 564 Preferences.getIrc("NotifyJoinPart"):
529 self.__ui.showNotification(UI.PixmapCache.getPixmap("irc48.png"), 565 self.__ui.showNotification(
566 UI.PixmapCache.getPixmap("irc48.png"),
530 self.trUtf8("Join Channel"), msg) 567 self.trUtf8("Join Channel"), msg)
531 return True 568 return True
532 569
533 return False 570 return False
534 571
545 del itm 582 del itm
546 if match.lastindex == 2: 583 if match.lastindex == 2:
547 msg = self.trUtf8("{0} has left {1}.").format( 584 msg = self.trUtf8("{0} has left {1}.").format(
548 match.group(1), self.__name) 585 match.group(1), self.__name)
549 nmsg = msg 586 nmsg = msg
550 self.__addManagementMessage(IrcChannelWidget.LeaveIndicator, msg) 587 self.__addManagementMessage(
588 IrcChannelWidget.LeaveIndicator, msg)
551 else: 589 else:
552 msg = self.trUtf8("{0} has left {1}: {2}.").format( 590 msg = self.trUtf8("{0} has left {1}: {2}.").format(
553 match.group(1), self.__name, ircFilter(match.group(3))) 591 match.group(1), self.__name, ircFilter(match.group(3)))
554 nmsg = self.trUtf8("{0} has left {1}: {2}.").format( 592 nmsg = self.trUtf8("{0} has left {1}: {2}.").format(
555 match.group(1), self.__name, match.group(3)) 593 match.group(1), self.__name, match.group(3))
556 self.__addManagementMessage(IrcChannelWidget.LeaveIndicator, msg) 594 self.__addManagementMessage(
595 IrcChannelWidget.LeaveIndicator, msg)
557 if Preferences.getIrc("ShowNotifications") and \ 596 if Preferences.getIrc("ShowNotifications") and \
558 Preferences.getIrc("NotifyJoinPart"): 597 Preferences.getIrc("NotifyJoinPart"):
559 self.__ui.showNotification(UI.PixmapCache.getPixmap("irc48.png"), 598 self.__ui.showNotification(
599 UI.PixmapCache.getPixmap("irc48.png"),
560 self.trUtf8("Leave Channel"), nmsg) 600 self.trUtf8("Leave Channel"), nmsg)
561 return True 601 return True
562 602
563 return False 603 return False
564 604
574 self.usersList.takeItem(self.usersList.row(itm)) 614 self.usersList.takeItem(self.usersList.row(itm))
575 del itm 615 del itm
576 if match.lastindex == 1: 616 if match.lastindex == 1:
577 msg = self.trUtf8("{0} has quit {1}.").format( 617 msg = self.trUtf8("{0} has quit {1}.").format(
578 match.group(1), self.__name) 618 match.group(1), self.__name)
579 self.__addManagementMessage(IrcChannelWidget.MessageIndicator, msg) 619 self.__addManagementMessage(
620 IrcChannelWidget.MessageIndicator, msg)
580 else: 621 else:
581 msg = self.trUtf8("{0} has quit {1}: {2}.").format( 622 msg = self.trUtf8("{0} has quit {1}: {2}.").format(
582 match.group(1), self.__name, ircFilter(match.group(2))) 623 match.group(1), self.__name, ircFilter(match.group(2)))
583 self.__addManagementMessage(IrcChannelWidget.MessageIndicator, msg) 624 self.__addManagementMessage(
625 IrcChannelWidget.MessageIndicator, msg)
584 if Preferences.getIrc("ShowNotifications") and \ 626 if Preferences.getIrc("ShowNotifications") and \
585 Preferences.getIrc("NotifyJoinPart"): 627 Preferences.getIrc("NotifyJoinPart"):
586 self.__ui.showNotification(UI.PixmapCache.getPixmap("irc48.png"), 628 self.__ui.showNotification(
629 UI.PixmapCache.getPixmap("irc48.png"),
587 self.trUtf8("Quit"), msg) 630 self.trUtf8("Quit"), msg)
588 631
589 # always return False for other channels and server to process 632 # always return False for other channels and server to process
590 return False 633 return False
591 634
641 @param match match object that matched the pattern 684 @param match match object that matched the pattern
642 @return flag indicating whether the message was handled (boolean) 685 @return flag indicating whether the message was handled (boolean)
643 """ 686 """
644 if match.group(1).lower() == self.__name.lower(): 687 if match.group(1).lower() == self.__name.lower():
645 self.__addManagementMessage(self.trUtf8("Away"), 688 self.__addManagementMessage(self.trUtf8("Away"),
646 self.trUtf8("{0} is away: {1}").format(match.group(2), match.group(3))) 689 self.trUtf8("{0} is away: {1}").format(
690 match.group(2), match.group(3)))
647 return True 691 return True
648 692
649 return False 693 return False
650 694
651 def __setTopic(self, match): 695 def __setTopic(self, match):
687 @param match match object that matched the pattern 731 @param match match object that matched the pattern
688 @return flag indicating whether the message was handled (boolean) 732 @return flag indicating whether the message was handled (boolean)
689 """ 733 """
690 if match.group(1).lower() == self.__name.lower(): 734 if match.group(1).lower() == self.__name.lower():
691 self.__addManagementMessage(IrcChannelWidget.MessageIndicator, 735 self.__addManagementMessage(IrcChannelWidget.MessageIndicator,
692 ircFilter(self.trUtf8("Channel URL: {0}").format(match.group(2)))) 736 ircFilter(self.trUtf8("Channel URL: {0}").format(
737 match.group(2))))
693 return True 738 return True
694 739
695 return False 740 return False
696 741
697 def __channelModes(self, match): 742 def __channelModes(self, match):
709 for modeChar in modeString: 754 for modeChar in modeString:
710 if modeChar == "+": 755 if modeChar == "+":
711 continue 756 continue
712 elif modeChar == "k": 757 elif modeChar == "k":
713 parameter = modesParameters.pop(0) 758 parameter = modesParameters.pop(0)
714 modes.append( 759 modes.append(self.trUtf8(
715 self.trUtf8("password protected ({0})").format(parameter)) 760 "password protected ({0})").format(parameter))
716 elif modeChar == "l": 761 elif modeChar == "l":
717 parameter = modesParameters.pop(0) 762 parameter = modesParameters.pop(0)
718 modes.append( 763 modes.append(self.trUtf8(
719 self.trUtf8("limited to %n user(s)", "", int(parameter))) 764 "limited to %n user(s)", "", int(parameter)))
720 elif modeChar in modesDict: 765 elif modeChar in modesDict:
721 modes.append(modesDict[modeChar]) 766 modes.append(modesDict[modeChar])
722 else: 767 else:
723 modes.append(modeChar) 768 modes.append(modeChar)
724 769
769 isPlus = False 814 isPlus = False
770 continue 815 continue
771 elif mode == "a": 816 elif mode == "a":
772 if isPlus: 817 if isPlus:
773 message = self.trUtf8( 818 message = self.trUtf8(
774 "{0} sets the channel mode to 'anonymous'.").format(nick) 819 "{0} sets the channel mode to 'anonymous'.")\
820 .format(nick)
775 else: 821 else:
776 message = self.trUtf8( 822 message = self.trUtf8(
777 "{0} removes the 'anonymous' mode from the channel.").format( 823 "{0} removes the 'anonymous' mode from the"
778 nick) 824 " channel.").format(nick)
779 elif mode == "b": 825 elif mode == "b":
780 if isPlus: 826 if isPlus:
781 message = self.trUtf8( 827 message = self.trUtf8(
782 "{0} sets a ban on {1}.").format( 828 "{0} sets a ban on {1}.").format(
783 nick, modesParameters.pop(0)) 829 nick, modesParameters.pop(0))
786 "{0} removes the ban on {1}.").format( 832 "{0} removes the ban on {1}.").format(
787 nick, modesParameters.pop(0)) 833 nick, modesParameters.pop(0))
788 elif mode == "c": 834 elif mode == "c":
789 if isPlus: 835 if isPlus:
790 message = self.trUtf8( 836 message = self.trUtf8(
791 "{0} sets the channel mode to 'no colors allowed'.").format( 837 "{0} sets the channel mode to 'no colors"
792 nick) 838 " allowed'.").format(nick)
793 else: 839 else:
794 message = self.trUtf8( 840 message = self.trUtf8(
795 "{0} sets the channel mode to 'allow color codes'.").format( 841 "{0} sets the channel mode to 'allow color"
796 nick) 842 " codes'.").format(nick)
797 elif mode == "e": 843 elif mode == "e":
798 if isPlus: 844 if isPlus:
799 message = self.trUtf8( 845 message = self.trUtf8(
800 "{0} sets a ban exception on {1}.").format( 846 "{0} sets a ban exception on {1}.").format(
801 nick, modesParameters.pop(0)) 847 nick, modesParameters.pop(0))
804 "{0} removes the ban exception on {1}.").format( 850 "{0} removes the ban exception on {1}.").format(
805 nick, modesParameters.pop(0)) 851 nick, modesParameters.pop(0))
806 elif mode == "i": 852 elif mode == "i":
807 if isPlus: 853 if isPlus:
808 message = self.trUtf8( 854 message = self.trUtf8(
809 "{0} sets the channel mode to 'invite only'.").format(nick) 855 "{0} sets the channel mode to 'invite only'.")\
856 .format(nick)
810 else: 857 else:
811 message = self.trUtf8( 858 message = self.trUtf8(
812 "{0} removes the 'invite only' mode from the channel." 859 "{0} removes the 'invite only' mode from the"
813 ).format(nick) 860 " channel.").format(nick)
814 elif mode == "k": 861 elif mode == "k":
815 if isPlus: 862 if isPlus:
816 message = self.trUtf8( 863 message = self.trUtf8(
817 "{0} sets the channel key to '{1}'.").format( 864 "{0} sets the channel key to '{1}'.").format(
818 nick, modesParameters.pop(0)) 865 nick, modesParameters.pop(0))
828 message = self.trUtf8( 875 message = self.trUtf8(
829 "{0} removes the channel limit.").format(nick) 876 "{0} removes the channel limit.").format(nick)
830 elif mode == "m": 877 elif mode == "m":
831 if isPlus: 878 if isPlus:
832 message = self.trUtf8( 879 message = self.trUtf8(
833 "{0} sets the channel mode to 'moderated'.").format(nick) 880 "{0} sets the channel mode to 'moderated'.")\
881 .format(nick)
834 else: 882 else:
835 message = self.trUtf8( 883 message = self.trUtf8(
836 "{0} sets the channel mode to 'unmoderated'.").format(nick) 884 "{0} sets the channel mode to 'unmoderated'.")\
885 .format(nick)
837 elif mode == "n": 886 elif mode == "n":
838 if isPlus: 887 if isPlus:
839 message = self.trUtf8( 888 message = self.trUtf8(
840 "{0} sets the channel mode to 'no messages from outside'." 889 "{0} sets the channel mode to 'no messages from"
841 ).format(nick) 890 " outside'.").format(nick)
842 else: 891 else:
843 message = self.trUtf8( 892 message = self.trUtf8(
844 "{0} sets the channel mode to 'allow messages from outside'." 893 "{0} sets the channel mode to 'allow messages"
845 ).format(nick) 894 " from outside'.").format(nick)
846 elif mode == "p": 895 elif mode == "p":
847 if isPlus: 896 if isPlus:
848 message = self.trUtf8( 897 message = self.trUtf8(
849 "{0} sets the channel mode to 'private'.").format(nick) 898 "{0} sets the channel mode to 'private'.")\
899 .format(nick)
850 else: 900 else:
851 message = self.trUtf8( 901 message = self.trUtf8(
852 "{0} sets the channel mode to 'public'.").format(nick) 902 "{0} sets the channel mode to 'public'.")\
903 .format(nick)
853 elif mode == "q": 904 elif mode == "q":
854 if isPlus: 905 if isPlus:
855 message = self.trUtf8( 906 message = self.trUtf8(
856 "{0} sets the channel mode to 'quiet'.").format(nick) 907 "{0} sets the channel mode to 'quiet'.")\
908 .format(nick)
857 else: 909 else:
858 message = self.trUtf8( 910 message = self.trUtf8(
859 "{0} removes the 'quiet' mode from the channel.").format( 911 "{0} removes the 'quiet' mode from the channel.")\
860 nick) 912 .format(nick)
861 elif mode == "r": 913 elif mode == "r":
862 continue 914 continue
863 elif mode == "s": 915 elif mode == "s":
864 if isPlus: 916 if isPlus:
865 message = self.trUtf8( 917 message = self.trUtf8(
866 "{0} sets the channel mode to 'secret'.").format(nick) 918 "{0} sets the channel mode to 'secret'.")\
919 .format(nick)
867 else: 920 else:
868 message = self.trUtf8( 921 message = self.trUtf8(
869 "{0} sets the channel mode to 'visible'.").format(nick) 922 "{0} sets the channel mode to 'visible'.")\
923 .format(nick)
870 elif mode == "t": 924 elif mode == "t":
871 if isPlus: 925 if isPlus:
872 message = self.trUtf8( 926 message = self.trUtf8(
873 "{0} switches on 'topic protection'.").format(nick) 927 "{0} switches on 'topic protection'.").format(nick)
874 else: 928 else:
875 message = self.trUtf8( 929 message = self.trUtf8(
876 "{0} switches off 'topic protection'.").format(nick) 930 "{0} switches off 'topic protection'.")\
931 .format(nick)
877 elif mode == "I": 932 elif mode == "I":
878 if isPlus: 933 if isPlus:
879 message = self.trUtf8( 934 message = self.trUtf8(
880 "{0} sets invitation mask {1}.").format( 935 "{0} sets invitation mask {1}.").format(
881 nick, modesParameters.pop(0)) 936 nick, modesParameters.pop(0))
958 self.sendCtcpReply.emit(match.group(1), "VERSION " + msg) 1013 self.sendCtcpReply.emit(match.group(1), "VERSION " + msg)
959 elif ctcpRequest == "ping": 1014 elif ctcpRequest == "ping":
960 self.__addManagementMessage(self.trUtf8("CTCP"), 1015 self.__addManagementMessage(self.trUtf8("CTCP"),
961 self.trUtf8("Received CTCP-PING request from {0}," 1016 self.trUtf8("Received CTCP-PING request from {0},"
962 " sending answer.").format(match.group(1))) 1017 " sending answer.").format(match.group(1)))
963 self.sendCtcpReply.emit(match.group(1), "PING {0}".format(ctcpArg)) 1018 self.sendCtcpReply.emit(
1019 match.group(1), "PING {0}".format(ctcpArg))
964 elif ctcpRequest == "clientinfo": 1020 elif ctcpRequest == "clientinfo":
965 self.__addManagementMessage(self.trUtf8("CTCP"), 1021 self.__addManagementMessage(self.trUtf8("CTCP"),
966 self.trUtf8("Received CTCP-CLIENTINFO request from {0}," 1022 self.trUtf8("Received CTCP-CLIENTINFO request from {0},"
967 " sending answer.").format(match.group(1))) 1023 " sending answer.").format(match.group(1)))
968 self.sendCtcpReply.emit(match.group(1), 1024 self.sendCtcpReply.emit(match.group(1),
969 "CLIENTINFO CLIENTINFO PING VERSION") 1025 "CLIENTINFO CLIENTINFO PING VERSION")
970 else: 1026 else:
971 self.__addManagementMessage(self.trUtf8("CTCP"), 1027 self.__addManagementMessage(self.trUtf8("CTCP"),
972 self.trUtf8("Received unknown CTCP-{0} request from {1}.").format( 1028 self.trUtf8("Received unknown CTCP-{0} request from {1}.")
973 ctcpRequest, match.group(1))) 1029 .format(ctcpRequest, match.group(1)))
974 return True 1030 return True
975 1031
976 return False 1032 return False
977 1033
978 def setUserPrivilegePrefix(self, prefixes): 1034 def setUserPrivilegePrefix(self, prefixes):
1050 """ 1106 """
1051 Public method to draw a line to mark the current position. 1107 Public method to draw a line to mark the current position.
1052 """ 1108 """
1053 self.unsetMarkerLine() 1109 self.unsetMarkerLine()
1054 self.__markerLine = \ 1110 self.__markerLine = \
1055 '<span style=" color:{0}; background-color:{1};">{2}</span>'.format( 1111 '<span style=" color:{0}; background-color:{1};">{2}</span>'\
1056 Preferences.getIrc("MarkerLineForegroundColour"), 1112 .format(Preferences.getIrc("MarkerLineForegroundColour"),
1057 Preferences.getIrc("MarkerLineBackgroundColour"), 1113 Preferences.getIrc("MarkerLineBackgroundColour"),
1058 self.trUtf8('--- New From Here ---')) 1114 self.trUtf8('--- New From Here ---'))
1059 self.messages.append(self.__markerLine) 1115 self.messages.append(self.__markerLine)
1060 1116
1061 def unsetMarkerLine(self): 1117 def unsetMarkerLine(self):
1062 """ 1118 """
1063 Public method to remove the marker line. 1119 Public method to remove the marker line.
1080 """ 1136 """
1081 self.messages.clear() 1137 self.messages.clear()
1082 1138
1083 def __copyMessages(self): 1139 def __copyMessages(self):
1084 """ 1140 """
1085 Private slot to copy the selection of the messages display to the clipboard. 1141 Private slot to copy the selection of the messages display to the
1142 clipboard.
1086 """ 1143 """
1087 self.messages.copy() 1144 self.messages.copy()
1088 1145
1089 def __copyAllMessages(self): 1146 def __copyAllMessages(self):
1090 """ 1147 """
1091 Private slot to copy the contents of the messages display to the clipboard. 1148 Private slot to copy the contents of the messages display to the
1149 clipboard.
1092 """ 1150 """
1093 txt = self.messages.toPlainText() 1151 txt = self.messages.toPlainText()
1094 if txt: 1152 if txt:
1095 cb = QApplication.clipboard() 1153 cb = QApplication.clipboard()
1096 cb.setText(txt) 1154 cb.setText(txt)
1097 1155
1098 def __cutAllMessages(self): 1156 def __cutAllMessages(self):
1099 """ 1157 """
1100 Private slot to cut the contents of the messages display to the clipboard. 1158 Private slot to cut the contents of the messages display to the
1159 clipboard.
1101 """ 1160 """
1102 txt = self.messages.toPlainText() 1161 txt = self.messages.toPlainText()
1103 if txt: 1162 if txt:
1104 cb = QApplication.clipboard() 1163 cb = QApplication.clipboard()
1105 cb.setText(txt) 1164 cb.setText(txt)
1118 fname, selectedFilter = E5FileDialog.getSaveFileNameAndFilter( 1177 fname, selectedFilter = E5FileDialog.getSaveFileNameAndFilter(
1119 self, 1178 self,
1120 self.trUtf8("Save Messages"), 1179 self.trUtf8("Save Messages"),
1121 "", 1180 "",
1122 self.trUtf8( 1181 self.trUtf8(
1123 "HTML Files (*.{0});;Text Files (*.txt);;All Files (*)").format( 1182 "HTML Files (*.{0});;Text Files (*.txt);;All Files (*)")
1124 htmlExtension), 1183 .format(htmlExtension),
1125 None, 1184 None,
1126 E5FileDialog.Options(E5FileDialog.DontConfirmOverwrite)) 1185 E5FileDialog.Options(E5FileDialog.DontConfirmOverwrite))
1127 if fname: 1186 if fname:
1128 ext = QFileInfo(fname).suffix() 1187 ext = QFileInfo(fname).suffix()
1129 if not ext: 1188 if not ext:
1150 f.write(txt) 1209 f.write(txt)
1151 f.close() 1210 f.close()
1152 except IOError as err: 1211 except IOError as err:
1153 E5MessageBox.critical(self, 1212 E5MessageBox.critical(self,
1154 self.trUtf8("Error saving Messages"), 1213 self.trUtf8("Error saving Messages"),
1155 self.trUtf8("""<p>The messages contents could not be written""" 1214 self.trUtf8(
1156 """ to <b>{0}</b></p><p>Reason: {1}</p>""")\ 1215 """<p>The messages contents could not be written"""
1216 """ to <b>{0}</b></p><p>Reason: {1}</p>""")
1157 .format(fname, str(err))) 1217 .format(fname, str(err)))
1158 1218
1159 def __initMessagesMenu(self): 1219 def __initMessagesMenu(self):
1160 """ 1220 """
1161 Private slot to initialize the context menu of the messages pane. 1221 Private slot to initialize the context menu of the messages pane.
1187 self.__messagesMenu.addSeparator() 1247 self.__messagesMenu.addSeparator()
1188 self.__setMarkerMessagesAct = \ 1248 self.__setMarkerMessagesAct = \
1189 self.__messagesMenu.addAction(self.trUtf8("Mark Current Position"), 1249 self.__messagesMenu.addAction(self.trUtf8("Mark Current Position"),
1190 self.setMarkerLine) 1250 self.setMarkerLine)
1191 self.__unsetMarkerMessagesAct = \ 1251 self.__unsetMarkerMessagesAct = \
1192 self.__messagesMenu.addAction(self.trUtf8("Remove Position Marker"), 1252 self.__messagesMenu.addAction(
1253 self.trUtf8("Remove Position Marker"),
1193 self.unsetMarkerLine) 1254 self.unsetMarkerLine)
1194 1255
1195 self.on_messages_copyAvailable(False) 1256 self.on_messages_copyAvailable(False)
1196 1257
1197 @pyqtSlot(bool) 1258 @pyqtSlot(bool)
1198 def on_messages_copyAvailable(self, yes): 1259 def on_messages_copyAvailable(self, yes):
1199 """ 1260 """
1200 Private slot to react to text selection/deselection of the messages edit. 1261 Private slot to react to text selection/deselection of the messages
1262 edit.
1201 1263
1202 @param yes flag signaling the availability of selected text (boolean) 1264 @param yes flag signaling the availability of selected text (boolean)
1203 """ 1265 """
1204 self.__copyMessagesAct.setEnabled(yes) 1266 self.__copyMessagesAct.setEnabled(yes)
1205 1267
1302 self.__autoWhoRequested = True 1364 self.__autoWhoRequested = True
1303 self.sendData.emit(self.__autoWhoTemplate.format(self.__name)) 1365 self.sendData.emit(self.__autoWhoTemplate.format(self.__name))
1304 1366
1305 def __autoWhoEntry(self, match): 1367 def __autoWhoEntry(self, match):
1306 """ 1368 """
1307 Private method to handle a WHO entry returned by the server as requested 1369 Private method to handle a WHO entry returned by the server as
1308 automatically. 1370 requested automatically.
1309 1371
1310 @param match match object that matched the pattern 1372 @param match match object that matched the pattern
1311 @return flag indicating whether the message was handled (boolean) 1373 @return flag indicating whether the message was handled (boolean)
1312 """ 1374 """
1313 # group(1) nick 1375 # group(1) nick
1331 if self.__autoWhoRequested: 1393 if self.__autoWhoRequested:
1332 self.__autoWhoRequested = False 1394 self.__autoWhoRequested = False
1333 self.initAutoWho() 1395 self.initAutoWho()
1334 else: 1396 else:
1335 self.__addManagementMessage(self.trUtf8("Who"), 1397 self.__addManagementMessage(self.trUtf8("Who"),
1336 self.trUtf8("End of WHO list for {0}.").format(match.group(1))) 1398 self.trUtf8("End of WHO list for {0}.").format(
1399 match.group(1)))
1337 return True 1400 return True
1338 1401
1339 return False 1402 return False
1340 1403
1341 def __whoEntry(self, match): 1404 def __whoEntry(self, match):
1342 """ 1405 """
1343 Private method to handle a WHO entry returned by the server as requested 1406 Private method to handle a WHO entry returned by the server as
1344 manually. 1407 requested manually.
1345 1408
1346 @param match match object that matched the pattern 1409 @param match match object that matched the pattern
1347 @return flag indicating whether the message was handled (boolean) 1410 @return flag indicating whether the message was handled (boolean)
1348 """ 1411 """
1349 # group(1) channel 1412 # group(1) channel
1351 # group(3) host 1414 # group(3) host
1352 # group(4) nick 1415 # group(4) nick
1353 # group(5) user flags 1416 # group(5) user flags
1354 # group(6) real name 1417 # group(6) real name
1355 if match.group(1).lower() == self.__name.lower(): 1418 if match.group(1).lower() == self.__name.lower():
1356 away = self.trUtf8(" (Away)") if match.group(5).startswith("G") else "" 1419 away = self.trUtf8(" (Away)") if match.group(5).startswith("G") \
1420 else ""
1357 self.__addManagementMessage(self.trUtf8("Who"), 1421 self.__addManagementMessage(self.trUtf8("Who"),
1358 self.trUtf8("{0} is {1}@{2} ({3}){4}").format( 1422 self.trUtf8("{0} is {1}@{2} ({3}){4}").format(
1359 match.group(4), match.group(2), match.group(3), match.group(6), away)) 1423 match.group(4), match.group(2), match.group(3),
1424 match.group(6), away))
1360 return True 1425 return True
1361 1426
1362 return False 1427 return False
1363 1428
1364 def __whoIsUser(self, match): 1429 def __whoIsUser(self, match):
1456 # group(1) nick 1521 # group(1) nick
1457 # group(2) server 1522 # group(2) server
1458 # group(3) server info 1523 # group(3) server info
1459 if match.group(1) == self.__whoIsNick: 1524 if match.group(1) == self.__whoIsNick:
1460 self.__addManagementMessage(self.trUtf8("Whois"), 1525 self.__addManagementMessage(self.trUtf8("Whois"),
1461 self.trUtf8("{0} is online via {1} ({2}).").format(match.group(1), 1526 self.trUtf8("{0} is online via {1} ({2}).").format(
1462 match.group(2), match.group(3))) 1527 match.group(1), match.group(2), match.group(3)))
1463 return True 1528 return True
1464 1529
1465 return False 1530 return False
1466 1531
1467 def __whoIsOperator(self, match): 1532 def __whoIsOperator(self, match):
1474 # group(1) nick 1539 # group(1) nick
1475 # group(2) message 1540 # group(2) message
1476 if match.group(1) == self.__whoIsNick: 1541 if match.group(1) == self.__whoIsNick:
1477 if match.group(2).lower().startswith("is an irc operator"): 1542 if match.group(2).lower().startswith("is an irc operator"):
1478 self.__addManagementMessage(self.trUtf8("Whois"), 1543 self.__addManagementMessage(self.trUtf8("Whois"),
1479 self.trUtf8("{0} is an IRC Operator.").format(match.group(1))) 1544 self.trUtf8("{0} is an IRC Operator.").format(
1545 match.group(1)))
1480 else: 1546 else:
1481 self.__addManagementMessage(self.trUtf8("Whois"), 1547 self.__addManagementMessage(self.trUtf8("Whois"),
1482 "{0} {1}".format(match.group(1), match.group(2))) 1548 "{0} {1}".format(match.group(1), match.group(2)))
1483 return True 1549 return True
1484 1550
1508 daysString = self.trUtf8("%n day(s)", "", days) 1574 daysString = self.trUtf8("%n day(s)", "", days)
1509 hoursString = self.trUtf8("%n hour(s)", "", hours) 1575 hoursString = self.trUtf8("%n hour(s)", "", hours)
1510 minutesString = self.trUtf8("%n minute(s)", "", minutes) 1576 minutesString = self.trUtf8("%n minute(s)", "", minutes)
1511 secondsString = self.trUtf8("%n second(s)", "", seconds) 1577 secondsString = self.trUtf8("%n second(s)", "", seconds)
1512 self.__addManagementMessage(self.trUtf8("Whois"), 1578 self.__addManagementMessage(self.trUtf8("Whois"),
1513 self.trUtf8("{0} has been idle for {1}, {2}, {3}, and {4}.", 1579 self.trUtf8(
1514 "{0} = name of person, {1} = (x days), {2} = (x hours)," 1580 "{0} has been idle for {1}, {2}, {3}, and {4}.",
1515 " {3} = (x minutes), {4} = (x seconds)").format( 1581 "{0} = name of person, {1} = (x days),"
1516 match.group(1), daysString, hoursString, minutesString, 1582 " {2} = (x hours), {3} = (x minutes),"
1517 secondsString)) 1583 " {4} = (x seconds)").format(
1584 match.group(1), daysString, hoursString, minutesString,
1585 secondsString))
1518 elif hours: 1586 elif hours:
1519 hoursString = self.trUtf8("%n hour(s)", "", hours) 1587 hoursString = self.trUtf8("%n hour(s)", "", hours)
1520 minutesString = self.trUtf8("%n minute(s)", "", minutes) 1588 minutesString = self.trUtf8("%n minute(s)", "", minutes)
1521 secondsString = self.trUtf8("%n second(s)", "", seconds) 1589 secondsString = self.trUtf8("%n second(s)", "", seconds)
1522 self.__addManagementMessage(self.trUtf8("Whois"), 1590 self.__addManagementMessage(self.trUtf8("Whois"),
1538 seconds).format(match.group(1))) 1606 seconds).format(match.group(1)))
1539 1607
1540 if not signonTime.isNull(): 1608 if not signonTime.isNull():
1541 self.__addManagementMessage(self.trUtf8("Whois"), 1609 self.__addManagementMessage(self.trUtf8("Whois"),
1542 self.trUtf8("{0} has been online since {1}.").format( 1610 self.trUtf8("{0} has been online since {1}.").format(
1543 match.group(1), signonTime.toString("yyyy-MM-dd, hh:mm:ss"))) 1611 match.group(1),
1612 signonTime.toString("yyyy-MM-dd, hh:mm:ss")))
1544 return True 1613 return True
1545 1614
1546 return False 1615 return False
1547 1616
1548 def __whoIsEnd(self, match): 1617 def __whoIsEnd(self, match):
1555 # group(1) nick 1624 # group(1) nick
1556 # group(2) end message 1625 # group(2) end message
1557 if match.group(1) == self.__whoIsNick: 1626 if match.group(1) == self.__whoIsNick:
1558 self.__whoIsNick = "" 1627 self.__whoIsNick = ""
1559 self.__addManagementMessage(self.trUtf8("Whois"), 1628 self.__addManagementMessage(self.trUtf8("Whois"),
1560 self.trUtf8("End of WHOIS list for {0}.").format(match.group(1))) 1629 self.trUtf8("End of WHOIS list for {0}.").format(
1630 match.group(1)))
1561 return True 1631 return True
1562 1632
1563 return False 1633 return False
1564 1634
1565 def __whoIsIdentify(self, match): 1635 def __whoIsIdentify(self, match):
1571 """ 1641 """
1572 # group(1) nick 1642 # group(1) nick
1573 # group(2) identified message 1643 # group(2) identified message
1574 if match.group(1) == self.__whoIsNick: 1644 if match.group(1) == self.__whoIsNick:
1575 self.__addManagementMessage(self.trUtf8("Whois"), 1645 self.__addManagementMessage(self.trUtf8("Whois"),
1576 self.trUtf8("{0} is an identified user.").format(match.group(1))) 1646 self.trUtf8("{0} is an identified user.").format(
1647 match.group(1)))
1577 return True 1648 return True
1578 1649
1579 return False 1650 return False
1580 1651
1581 def __whoIsHelper(self, match): 1652 def __whoIsHelper(self, match):
1587 """ 1658 """
1588 # group(1) nick 1659 # group(1) nick
1589 # group(2) helper message 1660 # group(2) helper message
1590 if match.group(1) == self.__whoIsNick: 1661 if match.group(1) == self.__whoIsNick:
1591 self.__addManagementMessage(self.trUtf8("Whois"), 1662 self.__addManagementMessage(self.trUtf8("Whois"),
1592 self.trUtf8("{0} is available for help.").format(match.group(1))) 1663 self.trUtf8("{0} is available for help.").format(
1664 match.group(1)))
1593 return True 1665 return True
1594 1666
1595 return False 1667 return False
1596 1668
1597 def __whoIsAccount(self, match): 1669 def __whoIsAccount(self, match):
1621 # group(1) nick 1693 # group(1) nick
1622 # group(2) actual user@host 1694 # group(2) actual user@host
1623 # group(3) actual IP 1695 # group(3) actual IP
1624 if match.group(1) == self.__whoIsNick: 1696 if match.group(1) == self.__whoIsNick:
1625 self.__addManagementMessage(self.trUtf8("Whois"), 1697 self.__addManagementMessage(self.trUtf8("Whois"),
1626 self.trUtf8("{0} is actually using the host {1} (IP: {2}).").format( 1698 self.trUtf8(
1627 match.group(1), match.group(2), match.group(3))) 1699 "{0} is actually using the host {1} (IP: {2}).").format(
1700 match.group(1), match.group(2), match.group(3)))
1628 return True 1701 return True
1629 1702
1630 return False 1703 return False
1631 1704
1632 def __whoIsSecure(self, match): 1705 def __whoIsSecure(self, match):
1637 @return flag indicating whether the message was handled (boolean) 1710 @return flag indicating whether the message was handled (boolean)
1638 """ 1711 """
1639 # group(1) nick 1712 # group(1) nick
1640 if match.group(1) == self.__whoIsNick: 1713 if match.group(1) == self.__whoIsNick:
1641 self.__addManagementMessage(self.trUtf8("Whois"), 1714 self.__addManagementMessage(self.trUtf8("Whois"),
1642 self.trUtf8("{0} is using a secure connection.").format(match.group(1))) 1715 self.trUtf8("{0} is using a secure connection.").format(
1716 match.group(1)))
1643 return True 1717 return True
1644 1718
1645 return False 1719 return False
1646 1720
1647 def __whoIsConnection(self, match): 1721 def __whoIsConnection(self, match):

eric ide

mercurial