XEP-0030: API changes
- ``supports``, ``has_identity``, ``get_info``, ``get_items`` are now coroutines - ``set_info````set_items``, ``del_items``, ``add_item``, ``add_identity``, ``del_identity``, ``set_identities``, ``del_identities``, ``add_feature``, ``del_feature``, ``set_feature``, ``set_features``, ``del_features`` now return a Future also fix has_identity and supports which have been broken in forever
This commit is contained in:
parent
7772e26a8c
commit
13de36baa1
@ -6,13 +6,13 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
from asyncio import Future
|
||||||
from typing import Optional, Callable
|
from typing import Optional, Callable
|
||||||
|
|
||||||
from slixmpp import Iq
|
from slixmpp import Iq
|
||||||
from slixmpp import future_wrapper
|
from slixmpp import future_wrapper
|
||||||
from slixmpp.plugins import BasePlugin
|
from slixmpp.plugins import BasePlugin
|
||||||
from slixmpp.xmlstream.handler import Callback
|
from slixmpp.xmlstream.handler import Callback, CoroutineCallback
|
||||||
from slixmpp.xmlstream.matcher import StanzaPath
|
from slixmpp.xmlstream.matcher import StanzaPath
|
||||||
from slixmpp.xmlstream import register_stanza_plugin, JID
|
from slixmpp.xmlstream import register_stanza_plugin, JID
|
||||||
from slixmpp.plugins.xep_0030 import stanza, DiscoInfo, DiscoItems
|
from slixmpp.plugins.xep_0030 import stanza, DiscoInfo, DiscoItems
|
||||||
@ -91,12 +91,12 @@ class XEP_0030(BasePlugin):
|
|||||||
Start the XEP-0030 plugin.
|
Start the XEP-0030 plugin.
|
||||||
"""
|
"""
|
||||||
self.xmpp.register_handler(
|
self.xmpp.register_handler(
|
||||||
Callback('Disco Info',
|
CoroutineCallback('Disco Info',
|
||||||
StanzaPath('iq/disco_info'),
|
StanzaPath('iq/disco_info'),
|
||||||
self._handle_disco_info))
|
self._handle_disco_info))
|
||||||
|
|
||||||
self.xmpp.register_handler(
|
self.xmpp.register_handler(
|
||||||
Callback('Disco Items',
|
CoroutineCallback('Disco Items',
|
||||||
StanzaPath('iq/disco_items'),
|
StanzaPath('iq/disco_items'),
|
||||||
self._handle_disco_items))
|
self._handle_disco_items))
|
||||||
|
|
||||||
@ -228,10 +228,13 @@ class XEP_0030(BasePlugin):
|
|||||||
self.api.restore_default(op, jid, node)
|
self.api.restore_default(op, jid, node)
|
||||||
|
|
||||||
def supports(self, jid=None, node=None, feature=None, local=False,
|
def supports(self, jid=None, node=None, feature=None, local=False,
|
||||||
cached=True, ifrom=None):
|
cached=True, ifrom=None) -> Future:
|
||||||
"""
|
"""
|
||||||
Check if a JID supports a given feature.
|
Check if a JID supports a given feature.
|
||||||
|
|
||||||
|
.. versionchanged:: 1.8.0
|
||||||
|
This function now returns a Future.
|
||||||
|
|
||||||
Return values:
|
Return values:
|
||||||
:param True: The feature is supported
|
:param True: The feature is supported
|
||||||
:param False: The feature is not listed as supported
|
:param False: The feature is not listed as supported
|
||||||
@ -259,10 +262,13 @@ class XEP_0030(BasePlugin):
|
|||||||
return self.api['supports'](jid, node, ifrom, data)
|
return self.api['supports'](jid, node, ifrom, data)
|
||||||
|
|
||||||
def has_identity(self, jid=None, node=None, category=None, itype=None,
|
def has_identity(self, jid=None, node=None, category=None, itype=None,
|
||||||
lang=None, local=False, cached=True, ifrom=None):
|
lang=None, local=False, cached=True, ifrom=None) -> Future:
|
||||||
"""
|
"""
|
||||||
Check if a JID provides a given identity.
|
Check if a JID provides a given identity.
|
||||||
|
|
||||||
|
.. versionchanged:: 1.8.0
|
||||||
|
This function now returns a Future.
|
||||||
|
|
||||||
Return values:
|
Return values:
|
||||||
:param True: The identity is provided
|
:param True: The identity is provided
|
||||||
:param False: The identity is not listed
|
:param False: The identity is not listed
|
||||||
@ -324,8 +330,7 @@ class XEP_0030(BasePlugin):
|
|||||||
callback(results)
|
callback(results)
|
||||||
return results
|
return results
|
||||||
|
|
||||||
@future_wrapper
|
async def get_info(self, jid=None, node=None, local=None,
|
||||||
def get_info(self, jid=None, node=None, local=None,
|
|
||||||
cached=None, **kwargs):
|
cached=None, **kwargs):
|
||||||
"""
|
"""
|
||||||
Retrieve the disco#info results from a given JID/node combination.
|
Retrieve the disco#info results from a given JID/node combination.
|
||||||
@ -338,6 +343,9 @@ class XEP_0030(BasePlugin):
|
|||||||
If requesting items from a local JID/node, then only a DiscoInfo
|
If requesting items from a local JID/node, then only a DiscoInfo
|
||||||
stanza will be returned. Otherwise, an Iq stanza will be returned.
|
stanza will be returned. Otherwise, an Iq stanza will be returned.
|
||||||
|
|
||||||
|
.. versionchanged:: 1.8.0
|
||||||
|
This function is now a coroutine.
|
||||||
|
|
||||||
:param jid: Request info from this JID.
|
:param jid: Request info from this JID.
|
||||||
:param node: The particular node to query.
|
:param node: The particular node to query.
|
||||||
:param local: If true, then the query is for a JID/node
|
:param local: If true, then the query is for a JID/node
|
||||||
@ -369,18 +377,21 @@ class XEP_0030(BasePlugin):
|
|||||||
if local:
|
if local:
|
||||||
log.debug("Looking up local disco#info data " + \
|
log.debug("Looking up local disco#info data " + \
|
||||||
"for %s, node %s.", jid, node)
|
"for %s, node %s.", jid, node)
|
||||||
info = self.api['get_info'](jid, node,
|
info = await self.api['get_info'](
|
||||||
kwargs.get('ifrom', None),
|
jid, node, kwargs.get('ifrom', None),
|
||||||
kwargs)
|
kwargs
|
||||||
|
)
|
||||||
info = self._fix_default_info(info)
|
info = self._fix_default_info(info)
|
||||||
return self._wrap(kwargs.get('ifrom', None), jid, info)
|
return self._wrap(kwargs.get('ifrom', None), jid, info)
|
||||||
|
|
||||||
if cached:
|
if cached:
|
||||||
log.debug("Looking up cached disco#info data " + \
|
log.debug("Looking up cached disco#info data " + \
|
||||||
"for %s, node %s.", jid, node)
|
"for %s, node %s.", jid, node)
|
||||||
info = self.api['get_cached_info'](jid, node,
|
info = await self.api['get_cached_info'](
|
||||||
kwargs.get('ifrom', None),
|
jid, node,
|
||||||
kwargs)
|
kwargs.get('ifrom', None),
|
||||||
|
kwargs
|
||||||
|
)
|
||||||
if info is not None:
|
if info is not None:
|
||||||
return self._wrap(kwargs.get('ifrom', None), jid, info)
|
return self._wrap(kwargs.get('ifrom', None), jid, info)
|
||||||
|
|
||||||
@ -390,21 +401,24 @@ class XEP_0030(BasePlugin):
|
|||||||
iq['to'] = jid
|
iq['to'] = jid
|
||||||
iq['type'] = 'get'
|
iq['type'] = 'get'
|
||||||
iq['disco_info']['node'] = node if node else ''
|
iq['disco_info']['node'] = node if node else ''
|
||||||
return iq.send(timeout=kwargs.get('timeout', None),
|
return await iq.send(timeout=kwargs.get('timeout', None),
|
||||||
callback=kwargs.get('callback', None),
|
callback=kwargs.get('callback', None),
|
||||||
timeout_callback=kwargs.get('timeout_callback', None))
|
timeout_callback=kwargs.get('timeout_callback', None))
|
||||||
|
|
||||||
def set_info(self, jid=None, node=None, info=None):
|
def set_info(self, jid=None, node=None, info=None) -> Future:
|
||||||
"""
|
"""
|
||||||
Set the disco#info data for a JID/node based on an existing
|
Set the disco#info data for a JID/node based on an existing
|
||||||
disco#info stanza.
|
disco#info stanza.
|
||||||
|
|
||||||
|
.. versionchanged:: 1.8.0
|
||||||
|
This function now returns a Future.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if isinstance(info, Iq):
|
if isinstance(info, Iq):
|
||||||
info = info['disco_info']
|
info = info['disco_info']
|
||||||
self.api['set_info'](jid, node, None, info)
|
return self.api['set_info'](jid, node, None, info)
|
||||||
|
|
||||||
@future_wrapper
|
async def get_items(self, jid=None, node=None, local=False, **kwargs):
|
||||||
def get_items(self, jid=None, node=None, local=False, **kwargs):
|
|
||||||
"""
|
"""
|
||||||
Retrieve the disco#items results from a given JID/node combination.
|
Retrieve the disco#items results from a given JID/node combination.
|
||||||
|
|
||||||
@ -416,6 +430,9 @@ class XEP_0030(BasePlugin):
|
|||||||
If requesting items from a local JID/node, then only a DiscoItems
|
If requesting items from a local JID/node, then only a DiscoItems
|
||||||
stanza will be returned. Otherwise, an Iq stanza will be returned.
|
stanza will be returned. Otherwise, an Iq stanza will be returned.
|
||||||
|
|
||||||
|
.. versionchanged:: 1.8.0
|
||||||
|
This function is now a coroutine.
|
||||||
|
|
||||||
:param jid: Request info from this JID.
|
:param jid: Request info from this JID.
|
||||||
:param node: The particular node to query.
|
:param node: The particular node to query.
|
||||||
:param local: If true, then the query is for a JID/node
|
:param local: If true, then the query is for a JID/node
|
||||||
@ -428,7 +445,7 @@ class XEP_0030(BasePlugin):
|
|||||||
Otherwise the parameter is ignored.
|
Otherwise the parameter is ignored.
|
||||||
"""
|
"""
|
||||||
if local or local is None and jid is None:
|
if local or local is None and jid is None:
|
||||||
items = self.api['get_items'](jid, node,
|
items = await self.api['get_items'](jid, node,
|
||||||
kwargs.get('ifrom', None),
|
kwargs.get('ifrom', None),
|
||||||
kwargs)
|
kwargs)
|
||||||
return self._wrap(kwargs.get('ifrom', None), jid, items)
|
return self._wrap(kwargs.get('ifrom', None), jid, items)
|
||||||
@ -440,43 +457,52 @@ class XEP_0030(BasePlugin):
|
|||||||
iq['type'] = 'get'
|
iq['type'] = 'get'
|
||||||
iq['disco_items']['node'] = node if node else ''
|
iq['disco_items']['node'] = node if node else ''
|
||||||
if kwargs.get('iterator', False) and self.xmpp['xep_0059']:
|
if kwargs.get('iterator', False) and self.xmpp['xep_0059']:
|
||||||
raise NotImplementedError("XEP 0059 has not yet been fixed")
|
|
||||||
return self.xmpp['xep_0059'].iterate(iq, 'disco_items')
|
return self.xmpp['xep_0059'].iterate(iq, 'disco_items')
|
||||||
else:
|
else:
|
||||||
return iq.send(timeout=kwargs.get('timeout', None),
|
return await iq.send(timeout=kwargs.get('timeout', None),
|
||||||
callback=kwargs.get('callback', None),
|
callback=kwargs.get('callback', None),
|
||||||
timeout_callback=kwargs.get('timeout_callback', None))
|
timeout_callback=kwargs.get('timeout_callback', None))
|
||||||
|
|
||||||
def set_items(self, jid=None, node=None, **kwargs):
|
def set_items(self, jid=None, node=None, **kwargs) -> Future:
|
||||||
"""
|
"""
|
||||||
Set or replace all items for the specified JID/node combination.
|
Set or replace all items for the specified JID/node combination.
|
||||||
|
|
||||||
The given items must be in a list or set where each item is a
|
The given items must be in a list or set where each item is a
|
||||||
tuple of the form: (jid, node, name).
|
tuple of the form: (jid, node, name).
|
||||||
|
|
||||||
|
|
||||||
|
.. versionchanged:: 1.8.0
|
||||||
|
This function now returns a Future.
|
||||||
|
|
||||||
:param jid: The JID to modify.
|
:param jid: The JID to modify.
|
||||||
:param node: Optional node to modify.
|
:param node: Optional node to modify.
|
||||||
:param items: A series of items in tuple format.
|
:param items: A series of items in tuple format.
|
||||||
"""
|
"""
|
||||||
self.api['set_items'](jid, node, None, kwargs)
|
return self.api['set_items'](jid, node, None, kwargs)
|
||||||
|
|
||||||
def del_items(self, jid=None, node=None, **kwargs):
|
def del_items(self, jid=None, node=None, **kwargs) -> Future:
|
||||||
"""
|
"""
|
||||||
Remove all items from the given JID/node combination.
|
Remove all items from the given JID/node combination.
|
||||||
|
|
||||||
|
.. versionchanged:: 1.8.0
|
||||||
|
This function now returns a Future.
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
:param jid: The JID to modify.
|
:param jid: The JID to modify.
|
||||||
:param node: Optional node to modify.
|
:param node: Optional node to modify.
|
||||||
"""
|
"""
|
||||||
self.api['del_items'](jid, node, None, kwargs)
|
return self.api['del_items'](jid, node, None, kwargs)
|
||||||
|
|
||||||
def add_item(self, jid='', name='', node=None, subnode='', ijid=None):
|
def add_item(self, jid='', name='', node=None, subnode='', ijid=None) -> Future:
|
||||||
"""
|
"""
|
||||||
Add a new item element to the given JID/node combination.
|
Add a new item element to the given JID/node combination.
|
||||||
|
|
||||||
Each item is required to have a JID, but may also specify
|
Each item is required to have a JID, but may also specify
|
||||||
a node value to reference non-addressable entities.
|
a node value to reference non-addressable entities.
|
||||||
|
|
||||||
|
.. versionchanged:: 1.8.0
|
||||||
|
This function now returns a Future.
|
||||||
|
|
||||||
:param jid: The JID for the item.
|
:param jid: The JID for the item.
|
||||||
:param name: Optional name for the item.
|
:param name: Optional name for the item.
|
||||||
:param node: The node to modify.
|
:param node: The node to modify.
|
||||||
@ -488,9 +514,9 @@ class XEP_0030(BasePlugin):
|
|||||||
kwargs = {'ijid': jid,
|
kwargs = {'ijid': jid,
|
||||||
'name': name,
|
'name': name,
|
||||||
'inode': subnode}
|
'inode': subnode}
|
||||||
self.api['add_item'](ijid, node, None, kwargs)
|
return self.api['add_item'](ijid, node, None, kwargs)
|
||||||
|
|
||||||
def del_item(self, jid=None, node=None, **kwargs):
|
def del_item(self, jid=None, node=None, **kwargs) -> Future:
|
||||||
"""
|
"""
|
||||||
Remove a single item from the given JID/node combination.
|
Remove a single item from the given JID/node combination.
|
||||||
|
|
||||||
@ -499,10 +525,10 @@ class XEP_0030(BasePlugin):
|
|||||||
:param ijid: The item's JID.
|
:param ijid: The item's JID.
|
||||||
:param inode: The item's node.
|
:param inode: The item's node.
|
||||||
"""
|
"""
|
||||||
self.api['del_item'](jid, node, None, kwargs)
|
return self.api['del_item'](jid, node, None, kwargs)
|
||||||
|
|
||||||
def add_identity(self, category='', itype='', name='',
|
def add_identity(self, category='', itype='', name='',
|
||||||
node=None, jid=None, lang=None):
|
node=None, jid=None, lang=None) -> Future:
|
||||||
"""
|
"""
|
||||||
Add a new identity to the given JID/node combination.
|
Add a new identity to the given JID/node combination.
|
||||||
|
|
||||||
@ -514,6 +540,9 @@ class XEP_0030(BasePlugin):
|
|||||||
category/type/xml:lang pairs are allowed so long as the
|
category/type/xml:lang pairs are allowed so long as the
|
||||||
names are different. A category and type is always required.
|
names are different. A category and type is always required.
|
||||||
|
|
||||||
|
.. versionchanged:: 1.8.0
|
||||||
|
This function now returns a Future.
|
||||||
|
|
||||||
:param category: The identity's category.
|
:param category: The identity's category.
|
||||||
:param itype: The identity's type.
|
:param itype: The identity's type.
|
||||||
:param name: Optional name for the identity.
|
:param name: Optional name for the identity.
|
||||||
@ -525,24 +554,31 @@ class XEP_0030(BasePlugin):
|
|||||||
'itype': itype,
|
'itype': itype,
|
||||||
'name': name,
|
'name': name,
|
||||||
'lang': lang}
|
'lang': lang}
|
||||||
self.api['add_identity'](jid, node, None, kwargs)
|
return self.api['add_identity'](jid, node, None, kwargs)
|
||||||
|
|
||||||
def add_feature(self, feature: str, node: Optional[str] = None,
|
def add_feature(self, feature: str, node: Optional[str] = None,
|
||||||
jid: Optional[JID] = None):
|
jid: Optional[JID] = None) -> Future:
|
||||||
"""
|
"""
|
||||||
Add a feature to a JID/node combination.
|
Add a feature to a JID/node combination.
|
||||||
|
|
||||||
|
.. versionchanged:: 1.8.0
|
||||||
|
This function now returns a Future.
|
||||||
|
|
||||||
:param feature: The namespace of the supported feature.
|
:param feature: The namespace of the supported feature.
|
||||||
:param node: The node to modify.
|
:param node: The node to modify.
|
||||||
:param jid: The JID to modify.
|
:param jid: The JID to modify.
|
||||||
"""
|
"""
|
||||||
kwargs = {'feature': feature}
|
kwargs = {'feature': feature}
|
||||||
self.api['add_feature'](jid, node, None, kwargs)
|
return self.api['add_feature'](jid, node, None, kwargs)
|
||||||
|
|
||||||
def del_identity(self, jid: Optional[JID] = None, node: Optional[str] = None, **kwargs):
|
def del_identity(self, jid: Optional[JID] = None,
|
||||||
|
node: Optional[str] = None, **kwargs) -> Future:
|
||||||
"""
|
"""
|
||||||
Remove an identity from the given JID/node combination.
|
Remove an identity from the given JID/node combination.
|
||||||
|
|
||||||
|
.. versionchanged:: 1.8.0
|
||||||
|
This function now returns a Future.
|
||||||
|
|
||||||
:param jid: The JID to modify.
|
:param jid: The JID to modify.
|
||||||
:param node: The node to modify.
|
:param node: The node to modify.
|
||||||
:param category: The identity's category.
|
:param category: The identity's category.
|
||||||
@ -550,67 +586,82 @@ class XEP_0030(BasePlugin):
|
|||||||
:param name: Optional, human readable name for the identity.
|
:param name: Optional, human readable name for the identity.
|
||||||
:param lang: Optional, the identity's xml:lang value.
|
:param lang: Optional, the identity's xml:lang value.
|
||||||
"""
|
"""
|
||||||
self.api['del_identity'](jid, node, None, kwargs)
|
return self.api['del_identity'](jid, node, None, kwargs)
|
||||||
|
|
||||||
def del_feature(self, jid=None, node=None, **kwargs):
|
def del_feature(self, jid=None, node=None, **kwargs) -> Future:
|
||||||
"""
|
"""
|
||||||
Remove a feature from a given JID/node combination.
|
Remove a feature from a given JID/node combination.
|
||||||
|
|
||||||
|
.. versionchanged:: 1.8.0
|
||||||
|
This function now returns a Future.
|
||||||
|
|
||||||
:param jid: The JID to modify.
|
:param jid: The JID to modify.
|
||||||
:param node: The node to modify.
|
:param node: The node to modify.
|
||||||
:param feature: The feature's namespace.
|
:param feature: The feature's namespace.
|
||||||
"""
|
"""
|
||||||
self.api['del_feature'](jid, node, None, kwargs)
|
return self.api['del_feature'](jid, node, None, kwargs)
|
||||||
|
|
||||||
def set_identities(self, jid=None, node=None, **kwargs):
|
def set_identities(self, jid=None, node=None, **kwargs) -> Future:
|
||||||
"""
|
"""
|
||||||
Add or replace all identities for the given JID/node combination.
|
Add or replace all identities for the given JID/node combination.
|
||||||
|
|
||||||
The identities must be in a set where each identity is a tuple
|
The identities must be in a set where each identity is a tuple
|
||||||
of the form: (category, type, lang, name)
|
of the form: (category, type, lang, name)
|
||||||
|
|
||||||
|
.. versionchanged:: 1.8.0
|
||||||
|
This function now returns a Future.
|
||||||
|
|
||||||
:param jid: The JID to modify.
|
:param jid: The JID to modify.
|
||||||
:param node: The node to modify.
|
:param node: The node to modify.
|
||||||
:param identities: A set of identities in tuple form.
|
:param identities: A set of identities in tuple form.
|
||||||
:param lang: Optional, xml:lang value.
|
:param lang: Optional, xml:lang value.
|
||||||
"""
|
"""
|
||||||
self.api['set_identities'](jid, node, None, kwargs)
|
return self.api['set_identities'](jid, node, None, kwargs)
|
||||||
|
|
||||||
def del_identities(self, jid=None, node=None, **kwargs):
|
def del_identities(self, jid=None, node=None, **kwargs) -> Future:
|
||||||
"""
|
"""
|
||||||
Remove all identities for a JID/node combination.
|
Remove all identities for a JID/node combination.
|
||||||
|
|
||||||
If a language is specified, only identities using that
|
If a language is specified, only identities using that
|
||||||
language will be removed.
|
language will be removed.
|
||||||
|
|
||||||
|
.. versionchanged:: 1.8.0
|
||||||
|
This function now returns a Future.
|
||||||
|
|
||||||
:param jid: The JID to modify.
|
:param jid: The JID to modify.
|
||||||
:param node: The node to modify.
|
:param node: The node to modify.
|
||||||
:param lang: Optional. If given, only remove identities
|
:param lang: Optional. If given, only remove identities
|
||||||
using this xml:lang value.
|
using this xml:lang value.
|
||||||
"""
|
"""
|
||||||
self.api['del_identities'](jid, node, None, kwargs)
|
return self.api['del_identities'](jid, node, None, kwargs)
|
||||||
|
|
||||||
def set_features(self, jid=None, node=None, **kwargs):
|
def set_features(self, jid=None, node=None, **kwargs) -> Future:
|
||||||
"""
|
"""
|
||||||
Add or replace the set of supported features
|
Add or replace the set of supported features
|
||||||
for a JID/node combination.
|
for a JID/node combination.
|
||||||
|
|
||||||
|
.. versionchanged:: 1.8.0
|
||||||
|
This function now returns a Future.
|
||||||
|
|
||||||
:param jid: The JID to modify.
|
:param jid: The JID to modify.
|
||||||
:param node: The node to modify.
|
:param node: The node to modify.
|
||||||
:param features: The new set of supported features.
|
:param features: The new set of supported features.
|
||||||
"""
|
"""
|
||||||
self.api['set_features'](jid, node, None, kwargs)
|
return self.api['set_features'](jid, node, None, kwargs)
|
||||||
|
|
||||||
def del_features(self, jid=None, node=None, **kwargs):
|
def del_features(self, jid=None, node=None, **kwargs) -> Future:
|
||||||
"""
|
"""
|
||||||
Remove all features from a JID/node combination.
|
Remove all features from a JID/node combination.
|
||||||
|
|
||||||
|
.. versionchanged:: 1.8.0
|
||||||
|
This function now returns a Future.
|
||||||
|
|
||||||
:param jid: The JID to modify.
|
:param jid: The JID to modify.
|
||||||
:param node: The node to modify.
|
:param node: The node to modify.
|
||||||
"""
|
"""
|
||||||
self.api['del_features'](jid, node, None, kwargs)
|
return self.api['del_features'](jid, node, None, kwargs)
|
||||||
|
|
||||||
def _run_node_handler(self, htype, jid, node=None, ifrom=None, data=None):
|
async def _run_node_handler(self, htype, jid, node=None, ifrom=None, data=None):
|
||||||
"""
|
"""
|
||||||
Execute the most specific node handler for the given
|
Execute the most specific node handler for the given
|
||||||
JID/node combination.
|
JID/node combination.
|
||||||
@ -623,9 +674,9 @@ class XEP_0030(BasePlugin):
|
|||||||
if not data:
|
if not data:
|
||||||
data = {}
|
data = {}
|
||||||
|
|
||||||
return self.api[htype](jid, node, ifrom, data)
|
return await self.api[htype](jid, node, ifrom, data)
|
||||||
|
|
||||||
def _handle_disco_info(self, iq):
|
async def _handle_disco_info(self, iq):
|
||||||
"""
|
"""
|
||||||
Process an incoming disco#info stanza. If it is a get
|
Process an incoming disco#info stanza. If it is a get
|
||||||
request, find and return the appropriate identities
|
request, find and return the appropriate identities
|
||||||
@ -637,10 +688,10 @@ class XEP_0030(BasePlugin):
|
|||||||
if iq['type'] == 'get':
|
if iq['type'] == 'get':
|
||||||
log.debug("Received disco info query from " + \
|
log.debug("Received disco info query from " + \
|
||||||
"<%s> to <%s>.", iq['from'], iq['to'])
|
"<%s> to <%s>.", iq['from'], iq['to'])
|
||||||
info = self.api['get_info'](iq['to'],
|
info = await self.api['get_info'](iq['to'],
|
||||||
iq['disco_info']['node'],
|
iq['disco_info']['node'],
|
||||||
iq['from'],
|
iq['from'],
|
||||||
iq)
|
iq)
|
||||||
if isinstance(info, Iq):
|
if isinstance(info, Iq):
|
||||||
info['id'] = iq['id']
|
info['id'] = iq['id']
|
||||||
info.send()
|
info.send()
|
||||||
@ -662,13 +713,13 @@ class XEP_0030(BasePlugin):
|
|||||||
ito = iq['to'].full
|
ito = iq['to'].full
|
||||||
else:
|
else:
|
||||||
ito = None
|
ito = None
|
||||||
self.api['cache_info'](iq['from'],
|
await self.api['cache_info'](iq['from'],
|
||||||
iq['disco_info']['node'],
|
iq['disco_info']['node'],
|
||||||
ito,
|
ito,
|
||||||
iq)
|
iq)
|
||||||
self.xmpp.event('disco_info', iq)
|
self.xmpp.event('disco_info', iq)
|
||||||
|
|
||||||
def _handle_disco_items(self, iq):
|
async def _handle_disco_items(self, iq):
|
||||||
"""
|
"""
|
||||||
Process an incoming disco#items stanza. If it is a get
|
Process an incoming disco#items stanza. If it is a get
|
||||||
request, find and return the appropriate items. If it
|
request, find and return the appropriate items. If it
|
||||||
@ -679,10 +730,10 @@ class XEP_0030(BasePlugin):
|
|||||||
if iq['type'] == 'get':
|
if iq['type'] == 'get':
|
||||||
log.debug("Received disco items query from " + \
|
log.debug("Received disco items query from " + \
|
||||||
"<%s> to <%s>.", iq['from'], iq['to'])
|
"<%s> to <%s>.", iq['from'], iq['to'])
|
||||||
items = self.api['get_items'](iq['to'],
|
items = await self.api['get_items'](iq['to'],
|
||||||
iq['disco_items']['node'],
|
iq['disco_items']['node'],
|
||||||
iq['from'],
|
iq['from'],
|
||||||
iq)
|
iq)
|
||||||
if isinstance(items, Iq):
|
if isinstance(items, Iq):
|
||||||
items.send()
|
items.send()
|
||||||
else:
|
else:
|
||||||
|
@ -109,7 +109,7 @@ class StaticDisco(object):
|
|||||||
# the requester's JID, except for cached results. To do that,
|
# the requester's JID, except for cached results. To do that,
|
||||||
# register a custom node handler.
|
# register a custom node handler.
|
||||||
|
|
||||||
def supports(self, jid, node, ifrom, data):
|
async def supports(self, jid, node, ifrom, data):
|
||||||
"""
|
"""
|
||||||
Check if a JID supports a given feature.
|
Check if a JID supports a given feature.
|
||||||
|
|
||||||
@ -137,8 +137,8 @@ class StaticDisco(object):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
try:
|
try:
|
||||||
info = self.disco.get_info(jid=jid, node=node,
|
info = await self.disco.get_info(jid=jid, node=node,
|
||||||
ifrom=ifrom, **data)
|
ifrom=ifrom, **data)
|
||||||
info = self.disco._wrap(ifrom, jid, info, True)
|
info = self.disco._wrap(ifrom, jid, info, True)
|
||||||
features = info['disco_info']['features']
|
features = info['disco_info']['features']
|
||||||
return feature in features
|
return feature in features
|
||||||
@ -147,7 +147,7 @@ class StaticDisco(object):
|
|||||||
except IqTimeout:
|
except IqTimeout:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def has_identity(self, jid, node, ifrom, data):
|
async def has_identity(self, jid, node, ifrom, data):
|
||||||
"""
|
"""
|
||||||
Check if a JID has a given identity.
|
Check if a JID has a given identity.
|
||||||
|
|
||||||
@ -176,8 +176,8 @@ class StaticDisco(object):
|
|||||||
'cached': data.get('cached', True)}
|
'cached': data.get('cached', True)}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
info = self.disco.get_info(jid=jid, node=node,
|
info = await self.disco.get_info(jid=jid, node=node,
|
||||||
ifrom=ifrom, **data)
|
ifrom=ifrom, **data)
|
||||||
info = self.disco._wrap(ifrom, jid, info, True)
|
info = self.disco._wrap(ifrom, jid, info, True)
|
||||||
trunc = lambda i: (i[0], i[1], i[2])
|
trunc = lambda i: (i[0], i[1], i[2])
|
||||||
return identity in map(trunc, info['disco_info']['identities'])
|
return identity in map(trunc, info['disco_info']['identities'])
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
|
import asyncio
|
||||||
import time
|
import time
|
||||||
import threading
|
|
||||||
|
|
||||||
import unittest
|
import unittest
|
||||||
from slixmpp.test import SlixTest
|
from slixmpp.test import SlixTest
|
||||||
@ -288,7 +288,9 @@ class TestStreamDisco(SlixTest):
|
|||||||
|
|
||||||
self.xmpp.add_event_handler('disco_info', handle_disco_info)
|
self.xmpp.add_event_handler('disco_info', handle_disco_info)
|
||||||
|
|
||||||
self.xmpp['xep_0030'].get_info('user@localhost', 'foo')
|
|
||||||
|
self.xmpp.wrap(self.xmpp['xep_0030'].get_info('user@localhost', 'foo'))
|
||||||
|
self.wait_()
|
||||||
|
|
||||||
self.send("""
|
self.send("""
|
||||||
<iq type="get" to="user@localhost" id="1">
|
<iq type="get" to="user@localhost" id="1">
|
||||||
@ -483,7 +485,8 @@ class TestStreamDisco(SlixTest):
|
|||||||
|
|
||||||
self.xmpp.add_event_handler('disco_items', handle_disco_items)
|
self.xmpp.add_event_handler('disco_items', handle_disco_items)
|
||||||
|
|
||||||
self.xmpp['xep_0030'].get_items('user@localhost', 'foo')
|
self.xmpp.wrap(self.xmpp['xep_0030'].get_items('user@localhost', 'foo'))
|
||||||
|
self.wait_()
|
||||||
|
|
||||||
self.send("""
|
self.send("""
|
||||||
<iq type="get" to="user@localhost" id="1">
|
<iq type="get" to="user@localhost" id="1">
|
||||||
|
Loading…
Reference in New Issue
Block a user