Add XEP-0398 optimizations

- If the server implements XEP-0398 we dont need to add the avatar sha
anymore, the server adds it for us.
- It also means we dont have to query our own avatar from vcard at start
because the server tells us the avatar sha that is published with the inital
presence reflection
This commit is contained in:
Philipp Hörist 2018-09-01 20:34:56 +02:00 committed by Philipp Hörist
parent d4d29f8309
commit 3e73ee93e1
8 changed files with 77 additions and 32 deletions

View File

@ -114,6 +114,7 @@ class CommonConnection:
self.roster_supported = True
self.addressing_supported = False
self.avatar_conversion = False
self.muc_jid = {} # jid of muc server for each transport type
self._stun_servers = [] # STUN servers of our jabber server
@ -1398,8 +1399,9 @@ class Connection(CommonConnection, ConnectionHandlers):
app.nec.push_incoming_event(OurShowEvent(None, conn=self,
show='invisible'))
if initial:
# ask our VCard
self.get_module('VCardTemp').request_vcard()
if not self.avatar_conversion:
# ask our VCard
self.get_module('VCardTemp').request_vcard()
# Get bookmarks
self.get_module('Bookmarks').get_bookmarks()

View File

@ -580,8 +580,9 @@ class ConnectionHandlers(ConnectionSocks5Bytestream,
app.nec.push_incoming_event(OurShowEvent(None, conn=self,
show=show))
# ask our VCard
self.get_module('VCardTemp').request_vcard()
if not self.avatar_conversion:
# ask our VCard
self.get_module('VCardTemp').request_vcard()
# Get bookmarks
self.get_module('Bookmarks').get_bookmarks()

View File

@ -178,6 +178,10 @@ class Discovery:
self._con.get_module('PEP').pass_disco(from_, *args)
self._con.get_module('PubSub').pass_disco(from_, *args)
identities, features, data, node = args
if 'urn:xmpp:pep-vcard-conversion:0' in features:
self._con.avatar_conversion = True
def discover_server_info(self):
# Calling this method starts the connect_maschine()
server = self._con.get_own_jid().getDomain()

View File

@ -183,7 +183,10 @@ class Presence:
idle_node = presence.setTag('idle', namespace=nbxmpp.NS_IDLE)
idle_node.setAttr('since', idle_time)
self._con.get_module('VCardAvatars').add_update_node(presence)
if not self._con.avatar_conversion:
# XEP-0398 not supported by server so
# we add the avatar sha to our presence
self._con.get_module('VCardAvatars').add_update_node(presence)
if caps:
attrs = {'hash': 'sha-1',

View File

@ -107,8 +107,8 @@ class UserAvatar(AbstractPEPModule):
else:
own_jid = self._con.get_own_jid().getStripped()
app.logger.set_avatar_sha(own_jid, jid, sha)
app.contacts.set_avatar(self._account, jid, sha)
app.contacts.set_avatar(self._account, jid, sha)
app.interface.update_avatar(self._account, jid)
def _extract_info(self, item):

View File

@ -16,6 +16,7 @@
import os
import logging
from pathlib import Path
import nbxmpp
@ -38,6 +39,16 @@ class VCardAvatars:
]
self.avatar_advertised = False
self._find_own_avatar()
def _find_own_avatar(self):
sha = app.config.get_per('accounts', self._account, 'avatar_sha')
if not sha:
return
path = Path(configpaths.get('AVATAR')) / sha
if not path.exists():
log.info('Missing own avatar, reset sha')
app.config.set_per('accounts', self._account, 'avatar_sha', '')
def _presence_received(self, con, stanza):
update = stanza.getTag('x', namespace=nbxmpp.NS_VCARD_UPDATE)
@ -54,9 +65,14 @@ class VCardAvatars:
if self._con.get_own_jid().bareMatch(jid):
if self._con.get_own_jid() == jid:
# Reflection of our own presence
return
self._self_update_received(jid, avatar_sha)
# Initial presence reflection
if self._con.avatar_conversion:
# XEP-0398: Tells us the current avatar sha on the
# inital presence reflection
self._self_update_received(jid, avatar_sha)
else:
# Presence from another resource of ours
self._self_update_received(jid, avatar_sha)
return
# Check if presence is from a MUC service
@ -76,6 +92,9 @@ class VCardAvatars:
if avatar_sha == '':
# Empty <photo/> tag, means no avatar is advertised
log.info('%s has no avatar published', full_jid)
app.config.set_per('accounts', self._account, 'avatar_sha', '')
app.contacts.set_avatar(self._account, jid, None)
app.interface.update_avatar(self._account, jid)
return
log.info('Update: %s %s', jid, avatar_sha)
@ -83,8 +102,16 @@ class VCardAvatars:
'accounts', self._account, 'avatar_sha')
if avatar_sha != current_sha:
log.info('Request : %s', jid)
self._con.get_module('VCardTemp').request_vcard(RequestAvatar.SELF)
path = Path(configpaths.get('AVATAR')) / avatar_sha
if path.exists():
app.config.set_per(
'accounts', self._account, 'avatar_sha', avatar_sha)
app.contacts.set_avatar(self._account, jid, avatar_sha)
app.interface.update_avatar(self._account, jid)
else:
log.info('Request : %s', jid)
self._con.get_module('VCardTemp').request_vcard(
RequestAvatar.SELF)
else:
log.info('Avatar already known: %s %s',
jid, avatar_sha)
@ -168,10 +195,17 @@ class VCardAvatars:
else:
log.info('Avatar already known: %s', nick)
def send_avatar_presence(self, force=False):
if self.avatar_advertised and not force:
log.debug('Avatar already advertised')
return
def send_avatar_presence(self, force=False, after_publish=False):
if self._con.avatar_conversion:
if not after_publish:
# XEP-0398: We only resend presence after we publish a
# new avatar
return
else:
if self.avatar_advertised and not force:
log.debug('Avatar already advertised')
return
show = helpers.get_xmpp_show(app.SHOW_LIST[self._con.connected])
self._con.get_module('Presence').send_presence(
@ -180,8 +214,6 @@ class VCardAvatars:
status=self._con.status)
self.avatar_advertised = True
app.interface.update_avatar(self._account,
self._con.get_own_jid().getStripped())
def add_update_node(self, node):
update = node.setTag('x', namespace=nbxmpp.NS_VCARD_UPDATE)

