From 8828a5b99dcf9134b200efe1bc4a60e2f0d350bb Mon Sep 17 00:00:00 2001 From: mathieui Date: Mon, 19 Apr 2021 23:17:10 +0200 Subject: [PATCH 1/3] XEP-0115: add a broadcast parameter to update_caps and do not send a presence after updating if it is false --- slixmpp/plugins/xep_0115/caps.py | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/slixmpp/plugins/xep_0115/caps.py b/slixmpp/plugins/xep_0115/caps.py index e469f6ff..c52d1166 100644 --- a/slixmpp/plugins/xep_0115/caps.py +++ b/slixmpp/plugins/xep_0115/caps.py @@ -8,6 +8,7 @@ import hashlib import base64 from asyncio import Future +from typing import Optional from slixmpp import __version__ from slixmpp.stanza import StreamFeatures, Presence, Iq @@ -15,10 +16,10 @@ from slixmpp.xmlstream import register_stanza_plugin, JID from slixmpp.xmlstream.handler import Callback from slixmpp.xmlstream.matcher import StanzaPath from slixmpp.util import MemoryCache -from slixmpp import asyncio -from slixmpp.exceptions import XMPPError, IqError, IqTimeout +from slixmpp.exceptions import XMPPError from slixmpp.plugins import BasePlugin from slixmpp.plugins.xep_0115 import stanza, StaticCaps +from slixmpp.types import OptJidStr log = logging.getLogger(__name__) @@ -285,7 +286,17 @@ class XEP_0115(BasePlugin): binary = hash(S.encode('utf8')).digest() return base64.b64encode(binary).decode('utf-8') - async def update_caps(self, jid=None, node=None, preserve=False): + async def update_caps(self, jid: OptJidStr = None, + node: Optional[str] = None, + preserve: bool = False, + broadcast: bool = True): + """Update caps for a local JID based on current data. + + :param jid: JID whose info to update + :param node: Node to fetch info from + :param broadcast: Send a presence after updating. + :param preserve: Send presence only to contacts found in the roster. + """ try: info = await self.xmpp['xep_0030'].get_info(jid, node, local=True) if isinstance(info, Iq): @@ -299,7 +310,7 @@ class XEP_0115(BasePlugin): await self.cache_caps(ver, info) await self.assign_verstring(jid, ver) - if self.xmpp.sessionstarted and self.broadcast: + if broadcast and self.xmpp.sessionstarted and self.broadcast: if self.xmpp.is_component or preserve: for contact in self.xmpp.roster[jid]: self.xmpp.roster[jid][contact].send_last_presence() From 7bb94afdc856a4f534fe1657620e2646d8da5238 Mon Sep 17 00:00:00 2001 From: mathieui Date: Mon, 19 Apr 2021 23:19:40 +0200 Subject: [PATCH 2/3] XEP-0163: do not broadcast caps when adding/removing interest --- slixmpp/plugins/xep_0163.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/slixmpp/plugins/xep_0163.py b/slixmpp/plugins/xep_0163.py index b885eec8..d8ab8c8e 100644 --- a/slixmpp/plugins/xep_0163.py +++ b/slixmpp/plugins/xep_0163.py @@ -61,7 +61,7 @@ class XEP_0163(BasePlugin): self.xmpp['xep_0030'].add_feature('%s+notify' % ns, jid=jid) asyncio.ensure_future( - self.xmpp['xep_0115'].update_caps(jid), + self.xmpp['xep_0115'].update_caps(jid, broadcast=False), loop=self.xmpp.loop, ) @@ -82,7 +82,7 @@ class XEP_0163(BasePlugin): self.xmpp['xep_0030'].del_feature(jid=jid, feature='%s+notify' % namespace) asyncio.ensure_future( - self.xmpp['xep_0115'].update_caps(jid), + self.xmpp['xep_0115'].update_caps(jid, broadcast=False), loop=self.xmpp.loop, ) From 41fc6a2e6b29927148d2af7ed33d1f1645a31bf4 Mon Sep 17 00:00:00 2001 From: mathieui Date: Tue, 20 Apr 2021 00:06:37 +0200 Subject: [PATCH 3/3] itests: explicitly send caps in avatar example --- itests/test_user_avatar.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/itests/test_user_avatar.py b/itests/test_user_avatar.py index 193bbe72..988225bb 100644 --- a/itests/test_user_avatar.py +++ b/itests/test_user_avatar.py @@ -11,9 +11,12 @@ class TestUserAvatar(SlixIntegration): self.envjid('CI_ACCOUNT1'), self.envstr('CI_ACCOUNT1_PASSWORD'), ) - self.register_plugins(['xep_0084']) + self.register_plugins(['xep_0084', 'xep_0115']) self.data = b'coucou coucou' await self.connect_clients() + await asyncio.gather( + self.clients[0]['xep_0115'].update_caps(), + ) async def _clear_avatar(self): """Utility for purging remote state"""