Display contact avatar in the roster.
Implements XEP-0084 and XEP-0153.
This commit is contained in:
parent
232ef11630
commit
554ff650bf
8 changed files with 68 additions and 7 deletions
|
@ -425,6 +425,9 @@ use_bookmarks_method =
|
|||
# Ask for message delivery receipts (XEP-0184)
|
||||
#request_message_receipts = true
|
||||
|
||||
# Display your contacts’ avatar in the roster if true.
|
||||
#enable_avatars = true
|
||||
|
||||
# Extract base64 images received in XHTML-IM messages
|
||||
# if true.
|
||||
#extract_inline_images = true
|
||||
|
|
|
@ -23,7 +23,7 @@ Table of all XEPs implemented in poezio.
|
|||
+----------+-------------------------+---------------------+
|
||||
|0050 |Ad-Hoc Commands |70% |
|
||||
+----------+-------------------------+---------------------+
|
||||
|0054 |vcard-temp |30% |
|
||||
|0054 |vcard-temp |70% |
|
||||
+----------+-------------------------+---------------------+
|
||||
|0060 |Publish-Subscribe |10% |
|
||||
+----------+-------------------------+---------------------+
|
||||
|
@ -33,6 +33,8 @@ Table of all XEPs implemented in poezio.
|
|||
+----------+-------------------------+---------------------+
|
||||
|0077 |In-Band Registration |50% |
|
||||
+----------+-------------------------+---------------------+
|
||||
|0084 |User Avatar |50% |
|
||||
+----------+-------------------------+---------------------+
|
||||
|0085 |Chat State Notifications |100% |
|
||||
+----------+-------------------------+---------------------+
|
||||
|0092 |Software Version |100% |
|
||||
|
@ -45,6 +47,8 @@ Table of all XEPs implemented in poezio.
|
|||
+----------+-------------------------+---------------------+
|
||||
|0118 |User Tune |90% |
|
||||
+----------+-------------------------+---------------------+
|
||||
|0153 |vCard-Based Avatars |50% |
|
||||
+----------+-------------------------+---------------------+
|
||||
|0163 |Personal Eventing |100% |
|
||||
| |Protocol | |
|
||||
+----------+-------------------------+---------------------+
|
||||
|
|
|
@ -50,6 +50,7 @@ DEFAULT_CONFIG = {
|
|||
'display_mood_notifications': False,
|
||||
'display_tune_notifications': False,
|
||||
'display_user_color_in_join_part': True,
|
||||
'enable_avatars': True,
|
||||
'enable_carbons': True,
|
||||
'enable_user_activity': True,
|
||||
'enable_user_gaming': True,
|
||||
|
|
|
@ -106,8 +106,10 @@ class Connection(slixmpp.ClientXMPP):
|
|||
self.register_plugin('xep_0071')
|
||||
self.register_plugin('xep_0077')
|
||||
self.plugin['xep_0077'].create_account = False
|
||||
self.register_plugin('xep_0084')
|
||||
self.register_plugin('xep_0085')
|
||||
self.register_plugin('xep_0115')
|
||||
self.register_plugin('xep_0153')
|
||||
|
||||
# monkey-patch xep_0184 to avoid requesting receipts for messages
|
||||
# without a body
|
||||
|
|
|
@ -65,6 +65,7 @@ class Contact(object):
|
|||
self.__item = item
|
||||
self.folded_states = defaultdict(lambda: True)
|
||||
self._name = ''
|
||||
self.avatar = None
|
||||
self.error = None
|
||||
self.tune = {}
|
||||
self.gaming = {}
|
||||
|
|
|
@ -261,6 +261,11 @@ class Core(object):
|
|||
connection.MatchAll(None),
|
||||
self.handler.incoming_stanza)
|
||||
self.xmpp.register_handler(all_stanzas)
|
||||
if config.get('enable_avatars'):
|
||||
self.xmpp.add_event_handler("vcard_avatar_update",
|
||||
self.handler.on_vcard_avatar)
|
||||
self.xmpp.add_event_handler("avatar_metadata_publish",
|
||||
self.handler.on_0084_avatar)
|
||||
if config.get('enable_user_tune'):
|
||||
self.xmpp.add_event_handler("user_tune_publish",
|
||||
self.handler.on_tune_event)
|
||||
|
|
|
@ -355,6 +355,43 @@ class HandlerCore:
|
|||
else:
|
||||
self.core.refresh_window()
|
||||
|
||||
@asyncio.coroutine
|
||||
def on_0084_avatar(self, msg):
|
||||
jid = msg['from'].bare
|
||||
contact = roster[jid]
|
||||
if not contact:
|
||||
return
|
||||
log.debug('Received 0084 avatar update from %s', jid)
|
||||
try:
|
||||
metadata = msg['pubsub_event']['items']['item']['avatar_metadata']['items']
|
||||
except Exception:
|
||||
return
|
||||
for info in metadata:
|
||||
if not info['url']:
|
||||
try:
|
||||
result = yield from self.core.xmpp['xep_0084'].retrieve_avatar(jid,
|
||||
info['id'],
|
||||
timeout=10)
|
||||
contact.avatar = result['pubsub']['items']['item']['avatar_data']['value']
|
||||
except Exception:
|
||||
log.exception('Failed retrieving 0084 data from %s:', jid)
|
||||
return
|
||||
log.debug('Received %s avatar: %s', jid, info['type'])
|
||||
|
||||
@asyncio.coroutine
|
||||
def on_vcard_avatar(self, pres):
|
||||
jid = pres['from'].bare
|
||||
log.debug('Received vCard avatar update from %s', jid)
|
||||
try:
|
||||
result = yield from self.core.xmpp['xep_0054'].get_vcard(jid,
|
||||
cached=True,
|
||||
timeout=10)
|
||||
contact.avatar = result['vcard_temp']['PHOTO']
|
||||
except Exception:
|
||||
log.exception('Failed retrieving vCard from %s:', jid)
|
||||
return
|
||||
log.debug('Received %s avatar: %s', jid, avatar['TYPE'])
|
||||
|
||||
def on_nick_received(self, message):
|
||||
"""
|
||||
Called when a pep notification for an user nickname
|
||||
|
|
|
@ -44,6 +44,7 @@ class RosterInfoTab(Tab):
|
|||
self.core.information_buffer.add_window(self.information_win)
|
||||
self.roster_win = windows.RosterWin()
|
||||
self.contact_info_win = windows.ContactInfoWin()
|
||||
self.avatar_win = windows.ImageWin()
|
||||
self.default_help_message = windows.HelpText("Enter commands with “/”. “o”: toggle offline show")
|
||||
self.input = self.default_help_message
|
||||
self.state = 'normal'
|
||||
|
@ -513,11 +514,14 @@ class RosterInfoTab(Tab):
|
|||
info_width, 0, roster_width + 1,
|
||||
self.core.information_buffer)
|
||||
if display_contact_win:
|
||||
y = self.height - tab_win_height - contact_win_h - 1
|
||||
avatar_width = contact_win_h * 2
|
||||
self.contact_info_win.resize(contact_win_h,
|
||||
info_width,
|
||||
self.height - tab_win_height
|
||||
- contact_win_h - 1,
|
||||
roster_width + 1)
|
||||
info_width - avatar_width,
|
||||
y, roster_width + 1)
|
||||
self.avatar_win.resize(contact_win_h,
|
||||
avatar_width,
|
||||
y, self.width - avatar_width)
|
||||
self.roster_win.resize(self.height - 1 - Tab.tab_win_height(),
|
||||
roster_width, 0, 0)
|
||||
self.input.resize(1, self.width, self.height-1, 0)
|
||||
|
@ -989,8 +993,12 @@ class RosterInfoTab(Tab):
|
|||
self.v_separator.refresh()
|
||||
self.information_win.refresh()
|
||||
if display_contact_win:
|
||||
self.contact_info_win.refresh(
|
||||
self.roster_win.get_selected_row())
|
||||
row = self.roster_win.get_selected_row()
|
||||
self.contact_info_win.refresh(row)
|
||||
if isinstance(row, Contact):
|
||||
self.avatar_win.refresh(row.avatar)
|
||||
else:
|
||||
self.avatar_win.refresh(None)
|
||||
self.refresh_tab_win()
|
||||
self.input.refresh()
|
||||
|
||||
|
|
Loading…
Reference in a new issue