Mercurial > libervia-backend
comparison sat_frontends/quick_frontend/quick_contact_list.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 | be6d91572633 |
children | 4b842c1fb686 |
comparison
equal
deleted
inserted
replaced
4036:c4464d7ae97b | 4037:524856bd7b19 |
---|---|
81 # selected entities, full jid | 81 # selected entities, full jid |
82 self._selected = set() | 82 self._selected = set() |
83 | 83 |
84 # options | 84 # options |
85 self.show_disconnected = False | 85 self.show_disconnected = False |
86 self.show_empty_groups = True | 86 self._show_empty_groups = True |
87 self.show_resources = False | 87 self.show_resources = False |
88 self.show_status = False | 88 self.show_status = False |
89 # do we show entities with notifications? | 89 # do we show entities with notifications? |
90 # if True, entities will be show even if they normally would not | 90 # if True, entities will be show even if they normally would not |
91 # (e.g. not in contact list) if they have notifications attached | 91 # (e.g. not in contact list) if they have notifications attached |
92 self.show_entities_with_notifs = True | 92 self.show_entities_with_notifs = True |
93 | 93 |
94 self.host.bridge.asyncGetParamA( | 94 self.host.bridge.param_get_a_async( |
95 C.SHOW_EMPTY_GROUPS, | 95 C.SHOW_EMPTY_GROUPS, |
96 "General", | 96 "General", |
97 profile_key=profile, | 97 profile_key=profile, |
98 callback=self._showEmptyGroups, | 98 callback=self._show_empty_groups_cb, |
99 ) | 99 ) |
100 | 100 |
101 self.host.bridge.asyncGetParamA( | 101 self.host.bridge.param_get_a_async( |
102 C.SHOW_OFFLINE_CONTACTS, | 102 C.SHOW_OFFLINE_CONTACTS, |
103 "General", | 103 "General", |
104 profile_key=profile, | 104 profile_key=profile, |
105 callback=self._showOfflineContacts, | 105 callback=self._show_offline_contacts, |
106 ) | 106 ) |
107 | 107 |
108 self.host.addListener("presence", self.onPresenceUpdate, [self.profile]) | 108 self.host.addListener("presence", self.on_presence_update, [self.profile]) |
109 self.host.addListener("nicknames", self.onNicknamesUpdate, [self.profile]) | 109 self.host.addListener("nicknames", self.on_nicknames_update, [self.profile]) |
110 self.host.addListener("notification", self.onNotification, [self.profile]) | 110 self.host.addListener("notification", self.on_notification, [self.profile]) |
111 # onNotification only updates the entity, so we can re-use it | 111 # on_notification only updates the entity, so we can re-use it |
112 self.host.addListener("notificationsClear", self.onNotification, [self.profile]) | 112 self.host.addListener("notificationsClear", self.on_notification, [self.profile]) |
113 | 113 |
114 @property | 114 @property |
115 def whoami(self): | 115 def whoami(self): |
116 return self.host.profiles[self.profile].whoami | 116 return self.host.profiles[self.profile].whoami |
117 | 117 |
118 def _showEmptyGroups(self, show_str): | 118 def _show_empty_groups_cb(self, show_str): |
119 # Called only by __init__ | 119 # Called only by __init__ |
120 # self.update is not wanted here, as it is done by | 120 # self.update is not wanted here, as it is done by |
121 # handler when all profiles are ready | 121 # handler when all profiles are ready |
122 self.showEmptyGroups(C.bool(show_str)) | 122 self.show_empty_groups(C.bool(show_str)) |
123 | 123 |
124 def _showOfflineContacts(self, show_str): | 124 def _show_offline_contacts(self, show_str): |
125 # same comments as for _showEmptyGroups | 125 # same comments as for _show_empty_groups |
126 self.showOfflineContacts(C.bool(show_str)) | 126 self.show_offline_contacts(C.bool(show_str)) |
127 | 127 |
128 def __contains__(self, entity): | 128 def __contains__(self, entity): |
129 """Check if entity is in contact list | 129 """Check if entity is in contact list |
130 | 130 |
131 An entity can be in contact list even if not in roster | 131 An entity can be in contact list even if not in roster |
132 use isInRoster to check if entity is in roster. | 132 use is_in_roster to check if entity is in roster. |
133 @param entity (jid.JID): jid of the entity (resource is not ignored, | 133 @param entity (jid.JID): jid of the entity (resource is not ignored, |
134 use bare jid if needed) | 134 use bare jid if needed) |
135 """ | 135 """ |
136 if entity.resource: | 136 if entity.resource: |
137 try: | 137 try: |
207 key: bare jid, value: data | 207 key: bare jid, value: data |
208 """ | 208 """ |
209 return { | 209 return { |
210 jid_: cache | 210 jid_: cache |
211 for jid_, cache in self._cache.items() | 211 for jid_, cache in self._cache.items() |
212 if self.entityVisible(jid_) | 212 if self.entity_visible(jid_) |
213 } | 213 } |
214 | 214 |
215 def getItem(self, entity): | 215 def get_item(self, entity): |
216 """Return item representation of requested entity | 216 """Return item representation of requested entity |
217 | 217 |
218 @param entity(jid.JID): bare jid of entity | 218 @param entity(jid.JID): bare jid of entity |
219 @raise (KeyError): entity is unknown | 219 @raise (KeyError): entity is unknown |
220 """ | 220 """ |
221 return self._cache[entity] | 221 return self._cache[entity] |
222 | 222 |
223 def _gotContacts(self, contacts): | 223 def _got_contacts(self, contacts): |
224 """Add contacts and notice parent that contacts are filled | 224 """Add contacts and notice parent that contacts are filled |
225 | 225 |
226 Called during initial contact list filling | 226 Called during initial contact list filling |
227 @param contacts(tuple): all contacts | 227 @param contacts(tuple): all contacts |
228 """ | 228 """ |
233 # will cause troubles | 233 # will cause troubles |
234 log.warning( | 234 log.warning( |
235 "Roster entities with resources are not managed, ignoring {entity}" | 235 "Roster entities with resources are not managed, ignoring {entity}" |
236 .format(entity=entity)) | 236 .format(entity=entity)) |
237 continue | 237 continue |
238 self.host.newContactHandler(*contact, profile=self.profile) | 238 self.host.contact_new_handler(*contact, profile=self.profile) |
239 handler._contactsFilled(self.profile) | 239 handler._contacts_filled(self.profile) |
240 | 240 |
241 def _fill(self): | 241 def _fill(self): |
242 """Get all contacts from backend | 242 """Get all contacts from backend |
243 | 243 |
244 Contacts will be cleared before refilling them | 244 Contacts will be cleared before refilling them |
245 """ | 245 """ |
246 self.clearContacts(keep_cache=True) | 246 self.clear_contacts(keep_cache=True) |
247 self.host.bridge.getContacts(self.profile, callback=self._gotContacts) | 247 self.host.bridge.contacts_get(self.profile, callback=self._got_contacts) |
248 | 248 |
249 def fill(self): | 249 def fill(self): |
250 handler.fill(self.profile) | 250 handler.fill(self.profile) |
251 | 251 |
252 def getCache( | 252 def getCache( |
283 # we won't get the avatar set in the resource | 283 # we won't get the avatar set in the resource |
284 try: | 284 try: |
285 cache = self._cache[entity.bare] | 285 cache = self._cache[entity.bare] |
286 except KeyError: | 286 except KeyError: |
287 if create_if_not_found: | 287 if create_if_not_found: |
288 self.setContact(entity) | 288 self.set_contact(entity) |
289 cache = self._cache[entity.bare] | 289 cache = self._cache[entity.bare] |
290 else: | 290 else: |
291 raise exceptions.NotFound | 291 raise exceptions.NotFound |
292 | 292 |
293 if name is None: | 293 if name is None: |
317 elif entity.resource: | 317 elif entity.resource: |
318 try: | 318 try: |
319 return cache[C.CONTACT_RESOURCES][entity.resource][name] | 319 return cache[C.CONTACT_RESOURCES][entity.resource][name] |
320 except KeyError as e: | 320 except KeyError as e: |
321 if bare_default is None: | 321 if bare_default is None: |
322 bare_default = not self.isRoom(entity.bare) | 322 bare_default = not self.is_room(entity.bare) |
323 if not bare_default: | 323 if not bare_default: |
324 if default is Exception: | 324 if default is Exception: |
325 raise e | 325 raise e |
326 else: | 326 else: |
327 return default | 327 return default |
332 if default is Exception: | 332 if default is Exception: |
333 raise e | 333 raise e |
334 else: | 334 else: |
335 return default | 335 return default |
336 | 336 |
337 def setCache(self, entity, name, value): | 337 def set_cache(self, entity, name, value): |
338 """Set or update value for one data in cache | 338 """Set or update value for one data in cache |
339 | 339 |
340 @param entity(JID): entity to update | 340 @param entity(JID): entity to update |
341 @param name(str): value to set or update | 341 @param name(str): value to set or update |
342 """ | 342 """ |
343 self.setContact(entity, attributes={name: value}) | 343 self.set_contact(entity, attributes={name: value}) |
344 | 344 |
345 def getFullJid(self, entity): | 345 def get_full_jid(self, entity): |
346 """Get full jid from a bare jid | 346 """Get full jid from a bare jid |
347 | 347 |
348 @param entity(jid.JID): must be a bare jid | 348 @param entity(jid.JID): must be a bare jid |
349 @return (jid.JID): bare jid + main resource | 349 @return (jid.JID): bare jid + main resource |
350 @raise ValueError: the entity is not bare | 350 @raise ValueError: the entity is not bare |
351 """ | 351 """ |
352 if entity.resource: | 352 if entity.resource: |
353 raise ValueError("getFullJid must be used with a bare jid") | 353 raise ValueError("get_full_jid must be used with a bare jid") |
354 main_resource = self.getCache(entity, C.CONTACT_MAIN_RESOURCE) | 354 main_resource = self.getCache(entity, C.CONTACT_MAIN_RESOURCE) |
355 return jid.JID("{}/{}".format(entity, main_resource)) | 355 return jid.JID("{}/{}".format(entity, main_resource)) |
356 | 356 |
357 def setGroupData(self, group, name, value): | 357 def set_group_data(self, group, name, value): |
358 """Register a data for a group | 358 """Register a data for a group |
359 | 359 |
360 @param group: a valid (existing) group name | 360 @param group: a valid (existing) group name |
361 @param name: name of the data (can't be "jids") | 361 @param name: name of the data (can't be "jids") |
362 @param value: value to set | 362 @param value: value to set |
363 """ | 363 """ |
364 assert name != "jids" | 364 assert name != "jids" |
365 self._groups[group][name] = value | 365 self._groups[group][name] = value |
366 | 366 |
367 def getGroupData(self, group, name=None): | 367 def get_group_data(self, group, name=None): |
368 """Return value associated to group data | 368 """Return value associated to group data |
369 | 369 |
370 @param group: a valid (existing) group name | 370 @param group: a valid (existing) group name |
371 @param name: name of the data or None to get the whole dict | 371 @param name: name of the data or None to get the whole dict |
372 @return: registered value | 372 @return: registered value |
373 """ | 373 """ |
374 if name is None: | 374 if name is None: |
375 return self._groups[group] | 375 return self._groups[group] |
376 return self._groups[group][name] | 376 return self._groups[group][name] |
377 | 377 |
378 def isInRoster(self, entity): | 378 def is_in_roster(self, entity): |
379 """Tell if an entity is in roster | 379 """Tell if an entity is in roster |
380 | 380 |
381 @param entity(jid.JID): jid of the entity | 381 @param entity(jid.JID): jid of the entity |
382 the bare jid will be used | 382 the bare jid will be used |
383 """ | 383 """ |
384 return entity.bare in self._roster | 384 return entity.bare in self._roster |
385 | 385 |
386 def isRoom(self, entity): | 386 def is_room(self, entity): |
387 """Helper method to know if entity is a MUC room | 387 """Helper method to know if entity is a MUC room |
388 | 388 |
389 @param entity(jid.JID): jid of the entity | 389 @param entity(jid.JID): jid of the entity |
390 hint: use bare jid here, as room can't be full jid with MUC | 390 hint: use bare jid here, as room can't be full jid with MUC |
391 @return (bool): True if entity is a room | 391 @return (bool): True if entity is a room |
392 """ | 392 """ |
393 assert entity.resource is None # FIXME: this may change when MIX will be handled | 393 assert entity.resource is None # FIXME: this may change when MIX will be handled |
394 return self.isSpecial(entity, C.CONTACT_SPECIAL_GROUP) | 394 return self.is_special(entity, C.CONTACT_SPECIAL_GROUP) |
395 | 395 |
396 def isSpecial(self, entity, special_type): | 396 def is_special(self, entity, special_type): |
397 """Tell if an entity is of a specialy _type | 397 """Tell if an entity is of a specialy _type |
398 | 398 |
399 @param entity(jid.JID): jid of the special entity | 399 @param entity(jid.JID): jid of the special entity |
400 if the jid is full, will be added to special extras | 400 if the jid is full, will be added to special extras |
401 @param special_type: one of special type (e.g. C.CONTACT_SPECIAL_GROUP) | 401 @param special_type: one of special type (e.g. C.CONTACT_SPECIAL_GROUP) |
402 @return (bool): True if entity is from this special type | 402 @return (bool): True if entity is from this special type |
403 """ | 403 """ |
404 return self.getCache(entity, C.CONTACT_SPECIAL, default=None) == special_type | 404 return self.getCache(entity, C.CONTACT_SPECIAL, default=None) == special_type |
405 | 405 |
406 def setSpecial(self, entity, special_type): | 406 def set_special(self, entity, special_type): |
407 """Set special flag on an entity | 407 """Set special flag on an entity |
408 | 408 |
409 @param entity(jid.JID): jid of the special entity | 409 @param entity(jid.JID): jid of the special entity |
410 if the jid is full, will be added to special extras | 410 if the jid is full, will be added to special extras |
411 @param special_type: one of special type (e.g. C.CONTACT_SPECIAL_GROUP) | 411 @param special_type: one of special type (e.g. C.CONTACT_SPECIAL_GROUP) |
412 or None to remove special flag | 412 or None to remove special flag |
413 """ | 413 """ |
414 assert special_type in C.CONTACT_SPECIAL_ALLOWED + (None,) | 414 assert special_type in C.CONTACT_SPECIAL_ALLOWED + (None,) |
415 self.setCache(entity, C.CONTACT_SPECIAL, special_type) | 415 self.set_cache(entity, C.CONTACT_SPECIAL, special_type) |
416 | 416 |
417 def getSpecials(self, special_type=None, bare=False): | 417 def get_specials(self, special_type=None, bare=False): |
418 """Return all the bare JIDs of the special roster entities of with given type. | 418 """Return all the bare JIDs of the special roster entities of with given type. |
419 | 419 |
420 @param special_type(unicode, None): if not None, filter by special type | 420 @param special_type(unicode, None): if not None, filter by special type |
421 (e.g. C.CONTACT_SPECIAL_GROUP) | 421 (e.g. C.CONTACT_SPECIAL_GROUP) |
422 @param bare(bool): return only bare jids if True | 422 @param bare(bool): return only bare jids if True |
432 continue | 432 continue |
433 yield entity | 433 yield entity |
434 | 434 |
435 def disconnect(self): | 435 def disconnect(self): |
436 # for now we just clear contacts on disconnect | 436 # for now we just clear contacts on disconnect |
437 self.clearContacts() | 437 self.clear_contacts() |
438 | 438 |
439 def clearContacts(self, keep_cache=False): | 439 def clear_contacts(self, keep_cache=False): |
440 """Clear all the contact list | 440 """Clear all the contact list |
441 | 441 |
442 @param keep_cache: if True, don't reset the cache | 442 @param keep_cache: if True, don't reset the cache |
443 """ | 443 """ |
444 self.select(None) | 444 self.select(None) |
447 self._groups.clear() | 447 self._groups.clear() |
448 self._specials.clear() | 448 self._specials.clear() |
449 self._roster.clear() | 449 self._roster.clear() |
450 self.update() | 450 self.update() |
451 | 451 |
452 def setContact(self, entity, groups=None, attributes=None, in_roster=False): | 452 def set_contact(self, entity, groups=None, attributes=None, in_roster=False): |
453 """Add a contact to the list if it doesn't exist, else update it. | 453 """Add a contact to the list if it doesn't exist, else update it. |
454 | 454 |
455 This method can be called with groups=None for the purpose of updating | 455 This method can be called with groups=None for the purpose of updating |
456 the contact's attributes (e.g. nicknames). In that case, the groups | 456 the contact's attributes (e.g. nicknames). In that case, the groups |
457 attribute must not be set to the default group but ignored. If not, | 457 attribute must not be set to the default group but ignored. If not, |
471 | 471 |
472 entity_bare = entity.bare | 472 entity_bare = entity.bare |
473 # we check if the entity is visible before changing anything | 473 # we check if the entity is visible before changing anything |
474 # this way we know if we need to do an UPDATE_ADD, UPDATE_MODIFY | 474 # this way we know if we need to do an UPDATE_ADD, UPDATE_MODIFY |
475 # or an UPDATE_DELETE | 475 # or an UPDATE_DELETE |
476 was_visible = self.entityVisible(entity_bare) | 476 was_visible = self.entity_visible(entity_bare) |
477 | 477 |
478 if in_roster: | 478 if in_roster: |
479 self._roster.add(entity_bare) | 479 self._roster.add(entity_bare) |
480 | 480 |
481 cache = self._cache.setdefault( | 481 cache = self._cache.setdefault( |
524 cache[C.CONTACT_RESOURCES].setdefault(entity.resource, {}) | 524 cache[C.CONTACT_RESOURCES].setdefault(entity.resource, {}) |
525 if entity.resource | 525 if entity.resource |
526 else cache | 526 else cache |
527 ) | 527 ) |
528 for attribute, value in attributes.items(): | 528 for attribute, value in attributes.items(): |
529 if attribute == "nicknames" and self.isSpecial( | 529 if attribute == "nicknames" and self.is_special( |
530 entity, C.CONTACT_SPECIAL_GROUP | 530 entity, C.CONTACT_SPECIAL_GROUP |
531 ): | 531 ): |
532 # we don't want to keep nicknames for MUC rooms | 532 # we don't want to keep nicknames for MUC rooms |
533 # FIXME: this is here as plugin XEP-0054 can link resource's nick | 533 # FIXME: this is here as plugin XEP-0054 can link resource's nick |
534 # with bare jid which in the case of MUC | 534 # with bare jid which in the case of MUC |
538 # may not be needed anymore… | 538 # may not be needed anymore… |
539 continue | 539 continue |
540 cache_attr[attribute] = value | 540 cache_attr[attribute] = value |
541 | 541 |
542 # we can update the display if needed | 542 # we can update the display if needed |
543 if self.entityVisible(entity_bare): | 543 if self.entity_visible(entity_bare): |
544 # if the contact was not visible, we need to add a widget | 544 # if the contact was not visible, we need to add a widget |
545 # else we just update id | 545 # else we just update id |
546 update_type = C.UPDATE_MODIFY if was_visible else C.UPDATE_ADD | 546 update_type = C.UPDATE_MODIFY if was_visible else C.UPDATE_ADD |
547 self.update([entity], update_type, self.profile) | 547 self.update([entity], update_type, self.profile) |
548 elif was_visible: | 548 elif was_visible: |
549 # the entity was visible and is not anymore, we remove it | 549 # the entity was visible and is not anymore, we remove it |
550 self.update([entity], C.UPDATE_DELETE, self.profile) | 550 self.update([entity], C.UPDATE_DELETE, self.profile) |
551 | 551 |
552 def entityVisible(self, entity, check_resource=False): | 552 def entity_visible(self, entity, check_resource=False): |
553 """Tell if the contact should be showed or hidden. | 553 """Tell if the contact should be showed or hidden. |
554 | 554 |
555 @param entity (jid.JID): jid of the contact | 555 @param entity (jid.JID): jid of the contact |
556 @param check_resource (bool): True if resource must be significant | 556 @param check_resource (bool): True if resource must be significant |
557 @return (bool): True if that contact should be showed in the list | 557 @return (bool): True if that contact should be showed in the list |
569 (show is not None and show != C.PRESENCE_UNAVAILABLE) | 569 (show is not None and show != C.PRESENCE_UNAVAILABLE) |
570 or self.show_disconnected | 570 or self.show_disconnected |
571 or entity in selected | 571 or entity in selected |
572 or ( | 572 or ( |
573 self.show_entities_with_notifs | 573 self.show_entities_with_notifs |
574 and next(self.host.getNotifs(entity.bare, profile=self.profile), None) | 574 and next(self.host.get_notifs(entity.bare, profile=self.profile), None) |
575 ) | 575 ) |
576 or entity.resource is None and self.isRoom(entity.bare) | 576 or entity.resource is None and self.is_room(entity.bare) |
577 ) | 577 ) |
578 | 578 |
579 def anyEntityVisible(self, entities, check_resources=False): | 579 def any_entity_visible(self, entities, check_resources=False): |
580 """Tell if in a list of entities, at least one should be shown | 580 """Tell if in a list of entities, at least one should be shown |
581 | 581 |
582 @param entities (list[jid.JID]): list of jids | 582 @param entities (list[jid.JID]): list of jids |
583 @param check_resources (bool): True if resources must be significant | 583 @param check_resources (bool): True if resources must be significant |
584 @return (bool): True if a least one entity need to be shown | 584 @return (bool): True if a least one entity need to be shown |
585 """ | 585 """ |
586 # FIXME: looks inefficient, really needed? | 586 # FIXME: looks inefficient, really needed? |
587 for entity in entities: | 587 for entity in entities: |
588 if self.entityVisible(entity, check_resources): | 588 if self.entity_visible(entity, check_resources): |
589 return True | 589 return True |
590 return False | 590 return False |
591 | 591 |
592 def isEntityInGroup(self, entity, group): | 592 def is_entity_in_group(self, entity, group): |
593 """Tell if an entity is in a roster group | 593 """Tell if an entity is in a roster group |
594 | 594 |
595 @param entity(jid.JID): jid of the entity | 595 @param entity(jid.JID): jid of the entity |
596 @param group(unicode): group to check | 596 @param group(unicode): group to check |
597 @return (bool): True if the entity is in the group | 597 @return (bool): True if the entity is in the group |
598 """ | 598 """ |
599 return entity in self.getGroupData(group, "jids") | 599 return entity in self.get_group_data(group, "jids") |
600 | 600 |
601 def removeContact(self, entity): | 601 def remove_contact(self, entity): |
602 """remove a contact from the list | 602 """remove a contact from the list |
603 | 603 |
604 @param entity(jid.JID): jid of the entity to remove (bare jid is used) | 604 @param entity(jid.JID): jid of the entity to remove (bare jid is used) |
605 """ | 605 """ |
606 entity_bare = entity.bare | 606 entity_bare = entity.bare |
607 was_visible = self.entityVisible(entity_bare) | 607 was_visible = self.entity_visible(entity_bare) |
608 try: | 608 try: |
609 groups = self._cache[entity_bare].get(C.CONTACT_GROUPS, set()) | 609 groups = self._cache[entity_bare].get(C.CONTACT_GROUPS, set()) |
610 except KeyError: | 610 except KeyError: |
611 log.error(_("Trying to delete an unknow entity [{}]").format(entity)) | 611 log.error(_("Trying to delete an unknow entity [{}]").format(entity)) |
612 try: | 612 try: |
627 to_remove.add(set_entity) | 627 to_remove.add(set_entity) |
628 iterable.difference_update(to_remove) | 628 iterable.difference_update(to_remove) |
629 if was_visible: | 629 if was_visible: |
630 self.update([entity], C.UPDATE_DELETE, self.profile) | 630 self.update([entity], C.UPDATE_DELETE, self.profile) |
631 | 631 |
632 def onPresenceUpdate(self, entity, show, priority, statuses, profile): | 632 def on_presence_update(self, entity, show, priority, statuses, profile): |
633 """Update entity's presence status | 633 """Update entity's presence status |
634 | 634 |
635 @param entity(jid.JID): entity updated | 635 @param entity(jid.JID): entity updated |
636 @param show: availability | 636 @param show: availability |
637 @parap priority: resource's priority | 637 @parap priority: resource's priority |
638 @param statuses: dict of statuses | 638 @param statuses: dict of statuses |
639 @param profile: %(doc_profile)s | 639 @param profile: %(doc_profile)s |
640 """ | 640 """ |
641 # FIXME: cache modification should be done with setContact | 641 # FIXME: cache modification should be done with set_contact |
642 # the resources/presence handling logic should be moved there | 642 # the resources/presence handling logic should be moved there |
643 was_visible = self.entityVisible(entity.bare) | 643 was_visible = self.entity_visible(entity.bare) |
644 cache = self.getCache(entity, create_if_not_found=True) | 644 cache = self.getCache(entity, create_if_not_found=True) |
645 if show == C.PRESENCE_UNAVAILABLE: | 645 if show == C.PRESENCE_UNAVAILABLE: |
646 if not entity.resource: | 646 if not entity.resource: |
647 cache[C.CONTACT_RESOURCES].clear() | 647 cache[C.CONTACT_RESOURCES].clear() |
648 cache[C.CONTACT_MAIN_RESOURCE] = None | 648 cache[C.CONTACT_MAIN_RESOURCE] = None |
678 key=lambda res: resources_data[res].get( | 678 key=lambda res: resources_data[res].get( |
679 C.PRESENCE_PRIORITY, -2 ** 32 | 679 C.PRESENCE_PRIORITY, -2 ** 32 |
680 ), | 680 ), |
681 ) | 681 ) |
682 cache[C.CONTACT_MAIN_RESOURCE] = priority_resource | 682 cache[C.CONTACT_MAIN_RESOURCE] = priority_resource |
683 if self.entityVisible(entity.bare): | 683 if self.entity_visible(entity.bare): |
684 update_type = C.UPDATE_MODIFY if was_visible else C.UPDATE_ADD | 684 update_type = C.UPDATE_MODIFY if was_visible else C.UPDATE_ADD |
685 self.update([entity], update_type, self.profile) | 685 self.update([entity], update_type, self.profile) |
686 elif was_visible: | 686 elif was_visible: |
687 self.update([entity], C.UPDATE_DELETE, self.profile) | 687 self.update([entity], C.UPDATE_DELETE, self.profile) |
688 | 688 |
689 def onNicknamesUpdate(self, entity, nicknames, profile): | 689 def on_nicknames_update(self, entity, nicknames, profile): |
690 """Update entity's nicknames | 690 """Update entity's nicknames |
691 | 691 |
692 @param entity(jid.JID): entity updated | 692 @param entity(jid.JID): entity updated |
693 @param nicknames(list[unicode]): nicknames of the entity | 693 @param nicknames(list[unicode]): nicknames of the entity |
694 @param profile: %(doc_profile)s | 694 @param profile: %(doc_profile)s |
695 """ | 695 """ |
696 assert profile == self.profile | 696 assert profile == self.profile |
697 self.setCache(entity, "nicknames", nicknames) | 697 self.set_cache(entity, "nicknames", nicknames) |
698 | 698 |
699 def onNotification(self, entity, notif, profile): | 699 def on_notification(self, entity, notif, profile): |
700 """Update entity with notification | 700 """Update entity with notification |
701 | 701 |
702 @param entity(jid.JID): entity updated | 702 @param entity(jid.JID): entity updated |
703 @param notif(dict): notification data | 703 @param notif(dict): notification data |
704 @param profile: %(doc_profile)s | 704 @param profile: %(doc_profile)s |
705 """ | 705 """ |
706 assert profile == self.profile | 706 assert profile == self.profile |
707 if entity is not None and self.entityVisible(entity): | 707 if entity is not None and self.entity_visible(entity): |
708 self.update([entity], C.UPDATE_MODIFY, profile) | 708 self.update([entity], C.UPDATE_MODIFY, profile) |
709 | 709 |
710 def unselect(self, entity): | 710 def unselect(self, entity): |
711 """Unselect an entity | 711 """Unselect an entity |
712 | 712 |
745 else: | 745 else: |
746 cache[C.CONTACT_SELECTED].add(entity.resource) | 746 cache[C.CONTACT_SELECTED].add(entity.resource) |
747 self._selected.add(entity) | 747 self._selected.add(entity) |
748 self.update([entity], C.UPDATE_SELECTION, profile=self.profile) | 748 self.update([entity], C.UPDATE_SELECTION, profile=self.profile) |
749 | 749 |
750 def showOfflineContacts(self, show): | 750 def show_offline_contacts(self, show): |
751 """Tell if offline contacts should be shown | 751 """Tell if offline contacts should be shown |
752 | 752 |
753 @param show(bool): True if offline contacts should be shown | 753 @param show(bool): True if offline contacts should be shown |
754 """ | 754 """ |
755 assert isinstance(show, bool) | 755 assert isinstance(show, bool) |
756 if self.show_disconnected == show: | 756 if self.show_disconnected == show: |
757 return | 757 return |
758 self.show_disconnected = show | 758 self.show_disconnected = show |
759 self.update(type_=C.UPDATE_STRUCTURE, profile=self.profile) | 759 self.update(type_=C.UPDATE_STRUCTURE, profile=self.profile) |
760 | 760 |
761 def showEmptyGroups(self, show): | 761 def show_empty_groups(self, show): |
762 assert isinstance(show, bool) | 762 assert isinstance(show, bool) |
763 if self.show_empty_groups == show: | 763 if self._show_empty_groups == show: |
764 return | 764 return |
765 self.show_empty_groups = show | 765 self._show_empty_groups = show |
766 self.update(type_=C.UPDATE_STRUCTURE, profile=self.profile) | 766 self.update(type_=C.UPDATE_STRUCTURE, profile=self.profile) |
767 | 767 |
768 def showResources(self, show): | 768 def show_resources(self, show): |
769 assert isinstance(show, bool) | 769 assert isinstance(show, bool) |
770 if self.show_resources == show: | 770 if self.show_resources == show: |
771 return | 771 return |
772 self.show_resources = show | 772 self.show_resources = show |
773 self.update(type_=C.UPDATE_STRUCTURE, profile=self.profile) | 773 self.update(type_=C.UPDATE_STRUCTURE, profile=self.profile) |
774 | 774 |
775 def plug(self): | 775 def plug(self): |
776 handler.addProfile(self.profile) | 776 handler.add_profile(self.profile) |
777 | 777 |
778 def unplug(self): | 778 def unplug(self): |
779 handler.removeProfile(self.profile) | 779 handler.remove_profile(self.profile) |
780 | 780 |
781 def update(self, entities=None, type_=None, profile=None): | 781 def update(self, entities=None, type_=None, profile=None): |
782 handler.update(entities, type_, profile) | 782 handler.update(entities, type_, profile) |
783 | 783 |
784 | 784 |
928 | 928 |
929 This method should only be used in QuickContactList | 929 This method should only be used in QuickContactList |
930 """ | 930 """ |
931 self._widgets.remove(widget) | 931 self._widgets.remove(widget) |
932 | 932 |
933 def addProfiles(self, profiles): | 933 def add_profiles(self, profiles): |
934 """Add a contact list for plugged profiles | 934 """Add a contact list for plugged profiles |
935 | 935 |
936 @param profile(iterable[unicode]): plugged profiles | 936 @param profile(iterable[unicode]): plugged profiles |
937 """ | 937 """ |
938 for profile in profiles: | 938 for profile in profiles: |
939 if profile not in self._clist: | 939 if profile not in self._clist: |
940 self._clist[profile] = ProfileContactList(profile) | 940 self._clist[profile] = ProfileContactList(profile) |
941 return [self._clist[profile] for profile in profiles] | 941 return [self._clist[profile] for profile in profiles] |
942 | 942 |
943 def addProfile(self, profile): | 943 def add_profile(self, profile): |
944 return self.addProfiles([profile])[0] | 944 return self.add_profiles([profile])[0] |
945 | 945 |
946 def removeProfiles(self, profiles): | 946 def remove_profiles(self, profiles): |
947 """Remove given unplugged profiles from contact list | 947 """Remove given unplugged profiles from contact list |
948 | 948 |
949 @param profile(iterable[unicode]): unplugged profiles | 949 @param profile(iterable[unicode]): unplugged profiles |
950 """ | 950 """ |
951 for profile in profiles: | 951 for profile in profiles: |
952 del self._clist[profile] | 952 del self._clist[profile] |
953 | 953 |
954 def removeProfile(self, profile): | 954 def remove_profile(self, profile): |
955 self.removeProfiles([profile]) | 955 self.remove_profiles([profile]) |
956 | 956 |
957 def getSpecialExtras(self, special_type=None): | 957 def get_special_extras(self, special_type=None): |
958 """Return special extras with given type | 958 """Return special extras with given type |
959 | 959 |
960 If special_type is None, return all special extras. | 960 If special_type is None, return all special extras. |
961 | 961 |
962 @param special_type(unicode, None): one of special type | 962 @param special_type(unicode, None): one of special type |
964 None to return all special extras. | 964 None to return all special extras. |
965 @return (set[jid.JID]) | 965 @return (set[jid.JID]) |
966 """ | 966 """ |
967 entities = set() | 967 entities = set() |
968 for contact_list in self._clist.values(): | 968 for contact_list in self._clist.values(): |
969 entities.update(contact_list.getSpecialExtras(special_type)) | 969 entities.update(contact_list.get_special_extras(special_type)) |
970 return entities | 970 return entities |
971 | 971 |
972 def _contactsFilled(self, profile): | 972 def _contacts_filled(self, profile): |
973 self._to_fill.remove(profile) | 973 self._to_fill.remove(profile) |
974 if not self._to_fill: | 974 if not self._to_fill: |
975 del self._to_fill | 975 del self._to_fill |
976 # we need a full update when all contacts are filled | 976 # we need a full update when all contacts are filled |
977 self.update() | 977 self.update() |
978 self.host.callListeners("contactsFilled", profile=profile) | 978 self.host.call_listeners("contactsFilled", profile=profile) |
979 | 979 |
980 def fill(self, profile=None): | 980 def fill(self, profile=None): |
981 """Get all contacts from backend, and fill the widget | 981 """Get all contacts from backend, and fill the widget |
982 | 982 |
983 Contacts will be cleared before refilling them | 983 Contacts will be cleared before refilling them |
1007 ) | 1007 ) |
1008 ) | 1008 ) |
1009 for profile in remaining: | 1009 for profile in remaining: |
1010 self._clist[profile]._fill() | 1010 self._clist[profile]._fill() |
1011 | 1011 |
1012 def clearContacts(self, keep_cache=False): | 1012 def clear_contacts(self, keep_cache=False): |
1013 """Clear all the contact list | 1013 """Clear all the contact list |
1014 | 1014 |
1015 @param keep_cache: if True, don't reset the cache | 1015 @param keep_cache: if True, don't reset the cache |
1016 """ | 1016 """ |
1017 for contact_list in self._clist.values(): | 1017 for contact_list in self._clist.values(): |
1018 contact_list.clearContacts(keep_cache) | 1018 contact_list.clear_contacts(keep_cache) |
1019 # we need a full update | 1019 # we need a full update |
1020 self.update() | 1020 self.update() |
1021 | 1021 |
1022 def select(self, entity): | 1022 def select(self, entity): |
1023 for contact_list in self._clist.values(): | 1023 for contact_list in self._clist.values(): |
1025 | 1025 |
1026 def unselect(self, entity): | 1026 def unselect(self, entity): |
1027 for contact_list in self._clist.values(): | 1027 for contact_list in self._clist.values(): |
1028 contact_list.select(entity) | 1028 contact_list.select(entity) |
1029 | 1029 |
1030 def lockUpdate(self, locked=True, do_update=True): | 1030 def lock_update(self, locked=True, do_update=True): |
1031 """Forbid contact list updates | 1031 """Forbid contact list updates |
1032 | 1032 |
1033 Used mainly while profiles are plugged, as many updates can occurs, causing | 1033 Used mainly while profiles are plugged, as many updates can occurs, causing |
1034 an impact on performances | 1034 an impact on performances |
1035 @param locked(bool): updates are forbidden if True | 1035 @param locked(bool): updates are forbidden if True |
1065 | 1065 |
1066 # options | 1066 # options |
1067 # for next values, None means use indivual value per profile | 1067 # for next values, None means use indivual value per profile |
1068 # True or False mean override these values for all profiles | 1068 # True or False mean override these values for all profiles |
1069 self.show_disconnected = None # TODO | 1069 self.show_disconnected = None # TODO |
1070 self.show_empty_groups = None # TODO | 1070 self._show_empty_groups = None # TODO |
1071 self.show_resources = None # TODO | 1071 self.show_resources = None # TODO |
1072 self.show_status = None # TODO | 1072 self.show_status = None # TODO |
1073 | 1073 |
1074 def postInit(self): | 1074 def post_init(self): |
1075 """Method to be called by frontend after widget is initialised""" | 1075 """Method to be called by frontend after widget is initialised""" |
1076 handler.register(self) | 1076 handler.register(self) |
1077 | 1077 |
1078 @property | 1078 @property |
1079 def all_iter(self): | 1079 def all_iter(self): |
1106 @param profile(unicode, None): profile concerned with the update | 1106 @param profile(unicode, None): profile concerned with the update |
1107 None if all profiles need to be updated | 1107 None if all profiles need to be updated |
1108 """ | 1108 """ |
1109 raise NotImplementedError | 1109 raise NotImplementedError |
1110 | 1110 |
1111 def onDelete(self): | 1111 def on_delete(self): |
1112 QuickWidget.onDelete(self) | 1112 QuickWidget.on_delete(self) |
1113 handler.unregister(self) | 1113 handler.unregister(self) |