View File

@ -14,7 +14,6 @@
# XEP-0054: vcard-temp
import os
import hashlib
import binascii
import base64
@ -23,7 +22,6 @@ import logging
import nbxmpp
from gajim.common import app
from gajim.common import configpaths
from gajim.common.const import RequestAvatar
from gajim.common.nec import NetworkIncomingEvent
from gajim.common.connection_handlers_events import InformationEvent
@ -156,8 +154,10 @@ class VCardTemp:
'accounts', self._account, 'avatar_sha', sha or '')
own_jid = self._con.get_own_jid().getStripped()
app.contacts.set_avatar(self._account, own_jid, sha)
app.interface.update_avatar(
self._account, self._con.get_own_jid().getStripped())
self._con.get_module('VCardAvatars').send_avatar_presence(
force=True)
after_publish=True)
log.info('%s: Published: %s', self._account, sha)
app.nec.push_incoming_event(
VcardPublishedEvent(None, conn=self._con))
@ -231,28 +231,28 @@ class VCardTemp:
self._own_vcard = vcard
self.own_vcard_received = True
if avatar_sha is None:
# No avatar found in vcard
log.info('No avatar found')
app.config.set_per('accounts', self._account, 'avatar_sha', '')
app.contacts.set_avatar(self._account, jid, avatar_sha)
self._con.get_module('VCardAvatars').send_avatar_presence(force=True)
return
current_sha = app.config.get_per('accounts', self._account, 'avatar_sha')
# Avatar found in vcard
current_sha = app.config.get_per(
'accounts', self._account, 'avatar_sha')
if current_sha == avatar_sha:
path = os.path.join(configpaths.get('AVATAR'), current_sha)
if not os.path.isfile(path):
log.info('Caching: %s', current_sha)
app.interface.save_avatar(photo_decoded)
self._con.get_module('VCardAvatars').send_avatar_presence()
else:
app.interface.save_avatar(photo_decoded)
app.contacts.set_avatar(self._account, jid, avatar_sha)
app.config.set_per(
'accounts', self._account, 'avatar_sha', avatar_sha)
self._con.get_module('VCardAvatars').send_avatar_presence(force=True)
app.config.set_per('accounts', self._account, 'avatar_sha', avatar_sha)
if app.is_invisible(self._account):
log.info('We are invisible, not advertising avatar')
return
self._con.get_module('VCardAvatars').send_avatar_presence(force=True)
app.interface.update_avatar(self._account, jid)
def _on_room_avatar_received(self, jid, resource, room, vcard,
expected_sha):

View File

@ -177,7 +177,10 @@ class ServerInfoDialog(Gtk.Dialog):
mam_enabled),
Feature('XEP-0363: HTTP File Upload',
con.get_module('HTTPUpload').available,
con.get_module('HTTPUpload').httpupload_namespace, None)]
con.get_module('HTTPUpload').httpupload_namespace, None),
Feature('XEP-0398: Avatar Conversion',
con.avatar_conversion, '', None)
]
def add_info(self, info):
self.info_listbox.add(ServerInfoItem(info))