Mercurial > libervia-backend
comparison sat_frontends/quick_frontend/quick_chat.py @ 4037:524856bd7b19
massive refactoring to switch from camelCase to snake_case:
historically, Libervia (SàT before) was using camelCase as allowed by PEP8 when using a
pre-PEP8 code, to use the same coding style as in Twisted.
However, snake_case is more readable and it's better to follow PEP8 best practices, so it
has been decided to move on full snake_case. Because Libervia has a huge codebase, this
ended with a ugly mix of camelCase and snake_case.
To fix that, this patch does a big refactoring by renaming every function and method
(including bridge) that are not coming from Twisted or Wokkel, to use fully snake_case.
This is a massive change, and may result in some bugs.
author | Goffi <goffi@goffi.org> |
---|---|
date | Sat, 08 Apr 2023 13:54:42 +0200 |
parents | 78b5f356900c |
children | 4b842c1fb686 |
comparison
equal
deleted
inserted
replaced
4036:c4464d7ae97b | 4037:524856bd7b19 |
---|---|
53 self.to_jid = to_jid | 53 self.to_jid = to_jid |
54 self.message = msg | 54 self.message = msg |
55 self.subject = subject | 55 self.subject = subject |
56 self.type = type_ | 56 self.type = type_ |
57 self.extra = extra | 57 self.extra = extra |
58 self.nick = self.getNick(from_jid) | 58 self.nick = self.get_nick(from_jid) |
59 self._status = None | 59 self._status = None |
60 # own_mess is True if message was sent by profile's jid | 60 # own_mess is True if message was sent by profile's jid |
61 self.own_mess = ( | 61 self.own_mess = ( |
62 (from_jid.resource == self.parent.nick) | 62 (from_jid.resource == self.parent.nick) |
63 if self.parent.type == C.CHAT_GROUP | 63 if self.parent.type == C.CHAT_GROUP |
67 if self.parent.type == C.CHAT_GROUP and not self.own_mess: | 67 if self.parent.type == C.CHAT_GROUP and not self.own_mess: |
68 for m in msg.values(): | 68 for m in msg.values(): |
69 if self.parent.nick.lower() in m.lower(): | 69 if self.parent.nick.lower() in m.lower(): |
70 self._mention = True | 70 self._mention = True |
71 break | 71 break |
72 self.handleMe() | 72 self.handle_me() |
73 self.widgets = set() # widgets linked to this message | 73 self.widgets = set() # widgets linked to this message |
74 | 74 |
75 def __str__(self): | 75 def __str__(self): |
76 return "Message<{mess_type}> [{time}]{nick}> {message}".format( | 76 return "Message<{mess_type}> [{time}]{nick}> {message}".format( |
77 mess_type=self.type, | 77 mess_type=self.type, |
145 contact_list = self.host.contact_lists[self.profile] | 145 contact_list = self.host.contact_lists[self.profile] |
146 try: | 146 try: |
147 return contact_list.getCache(entity, "avatar") | 147 return contact_list.getCache(entity, "avatar") |
148 except (exceptions.NotFound, KeyError): | 148 except (exceptions.NotFound, KeyError): |
149 # we don't check the result as the avatar listener will be called | 149 # we don't check the result as the avatar listener will be called |
150 self.host.bridge.avatarGet(entity, True, self.profile) | 150 self.host.bridge.avatar_get(entity, True, self.profile) |
151 return None | 151 return None |
152 | 152 |
153 @property | 153 @property |
154 def encrypted(self): | 154 def encrypted(self): |
155 return self.extra.get("encrypted", False) | 155 return self.extra.get("encrypted", False) |
156 | 156 |
157 def getNick(self, entity): | 157 def get_nick(self, entity): |
158 """Return nick of an entity when possible""" | 158 """Return nick of an entity when possible""" |
159 contact_list = self.host.contact_lists[self.profile] | 159 contact_list = self.host.contact_lists[self.profile] |
160 if self.type == C.MESS_TYPE_INFO and self.info_type in ROOM_USER_MOVED: | 160 if self.type == C.MESS_TYPE_INFO and self.info_type in ROOM_USER_MOVED: |
161 try: | 161 try: |
162 return self.extra["user_nick"] | 162 return self.extra["user_nick"] |
163 except KeyError: | 163 except KeyError: |
164 log.error("extra data is missing user nick for uid {}".format(self.uid)) | 164 log.error("extra data is missing user nick for uid {}".format(self.uid)) |
165 return "" | 165 return "" |
166 # FIXME: converted getSpecials to list for pyjamas | 166 # FIXME: converted get_specials to list for pyjamas |
167 if self.parent.type == C.CHAT_GROUP or entity in list( | 167 if self.parent.type == C.CHAT_GROUP or entity in list( |
168 contact_list.getSpecials(C.CONTACT_SPECIAL_GROUP) | 168 contact_list.get_specials(C.CONTACT_SPECIAL_GROUP) |
169 ): | 169 ): |
170 return entity.resource or "" | 170 return entity.resource or "" |
171 if entity.bare in contact_list: | 171 if entity.bare in contact_list: |
172 | 172 |
173 try: | 173 try: |
174 nicknames = contact_list.getCache(entity, "nicknames") | 174 nicknames = contact_list.getCache(entity, "nicknames") |
175 except (exceptions.NotFound, KeyError): | 175 except (exceptions.NotFound, KeyError): |
176 # we check result as listener will be called | 176 # we check result as listener will be called |
177 self.host.bridge.identityGet( | 177 self.host.bridge.identity_get( |
178 entity.bare, ["nicknames"], True, self.profile) | 178 entity.bare, ["nicknames"], True, self.profile) |
179 return entity.node or entity | 179 return entity.node or entity |
180 | 180 |
181 if nicknames: | 181 if nicknames: |
182 return nicknames[0] | 182 return nicknames[0] |
198 if status != self._status: | 198 if status != self._status: |
199 self._status = status | 199 self._status = status |
200 for w in self.widgets: | 200 for w in self.widgets: |
201 w.update({"status": status}) | 201 w.update({"status": status}) |
202 | 202 |
203 def handleMe(self): | 203 def handle_me(self): |
204 """Check if messages starts with "/me " and change them if it is the case | 204 """Check if messages starts with "/me " and change them if it is the case |
205 | 205 |
206 if several messages (different languages) are presents, they all need to start with "/me " | 206 if several messages (different languages) are presents, they all need to start with "/me " |
207 """ | 207 """ |
208 # TODO: XHTML-IM /me are not handled | 208 # TODO: XHTML-IM /me are not handled |
304 self.encrypted = False # True if this session is currently encrypted | 304 self.encrypted = False # True if this session is currently encrypted |
305 self._locked = False | 305 self._locked = False |
306 # True when resync is in progress, avoid resynchronising twice when resync is called | 306 # True when resync is in progress, avoid resynchronising twice when resync is called |
307 # and history is still being updated. For internal use only | 307 # and history is still being updated. For internal use only |
308 self._resync_lock = False | 308 self._resync_lock = False |
309 self.setLocked() | 309 self.set_locked() |
310 if type_ == C.CHAT_GROUP: | 310 if type_ == C.CHAT_GROUP: |
311 if target.resource: | 311 if target.resource: |
312 raise exceptions.InternalError( | 312 raise exceptions.InternalError( |
313 "a group chat entity can't have a resource" | 313 "a group chat entity can't have a resource" |
314 ) | 314 ) |
315 if nick is None: | 315 if nick is None: |
316 raise exceptions.InternalError("nick must not be None for group chat") | 316 raise exceptions.InternalError("nick must not be None for group chat") |
317 | 317 |
318 self.nick = nick | 318 self.nick = nick |
319 self.occupants = {} | 319 self.occupants = {} |
320 self.setOccupants(occupants) | 320 self.set_occupants(occupants) |
321 else: | 321 else: |
322 if occupants is not None or nick is not None: | 322 if occupants is not None or nick is not None: |
323 raise exceptions.InternalError( | 323 raise exceptions.InternalError( |
324 "only group chat can have occupants or nick" | 324 "only group chat can have occupants or nick" |
325 ) | 325 ) |
338 lt.tm_wday, | 338 lt.tm_wday, |
339 lt.tm_yday, | 339 lt.tm_yday, |
340 lt.tm_isdst, | 340 lt.tm_isdst, |
341 ) # struct_time of day changing time | 341 ) # struct_time of day changing time |
342 if self.host.AVATARS_HANDLER: | 342 if self.host.AVATARS_HANDLER: |
343 self.host.addListener("avatar", self.onAvatar, profiles) | 343 self.host.addListener("avatar", self.on_avatar, profiles) |
344 | 344 |
345 def setLocked(self): | 345 def set_locked(self): |
346 """Set locked flag | 346 """Set locked flag |
347 | 347 |
348 To be set when we are waiting for history/search | 348 To be set when we are waiting for history/search |
349 """ | 349 """ |
350 # FIXME: we don't use getter/setter here because of pyjamas | 350 # FIXME: we don't use getter/setter here because of pyjamas |
351 # TODO: use proper getter/setter once we get rid of pyjamas | 351 # TODO: use proper getter/setter once we get rid of pyjamas |
352 if self._locked: | 352 if self._locked: |
353 log.warning("{wid} is already locked!".format(wid=self)) | 353 log.warning("{wid} is already locked!".format(wid=self)) |
354 return | 354 return |
355 self._locked = True | 355 self._locked = True |
356 # messageNew signals are cached when locked | 356 # message_new signals are cached when locked |
357 self._cache = OrderedDict() | 357 self._cache = OrderedDict() |
358 log.debug("{wid} is now locked".format(wid=self)) | 358 log.debug("{wid} is now locked".format(wid=self)) |
359 | 359 |
360 def setUnlocked(self): | 360 def set_unlocked(self): |
361 if not self._locked: | 361 if not self._locked: |
362 log.debug("{wid} was already unlocked".format(wid=self)) | 362 log.debug("{wid} was already unlocked".format(wid=self)) |
363 return | 363 return |
364 self._locked = False | 364 self._locked = False |
365 for uid, data in self._cache.items(): | 365 for uid, data in self._cache.items(): |
366 if uid not in self.messages: | 366 if uid not in self.messages: |
367 self.messageNew(*data) | 367 self.message_new(*data) |
368 else: | 368 else: |
369 log.debug("discarding message already in history: {data}, ".format(data=data)) | 369 log.debug("discarding message already in history: {data}, ".format(data=data)) |
370 del self._cache | 370 del self._cache |
371 log.debug("{wid} is now unlocked".format(wid=self)) | 371 log.debug("{wid} is now unlocked".format(wid=self)) |
372 | 372 |
373 def postInit(self): | 373 def post_init(self): |
374 """Method to be called by frontend after widget is initialised | 374 """Method to be called by frontend after widget is initialised |
375 | 375 |
376 handle the display of history and subject | 376 handle the display of history and subject |
377 """ | 377 """ |
378 self.historyPrint(profile=self.profile) | 378 self.history_print(profile=self.profile) |
379 if self.subject is not None: | 379 if self.subject is not None: |
380 self.setSubject(self.subject) | 380 self.set_subject(self.subject) |
381 if self.host.ENCRYPTION_HANDLERS: | 381 if self.host.ENCRYPTION_HANDLERS: |
382 self.getEncryptionState() | 382 self.get_encryption_state() |
383 | 383 |
384 def onDelete(self): | 384 def on_delete(self): |
385 if self.host.AVATARS_HANDLER: | 385 if self.host.AVATARS_HANDLER: |
386 self.host.removeListener("avatar", self.onAvatar) | 386 self.host.removeListener("avatar", self.on_avatar) |
387 | 387 |
388 @property | 388 @property |
389 def contact_list(self): | 389 def contact_list(self): |
390 return self.host.contact_lists[self.profile] | 390 return self.host.contact_lists[self.profile] |
391 | 391 |
401 | 401 |
402 @quick_widgets.QuickWidget.sync.setter | 402 @quick_widgets.QuickWidget.sync.setter |
403 def sync(self, state): | 403 def sync(self, state): |
404 quick_widgets.QuickWidget.sync.fset(self, state) | 404 quick_widgets.QuickWidget.sync.fset(self, state) |
405 if not state: | 405 if not state: |
406 self.setLocked() | 406 self.set_locked() |
407 | 407 |
408 def _resyncComplete(self): | 408 def _resync_complete(self): |
409 self.sync = True | 409 self.sync = True |
410 self._resync_lock = False | 410 self._resync_lock = False |
411 | 411 |
412 def occupantsClear(self): | 412 def occupants_clear(self): |
413 """Remove all occupants | 413 """Remove all occupants |
414 | 414 |
415 Must be overridden by frontends to clear their own representations of occupants | 415 Must be overridden by frontends to clear their own representations of occupants |
416 """ | 416 """ |
417 self.occupants.clear() | 417 self.occupants.clear() |
426 continue | 426 continue |
427 last_message = mess | 427 last_message = mess |
428 break | 428 break |
429 else: | 429 else: |
430 # we have no message yet, we can get normal history | 430 # we have no message yet, we can get normal history |
431 self.historyPrint(callback=self._resyncComplete, profile=self.profile) | 431 self.history_print(callback=self._resync_complete, profile=self.profile) |
432 return | 432 return |
433 if self.type == C.CHAT_GROUP: | 433 if self.type == C.CHAT_GROUP: |
434 self.occupantsClear() | 434 self.occupants_clear() |
435 self.host.bridge.mucOccupantsGet( | 435 self.host.bridge.muc_occupants_get( |
436 str(self.target), self.profile, callback=self.updateOccupants, | 436 str(self.target), self.profile, callback=self.update_occupants, |
437 errback=log.error) | 437 errback=log.error) |
438 self.historyPrint( | 438 self.history_print( |
439 size=C.HISTORY_LIMIT_NONE, | 439 size=C.HISTORY_LIMIT_NONE, |
440 filters={'timestamp_start': last_message.timestamp}, | 440 filters={'timestamp_start': last_message.timestamp}, |
441 callback=self._resyncComplete, | 441 callback=self._resync_complete, |
442 profile=self.profile) | 442 profile=self.profile) |
443 | 443 |
444 ## Widget management ## | 444 ## Widget management ## |
445 | 445 |
446 def __str__(self): | 446 def __str__(self): |
447 return "Chat Widget [target: {}, type: {}, profile: {}]".format( | 447 return "Chat Widget [target: {}, type: {}, profile: {}]".format( |
448 self.target, self.type, self.profile | 448 self.target, self.type, self.profile |
449 ) | 449 ) |
450 | 450 |
451 @staticmethod | 451 @staticmethod |
452 def getWidgetHash(target, profiles): | 452 def get_widget_hash(target, profiles): |
453 profile = list(profiles)[0] | 453 profile = list(profiles)[0] |
454 return profile + "\n" + str(target.bare) | 454 return profile + "\n" + str(target.bare) |
455 | 455 |
456 @staticmethod | 456 @staticmethod |
457 def getPrivateHash(target, profile): | 457 def get_private_hash(target, profile): |
458 """Get unique hash for private conversations | 458 """Get unique hash for private conversations |
459 | 459 |
460 This method should be used with force_hash to get unique widget for private MUC conversations | 460 This method should be used with force_hash to get unique widget for private MUC conversations |
461 """ | 461 """ |
462 return (str(profile), target) | 462 return (str(profile), target) |
463 | 463 |
464 def addTarget(self, target): | 464 def add_target(self, target): |
465 super(QuickChat, self).addTarget(target) | 465 super(QuickChat, self).add_target(target) |
466 if target.resource: | 466 if target.resource: |
467 self.current_target = ( | 467 self.current_target = ( |
468 target | 468 target |
469 ) # FIXME: tmp, must use resource priority throught contactList instead | 469 ) # FIXME: tmp, must use resource priority throught contactList instead |
470 | 470 |
471 def recreateArgs(self, args, kwargs): | 471 def recreate_args(self, args, kwargs): |
472 """copy important attribute for a new widget""" | 472 """copy important attribute for a new widget""" |
473 kwargs["type_"] = self.type | 473 kwargs["type_"] = self.type |
474 if self.type == C.CHAT_GROUP: | 474 if self.type == C.CHAT_GROUP: |
475 kwargs["occupants"] = {o.nick: o.data for o in self.occupants.values()} | 475 kwargs["occupants"] = {o.nick: o.data for o in self.occupants.values()} |
476 kwargs["subject"] = self.subject | 476 kwargs["subject"] = self.subject |
477 try: | 477 try: |
478 kwargs["nick"] = self.nick | 478 kwargs["nick"] = self.nick |
479 except AttributeError: | 479 except AttributeError: |
480 pass | 480 pass |
481 | 481 |
482 def onPrivateCreated(self, widget): | 482 def on_private_created(self, widget): |
483 """Method called when a new widget for private conversation (MUC) is created""" | 483 """Method called when a new widget for private conversation (MUC) is created""" |
484 raise NotImplementedError | 484 raise NotImplementedError |
485 | 485 |
486 def getOrCreatePrivateWidget(self, entity): | 486 def get_or_create_private_widget(self, entity): |
487 """Create a widget for private conversation, or get it if it already exists | 487 """Create a widget for private conversation, or get it if it already exists |
488 | 488 |
489 @param entity: full jid of the target | 489 @param entity: full jid of the target |
490 """ | 490 """ |
491 return self.host.widgets.getOrCreateWidget( | 491 return self.host.widgets.get_or_create_widget( |
492 QuickChat, | 492 QuickChat, |
493 entity, | 493 entity, |
494 type_=C.CHAT_ONE2ONE, | 494 type_=C.CHAT_ONE2ONE, |
495 force_hash=self.getPrivateHash(self.profile, entity), | 495 force_hash=self.get_private_hash(self.profile, entity), |
496 on_new_widget=self.onPrivateCreated, | 496 on_new_widget=self.on_private_created, |
497 profile=self.profile, | 497 profile=self.profile, |
498 ) # we force hash to have a new widget, not this one again | 498 ) # we force hash to have a new widget, not this one again |
499 | 499 |
500 @property | 500 @property |
501 def target(self): | 501 def target(self): |
503 return self.current_target.bare | 503 return self.current_target.bare |
504 return self.current_target | 504 return self.current_target |
505 | 505 |
506 ## occupants ## | 506 ## occupants ## |
507 | 507 |
508 def setOccupants(self, occupants): | 508 def set_occupants(self, occupants): |
509 """Set the whole list of occupants""" | 509 """Set the whole list of occupants""" |
510 assert len(self.occupants) == 0 | 510 assert len(self.occupants) == 0 |
511 for nick, data in occupants.items(): | 511 for nick, data in occupants.items(): |
512 # XXX: this log is disabled because it's really too verbose | 512 # XXX: this log is disabled because it's really too verbose |
513 # but kept commented as it may be useful for debugging | 513 # but kept commented as it may be useful for debugging |
514 # log.debug(u"adding occupant {nick} to {room}".format( | 514 # log.debug(u"adding occupant {nick} to {room}".format( |
515 # nick=nick, room=self.target)) | 515 # nick=nick, room=self.target)) |
516 self.occupants[nick] = Occupant(self, data, self.profile) | 516 self.occupants[nick] = Occupant(self, data, self.profile) |
517 | 517 |
518 def updateOccupants(self, occupants): | 518 def update_occupants(self, occupants): |
519 """Update occupants list | 519 """Update occupants list |
520 | 520 |
521 In opposition to setOccupants, this only add missing occupants and remove | 521 In opposition to set_occupants, this only add missing occupants and remove |
522 occupants who have left | 522 occupants who have left |
523 """ | 523 """ |
524 # FIXME: occupants with modified status are not handled | 524 # FIXME: occupants with modified status are not handled |
525 local_occupants = set(self.occupants) | 525 local_occupants = set(self.occupants) |
526 updated_occupants = set(occupants) | 526 updated_occupants = set(occupants) |
551 except KeyError: | 551 except KeyError: |
552 log.warning("Trying to remove an unknown occupant: {}".format(nick)) | 552 log.warning("Trying to remove an unknown occupant: {}".format(nick)) |
553 else: | 553 else: |
554 return occupant | 554 return occupant |
555 | 555 |
556 def setUserNick(self, nick): | 556 def set_user_nick(self, nick): |
557 """Set the nick of the user, usefull for e.g. change the color of the user""" | 557 """Set the nick of the user, usefull for e.g. change the color of the user""" |
558 self.nick = nick | 558 self.nick = nick |
559 | 559 |
560 def changeUserNick(self, old_nick, new_nick): | 560 def change_user_nick(self, old_nick, new_nick): |
561 """Change nick of a user in group list""" | 561 """Change nick of a user in group list""" |
562 log.info("{old} is now known as {new} in room {room_jid}".format( | 562 log.info("{old} is now known as {new} in room {room_jid}".format( |
563 old = old_nick, | 563 old = old_nick, |
564 new = new_nick, | 564 new = new_nick, |
565 room_jid = self.target)) | 565 room_jid = self.target)) |
566 | 566 |
567 ## Messages ## | 567 ## Messages ## |
568 | 568 |
569 def manageMessage(self, entity, mess_type): | 569 def manage_message(self, entity, mess_type): |
570 """Tell if this chat widget manage an entity and message type couple | 570 """Tell if this chat widget manage an entity and message type couple |
571 | 571 |
572 @param entity (jid.JID): (full) jid of the sending entity | 572 @param entity (jid.JID): (full) jid of the sending entity |
573 @param mess_type (str): message type as given by messageNew | 573 @param mess_type (str): message type as given by message_new |
574 @return (bool): True if this Chat Widget manage this couple | 574 @return (bool): True if this Chat Widget manage this couple |
575 """ | 575 """ |
576 if self.type == C.CHAT_GROUP: | 576 if self.type == C.CHAT_GROUP: |
577 if ( | 577 if ( |
578 mess_type in (C.MESS_TYPE_GROUPCHAT, C.MESS_TYPE_INFO) | 578 mess_type in (C.MESS_TYPE_GROUPCHAT, C.MESS_TYPE_INFO) |
582 else: | 582 else: |
583 if mess_type != C.MESS_TYPE_GROUPCHAT and entity in self.targets: | 583 if mess_type != C.MESS_TYPE_GROUPCHAT and entity in self.targets: |
584 return True | 584 return True |
585 return False | 585 return False |
586 | 586 |
587 def updateHistory(self, size=C.HISTORY_LIMIT_DEFAULT, filters=None, profile="@NONE@"): | 587 def update_history(self, size=C.HISTORY_LIMIT_DEFAULT, filters=None, profile="@NONE@"): |
588 """Called when history need to be recreated | 588 """Called when history need to be recreated |
589 | 589 |
590 Remove all message from history then call historyPrint | 590 Remove all message from history then call history_print |
591 Must probably be overriden by frontend to clear widget | 591 Must probably be overriden by frontend to clear widget |
592 @param size (int): number of messages | 592 @param size (int): number of messages |
593 @param filters (str): patterns to filter the history results | 593 @param filters (str): patterns to filter the history results |
594 @param profile (str): %(doc_profile)s | 594 @param profile (str): %(doc_profile)s |
595 """ | 595 """ |
596 self.setLocked() | 596 self.set_locked() |
597 self.messages.clear() | 597 self.messages.clear() |
598 self.historyPrint(size, filters, profile=profile) | 598 self.history_print(size, filters, profile=profile) |
599 | 599 |
600 def _onHistoryPrinted(self): | 600 def _on_history_printed(self): |
601 """Method called when history is printed (or failed) | 601 """Method called when history is printed (or failed) |
602 | 602 |
603 unlock the widget, and can be used to refresh or scroll down | 603 unlock the widget, and can be used to refresh or scroll down |
604 the focus after the history is printed | 604 the focus after the history is printed |
605 """ | 605 """ |
606 self.setUnlocked() | 606 self.set_unlocked() |
607 | 607 |
608 def historyPrint(self, size=C.HISTORY_LIMIT_DEFAULT, filters=None, callback=None, | 608 def history_print(self, size=C.HISTORY_LIMIT_DEFAULT, filters=None, callback=None, |
609 profile="@NONE@"): | 609 profile="@NONE@"): |
610 """Print the current history | 610 """Print the current history |
611 | 611 |
612 Note: self.setUnlocked will be called once history is printed | 612 Note: self.set_unlocked will be called once history is printed |
613 @param size (int): number of messages | 613 @param size (int): number of messages |
614 @param search (str): pattern to filter the history results | 614 @param search (str): pattern to filter the history results |
615 @param callback(callable, None): method to call when history has been printed | 615 @param callback(callable, None): method to call when history has been printed |
616 @param profile (str): %(doc_profile)s | 616 @param profile (str): %(doc_profile)s |
617 """ | 617 """ |
618 if filters is None: | 618 if filters is None: |
619 filters = {} | 619 filters = {} |
620 if size == 0: | 620 if size == 0: |
621 log.debug("Empty history requested, skipping") | 621 log.debug("Empty history requested, skipping") |
622 self._onHistoryPrinted() | 622 self._on_history_printed() |
623 return | 623 return |
624 log_msg = _("now we print the history") | 624 log_msg = _("now we print the history") |
625 if size != C.HISTORY_LIMIT_DEFAULT: | 625 if size != C.HISTORY_LIMIT_DEFAULT: |
626 log_msg += _(" ({} messages)".format(size)) | 626 log_msg += _(" ({} messages)".format(size)) |
627 log.debug(log_msg) | 627 log.debug(log_msg) |
645 # FIXME: info not handled correctly | 645 # FIXME: info not handled correctly |
646 filters["types"] = C.MESS_TYPE_GROUPCHAT | 646 filters["types"] = C.MESS_TYPE_GROUPCHAT |
647 | 647 |
648 self.history_filters = filters | 648 self.history_filters = filters |
649 | 649 |
650 def _historyGetCb(history): | 650 def _history_get_cb(history): |
651 # day_format = "%A, %d %b %Y" # to display the day change | 651 # day_format = "%A, %d %b %Y" # to display the day change |
652 # previous_day = datetime.now().strftime(day_format) | 652 # previous_day = datetime.now().strftime(day_format) |
653 # message_day = datetime.fromtimestamp(timestamp).strftime(self.day_format) | 653 # message_day = datetime.fromtimestamp(timestamp).strftime(self.day_format) |
654 # if previous_day != message_day: | 654 # if previous_day != message_day: |
655 # self.printDayChange(message_day) | 655 # self.print_day_change(message_day) |
656 # previous_day = message_day | 656 # previous_day = message_day |
657 for data in history: | 657 for data in history: |
658 uid, timestamp, from_jid, to_jid, message, subject, type_, extra_s = data | 658 uid, timestamp, from_jid, to_jid, message, subject, type_, extra_s = data |
659 from_jid = jid.JID(from_jid) | 659 from_jid = jid.JID(from_jid) |
660 to_jid = jid.JID(to_jid) | 660 to_jid = jid.JID(to_jid) |
673 subject, | 673 subject, |
674 type_, | 674 type_, |
675 extra, | 675 extra, |
676 profile, | 676 profile, |
677 ) | 677 ) |
678 self._onHistoryPrinted() | 678 self._on_history_printed() |
679 if callback is not None: | 679 if callback is not None: |
680 callback() | 680 callback() |
681 | 681 |
682 def _historyGetEb(err): | 682 def _history_get_eb(err): |
683 log.error(_("Can't get history: {}").format(err)) | 683 log.error(_("Can't get history: {}").format(err)) |
684 self._onHistoryPrinted() | 684 self._on_history_printed() |
685 if callback is not None: | 685 if callback is not None: |
686 callback() | 686 callback() |
687 | 687 |
688 self.host.bridge.historyGet( | 688 self.host.bridge.history_get( |
689 str(self.host.profiles[profile].whoami.bare), | 689 str(self.host.profiles[profile].whoami.bare), |
690 str(target), | 690 str(target), |
691 size, | 691 size, |
692 True, | 692 True, |
693 {k: str(v) for k,v in filters.items()}, | 693 {k: str(v) for k,v in filters.items()}, |
694 profile, | 694 profile, |
695 callback=_historyGetCb, | 695 callback=_history_get_cb, |
696 errback=_historyGetEb, | 696 errback=_history_get_eb, |
697 ) | 697 ) |
698 | 698 |
699 def messageEncryptionGetCb(self, session_data): | 699 def message_encryption_get_cb(self, session_data): |
700 if session_data: | 700 if session_data: |
701 session_data = data_format.deserialise(session_data) | 701 session_data = data_format.deserialise(session_data) |
702 self.messageEncryptionStarted(session_data) | 702 self.message_encryption_started(session_data) |
703 | 703 |
704 def messageEncryptionGetEb(self, failure_): | 704 def message_encryption_get_eb(self, failure_): |
705 log.error(_("Can't get encryption state: {reason}").format(reason=failure_)) | 705 log.error(_("Can't get encryption state: {reason}").format(reason=failure_)) |
706 | 706 |
707 def getEncryptionState(self): | 707 def get_encryption_state(self): |
708 """Retrieve encryption state with current target. | 708 """Retrieve encryption state with current target. |
709 | 709 |
710 Once state is retrieved, default messageEncryptionStarted will be called if | 710 Once state is retrieved, default message_encryption_started will be called if |
711 suitable | 711 suitable |
712 """ | 712 """ |
713 if self.type == C.CHAT_GROUP: | 713 if self.type == C.CHAT_GROUP: |
714 return | 714 return |
715 self.host.bridge.messageEncryptionGet(str(self.target.bare), self.profile, | 715 self.host.bridge.message_encryption_get(str(self.target.bare), self.profile, |
716 callback=self.messageEncryptionGetCb, | 716 callback=self.message_encryption_get_cb, |
717 errback=self.messageEncryptionGetEb) | 717 errback=self.message_encryption_get_eb) |
718 | 718 |
719 | 719 |
720 def messageNew(self, uid, timestamp, from_jid, to_jid, msg, subject, type_, extra, | 720 def message_new(self, uid, timestamp, from_jid, to_jid, msg, subject, type_, extra, |
721 profile): | 721 profile): |
722 if self._locked: | 722 if self._locked: |
723 self._cache[uid] = ( | 723 self._cache[uid] = ( |
724 uid, | 724 uid, |
725 timestamp, | 725 timestamp, |
740 | 740 |
741 if self.type == C.CHAT_GROUP: | 741 if self.type == C.CHAT_GROUP: |
742 if to_jid.resource and type_ != C.MESS_TYPE_GROUPCHAT: | 742 if to_jid.resource and type_ != C.MESS_TYPE_GROUPCHAT: |
743 # we have a private message, we forward it to a private conversation | 743 # we have a private message, we forward it to a private conversation |
744 # widget | 744 # widget |
745 chat_widget = self.getOrCreatePrivateWidget(to_jid) | 745 chat_widget = self.get_or_create_private_widget(to_jid) |
746 chat_widget.messageNew( | 746 chat_widget.message_new( |
747 uid, timestamp, from_jid, to_jid, msg, subject, type_, extra, profile | 747 uid, timestamp, from_jid, to_jid, msg, subject, type_, extra, profile |
748 ) | 748 ) |
749 return | 749 return |
750 if type_ == C.MESS_TYPE_INFO: | 750 if type_ == C.MESS_TYPE_INFO: |
751 try: | 751 try: |
766 ) | 766 ) |
767 self.messages[uid] = message | 767 self.messages[uid] = message |
768 | 768 |
769 if "received_timestamp" in extra: | 769 if "received_timestamp" in extra: |
770 log.warning("Delayed message received after history, this should not happen") | 770 log.warning("Delayed message received after history, this should not happen") |
771 self.createMessage(message) | 771 self.create_message(message) |
772 | 772 |
773 def messageEncryptionStarted(self, session_data): | 773 def message_encryption_started(self, session_data): |
774 self.encrypted = True | 774 self.encrypted = True |
775 log.debug(_("message encryption started with {target} using {encryption}").format( | 775 log.debug(_("message encryption started with {target} using {encryption}").format( |
776 target=self.target, encryption=session_data['name'])) | 776 target=self.target, encryption=session_data['name'])) |
777 | 777 |
778 def messageEncryptionStopped(self, session_data): | 778 def message_encryption_stopped(self, session_data): |
779 self.encrypted = False | 779 self.encrypted = False |
780 log.debug(_("message encryption stopped with {target} (was using {encryption})") | 780 log.debug(_("message encryption stopped with {target} (was using {encryption})") |
781 .format(target=self.target, encryption=session_data['name'])) | 781 .format(target=self.target, encryption=session_data['name'])) |
782 | 782 |
783 def createMessage(self, message, append=False): | 783 def create_message(self, message, append=False): |
784 """Must be implemented by frontend to create and show a new message widget | 784 """Must be implemented by frontend to create and show a new message widget |
785 | 785 |
786 This is only called on messageNew, not on history. | 786 This is only called on message_new, not on history. |
787 You need to override historyPrint to handle the later | 787 You need to override history_print to handle the later |
788 @param message(Message): message data | 788 @param message(Message): message data |
789 """ | 789 """ |
790 raise NotImplementedError | 790 raise NotImplementedError |
791 | 791 |
792 def isUserMoved(self, message): | 792 def is_user_moved(self, message): |
793 """Return True if message is a user left/joined message | 793 """Return True if message is a user left/joined message |
794 | 794 |
795 @param message(Message): message to check | 795 @param message(Message): message to check |
796 @return (bool): True is message is user moved info message | 796 @return (bool): True is message is user moved info message |
797 """ | 797 """ |
802 except KeyError: | 802 except KeyError: |
803 return False | 803 return False |
804 else: | 804 else: |
805 return info_type in ROOM_USER_MOVED | 805 return info_type in ROOM_USER_MOVED |
806 | 806 |
807 def handleUserMoved(self, message): | 807 def handle_user_moved(self, message): |
808 """Check if this message is a UserMoved one, and merge it when possible | 808 """Check if this message is a UserMoved one, and merge it when possible |
809 | 809 |
810 "merge it" means that info message indicating a user joined/left will be | 810 "merge it" means that info message indicating a user joined/left will be |
811 grouped if no other non-info messages has been sent since | 811 grouped if no other non-info messages has been sent since |
812 @param message(Message): message to check | 812 @param message(Message): message to check |
813 @return (bool): True if this message has been merged | 813 @return (bool): True if this message has been merged |
814 if True, a new MessageWidget must not be created and appended to history | 814 if True, a new MessageWidget must not be created and appended to history |
815 """ | 815 """ |
816 if self.isUserMoved(message): | 816 if self.is_user_moved(message): |
817 for wid in self.message_widgets_rev: | 817 for wid in self.message_widgets_rev: |
818 # we merge in/out messages if no message was sent meanwhile | 818 # we merge in/out messages if no message was sent meanwhile |
819 if not isinstance(wid, MessageWidget): | 819 if not isinstance(wid, MessageWidget): |
820 continue | 820 continue |
821 elif wid.mess_data.type != C.MESS_TYPE_INFO: | 821 elif wid.mess_data.type != C.MESS_TYPE_INFO: |
839 ).format(nick=nick, count=count) | 839 ).format(nick=nick, count=count) |
840 wid.reentered_count += 1 | 840 wid.reentered_count += 1 |
841 return True | 841 return True |
842 return False | 842 return False |
843 | 843 |
844 def printDayChange(self, day): | 844 def print_day_change(self, day): |
845 """Display the day on a new line. | 845 """Display the day on a new line. |
846 | 846 |
847 @param day(unicode): day to display (or not if this method is not overwritten) | 847 @param day(unicode): day to display (or not if this method is not overwritten) |
848 """ | 848 """ |
849 # FIXME: not called anymore after refactoring | 849 # FIXME: not called anymore after refactoring |
850 pass | 850 pass |
851 | 851 |
852 ## Room ## | 852 ## Room ## |
853 | 853 |
854 def setSubject(self, subject): | 854 def set_subject(self, subject): |
855 """Set title for a group chat""" | 855 """Set title for a group chat""" |
856 if self.type != C.CHAT_GROUP: | 856 if self.type != C.CHAT_GROUP: |
857 raise exceptions.InternalError( | 857 raise exceptions.InternalError( |
858 "trying to set subject for a non group chat window" | 858 "trying to set subject for a non group chat window" |
859 ) | 859 ) |
860 self.subject = subject | 860 self.subject = subject |
861 | 861 |
862 def changeSubject(self, new_subject): | 862 def change_subject(self, new_subject): |
863 """Change the subject of the room | 863 """Change the subject of the room |
864 | 864 |
865 This change the subject on the room itself (i.e. via XMPP), | 865 This change the subject on the room itself (i.e. via XMPP), |
866 while setSubject change the subject of this widget | 866 while set_subject change the subject of this widget |
867 """ | 867 """ |
868 self.host.bridge.mucSubject(str(self.target), new_subject, self.profile) | 868 self.host.bridge.muc_subject(str(self.target), new_subject, self.profile) |
869 | 869 |
870 def addGamePanel(self, widget): | 870 def add_game_panel(self, widget): |
871 """Insert a game panel to this Chat dialog. | 871 """Insert a game panel to this Chat dialog. |
872 | 872 |
873 @param widget (Widget): the game panel | 873 @param widget (Widget): the game panel |
874 """ | 874 """ |
875 raise NotImplementedError | 875 raise NotImplementedError |
876 | 876 |
877 def removeGamePanel(self, widget): | 877 def remove_game_panel(self, widget): |
878 """Remove the game panel from this Chat dialog. | 878 """Remove the game panel from this Chat dialog. |
879 | 879 |
880 @param widget (Widget): the game panel | 880 @param widget (Widget): the game panel |
881 """ | 881 """ |
882 raise NotImplementedError | 882 raise NotImplementedError |
889 # FIXME: to remove ? | 889 # FIXME: to remove ? |
890 raise NotImplementedError | 890 raise NotImplementedError |
891 | 891 |
892 ## events ## | 892 ## events ## |
893 | 893 |
894 def onChatState(self, from_jid, state, profile): | 894 def on_chat_state(self, from_jid, state, profile): |
895 """A chat state has been received""" | 895 """A chat state has been received""" |
896 if self.type == C.CHAT_GROUP: | 896 if self.type == C.CHAT_GROUP: |
897 nick = from_jid.resource | 897 nick = from_jid.resource |
898 try: | 898 try: |
899 self.occupants[nick].state = state | 899 self.occupants[nick].state = state |
902 "{nick} not found in {room}, ignoring new chat state".format( | 902 "{nick} not found in {room}, ignoring new chat state".format( |
903 nick=nick, room=self.target.bare | 903 nick=nick, room=self.target.bare |
904 ) | 904 ) |
905 ) | 905 ) |
906 | 906 |
907 def onMessageState(self, uid, status, profile): | 907 def on_message_state(self, uid, status, profile): |
908 try: | 908 try: |
909 mess_data = self.messages[uid] | 909 mess_data = self.messages[uid] |
910 except KeyError: | 910 except KeyError: |
911 pass | 911 pass |
912 else: | 912 else: |
913 mess_data.status = status | 913 mess_data.status = status |
914 | 914 |
915 def onAvatar(self, entity, avatar_data, profile): | 915 def on_avatar(self, entity, avatar_data, profile): |
916 if self.type == C.CHAT_GROUP: | 916 if self.type == C.CHAT_GROUP: |
917 if entity.bare == self.target: | 917 if entity.bare == self.target: |
918 try: | 918 try: |
919 self.occupants[entity.resource].update({"avatar": avatar_data}) | 919 self.occupants[entity.resource].update({"avatar": avatar_data}) |
920 except KeyError: | 920 except KeyError: |