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:
		@@ -6,13 +6,13 @@
 | 
			
		||||
import asyncio
 | 
			
		||||
import logging
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
from asyncio import Future
 | 
			
		||||
from typing import Optional, Callable
 | 
			
		||||
 | 
			
		||||
from slixmpp import Iq
 | 
			
		||||
from slixmpp import future_wrapper
 | 
			
		||||
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 import register_stanza_plugin, JID
 | 
			
		||||
from slixmpp.plugins.xep_0030 import stanza, DiscoInfo, DiscoItems
 | 
			
		||||
@@ -91,12 +91,12 @@ class XEP_0030(BasePlugin):
 | 
			
		||||
        Start the XEP-0030 plugin.
 | 
			
		||||
        """
 | 
			
		||||
        self.xmpp.register_handler(
 | 
			
		||||
                Callback('Disco Info',
 | 
			
		||||
                CoroutineCallback('Disco Info',
 | 
			
		||||
                         StanzaPath('iq/disco_info'),
 | 
			
		||||
                         self._handle_disco_info))
 | 
			
		||||
 | 
			
		||||
        self.xmpp.register_handler(
 | 
			
		||||
                Callback('Disco Items',
 | 
			
		||||
                CoroutineCallback('Disco Items',
 | 
			
		||||
                         StanzaPath('iq/disco_items'),
 | 
			
		||||
                         self._handle_disco_items))
 | 
			
		||||
 | 
			
		||||
@@ -228,10 +228,13 @@ class XEP_0030(BasePlugin):
 | 
			
		||||
            self.api.restore_default(op, jid, node)
 | 
			
		||||
 | 
			
		||||
    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.
 | 
			
		||||
 | 
			
		||||
        .. versionchanged:: 1.8.0
 | 
			
		||||
            This function now returns a Future.
 | 
			
		||||
 | 
			
		||||
        Return values:
 | 
			
		||||
        :param True: The feature is 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)
 | 
			
		||||
 | 
			
		||||
    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.
 | 
			
		||||
 | 
			
		||||
        .. versionchanged:: 1.8.0
 | 
			
		||||
            This function now returns a Future.
 | 
			
		||||
 | 
			
		||||
        Return values:
 | 
			
		||||
        :param True: The identity is provided
 | 
			
		||||
        :param False: The identity is not listed
 | 
			
		||||
@@ -324,8 +330,7 @@ class XEP_0030(BasePlugin):
 | 
			
		||||
            callback(results)
 | 
			
		||||
        return results
 | 
			
		||||
 | 
			
		||||
    @future_wrapper
 | 
			
		||||
    def get_info(self, jid=None, node=None, local=None,
 | 
			
		||||
    async def get_info(self, jid=None, node=None, local=None,
 | 
			
		||||
                       cached=None, **kwargs):
 | 
			
		||||
        """
 | 
			
		||||
        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
 | 
			
		||||
        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 node: The particular node to query.
 | 
			
		||||
        :param local: If true, then the query is for a JID/node
 | 
			
		||||
@@ -369,18 +377,21 @@ class XEP_0030(BasePlugin):
 | 
			
		||||
        if local:
 | 
			
		||||
            log.debug("Looking up local disco#info data " + \
 | 
			
		||||
                      "for %s, node %s.", jid, node)
 | 
			
		||||
            info = self.api['get_info'](jid, node,
 | 
			
		||||
                    kwargs.get('ifrom', None),
 | 
			
		||||
                    kwargs)
 | 
			
		||||
            info = await self.api['get_info'](
 | 
			
		||||
                jid, node, kwargs.get('ifrom', None),
 | 
			
		||||
                kwargs
 | 
			
		||||
            )
 | 
			
		||||
            info = self._fix_default_info(info)
 | 
			
		||||
            return self._wrap(kwargs.get('ifrom', None), jid, info)
 | 
			
		||||
 | 
			
		||||
        if cached:
 | 
			
		||||
            log.debug("Looking up cached disco#info data " + \
 | 
			
		||||
                      "for %s, node %s.", jid, node)
 | 
			
		||||
            info = self.api['get_cached_info'](jid, node,
 | 
			
		||||
                    kwargs.get('ifrom', None),
 | 
			
		||||
                    kwargs)
 | 
			
		||||
            info = await self.api['get_cached_info'](
 | 
			
		||||
                jid, node,
 | 
			
		||||
                kwargs.get('ifrom', None),
 | 
			
		||||
                kwargs
 | 
			
		||||
            )
 | 
			
		||||
            if info is not None:
 | 
			
		||||
                return self._wrap(kwargs.get('ifrom', None), jid, info)
 | 
			
		||||
 | 
			
		||||
@@ -390,21 +401,24 @@ class XEP_0030(BasePlugin):
 | 
			
		||||
        iq['to'] = jid
 | 
			
		||||
        iq['type'] = 'get'
 | 
			
		||||
        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),
 | 
			
		||||
                       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
 | 
			
		||||
        disco#info stanza.
 | 
			
		||||
 | 
			
		||||
        .. versionchanged:: 1.8.0
 | 
			
		||||
            This function now returns a Future.
 | 
			
		||||
 | 
			
		||||
        """
 | 
			
		||||
        if isinstance(info, Iq):
 | 
			
		||||
            info = info['disco_info']
 | 
			
		||||
        self.api['set_info'](jid, node, None, info)
 | 
			
		||||
        return self.api['set_info'](jid, node, None, info)
 | 
			
		||||
 | 
			
		||||
    @future_wrapper
 | 
			
		||||
    def get_items(self, jid=None, node=None, local=False, **kwargs):
 | 
			
		||||
    async def get_items(self, jid=None, node=None, local=False, **kwargs):
 | 
			
		||||
        """
 | 
			
		||||
        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
 | 
			
		||||
        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 node: The particular node to query.
 | 
			
		||||
        :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.
 | 
			
		||||
        """
 | 
			
		||||
        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)
 | 
			
		||||
            return self._wrap(kwargs.get('ifrom', None), jid, items)
 | 
			
		||||
@@ -440,43 +457,52 @@ class XEP_0030(BasePlugin):
 | 
			
		||||
        iq['type'] = 'get'
 | 
			
		||||
        iq['disco_items']['node'] = node if node else ''
 | 
			
		||||
        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')
 | 
			
		||||
        else:
 | 
			
		||||
            return iq.send(timeout=kwargs.get('timeout', None),
 | 
			
		||||
            return await iq.send(timeout=kwargs.get('timeout', None),
 | 
			
		||||
                           callback=kwargs.get('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.
 | 
			
		||||
 | 
			
		||||
        The given items must be in a list or set where each item is a
 | 
			
		||||
        tuple of the form: (jid, node, name).
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        .. versionchanged:: 1.8.0
 | 
			
		||||
            This function now returns a Future.
 | 
			
		||||
 | 
			
		||||
        :param jid: The JID to modify.
 | 
			
		||||
        :param node: Optional node to modify.
 | 
			
		||||
        :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.
 | 
			
		||||
 | 
			
		||||
        .. versionchanged:: 1.8.0
 | 
			
		||||
            This function now returns a Future.
 | 
			
		||||
 | 
			
		||||
        Arguments:
 | 
			
		||||
        :param jid: The JID 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.
 | 
			
		||||
 | 
			
		||||
        Each item is required to have a JID, but may also specify
 | 
			
		||||
        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 name: Optional name for the item.
 | 
			
		||||
        :param node: The node to modify.
 | 
			
		||||
@@ -488,9 +514,9 @@ class XEP_0030(BasePlugin):
 | 
			
		||||
        kwargs = {'ijid': jid,
 | 
			
		||||
                  'name': name,
 | 
			
		||||
                  '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.
 | 
			
		||||
 | 
			
		||||
@@ -499,10 +525,10 @@ class XEP_0030(BasePlugin):
 | 
			
		||||
        :param ijid: The item's JID.
 | 
			
		||||
        :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='',
 | 
			
		||||
                     node=None, jid=None, lang=None):
 | 
			
		||||
                     node=None, jid=None, lang=None) -> Future:
 | 
			
		||||
        """
 | 
			
		||||
        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
 | 
			
		||||
        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 itype: The identity's type.
 | 
			
		||||
        :param name: Optional name for the identity.
 | 
			
		||||
@@ -525,24 +554,31 @@ class XEP_0030(BasePlugin):
 | 
			
		||||
                  'itype': itype,
 | 
			
		||||
                  'name': name,
 | 
			
		||||
                  '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,
 | 
			
		||||
                    jid: Optional[JID] = None):
 | 
			
		||||
                    jid: Optional[JID] = None) -> Future:
 | 
			
		||||
        """
 | 
			
		||||
        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 node: The node to modify.
 | 
			
		||||
        :param jid: The JID to modify.
 | 
			
		||||
        """
 | 
			
		||||
        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.
 | 
			
		||||
 | 
			
		||||
        .. versionchanged:: 1.8.0
 | 
			
		||||
            This function now returns a Future.
 | 
			
		||||
 | 
			
		||||
        :param jid: The JID to modify.
 | 
			
		||||
        :param node: The node to modify.
 | 
			
		||||
        :param category: The identity's category.
 | 
			
		||||
@@ -550,67 +586,82 @@ class XEP_0030(BasePlugin):
 | 
			
		||||
        :param name: Optional, human readable name for the identity.
 | 
			
		||||
        :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.
 | 
			
		||||
 | 
			
		||||
        .. versionchanged:: 1.8.0
 | 
			
		||||
            This function now returns a Future.
 | 
			
		||||
 | 
			
		||||
        :param jid: The JID to modify.
 | 
			
		||||
        :param node: The node to modify.
 | 
			
		||||
        :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.
 | 
			
		||||
 | 
			
		||||
        The identities must be in a set where each identity is a tuple
 | 
			
		||||
        of the form: (category, type, lang, name)
 | 
			
		||||
 | 
			
		||||
        .. versionchanged:: 1.8.0
 | 
			
		||||
            This function now returns a Future.
 | 
			
		||||
 | 
			
		||||
        :param jid: The JID to modify.
 | 
			
		||||
        :param node: The node to modify.
 | 
			
		||||
        :param identities: A set of identities in tuple form.
 | 
			
		||||
        :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.
 | 
			
		||||
 | 
			
		||||
        If a language is specified, only identities using that
 | 
			
		||||
        language will be removed.
 | 
			
		||||
 | 
			
		||||
        .. versionchanged:: 1.8.0
 | 
			
		||||
            This function now returns a Future.
 | 
			
		||||
 | 
			
		||||
        :param jid: The JID to modify.
 | 
			
		||||
        :param node: The node to modify.
 | 
			
		||||
        :param lang: Optional. If given, only remove identities
 | 
			
		||||
                    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
 | 
			
		||||
        for a JID/node combination.
 | 
			
		||||
 | 
			
		||||
        .. versionchanged:: 1.8.0
 | 
			
		||||
            This function now returns a Future.
 | 
			
		||||
 | 
			
		||||
        :param jid: The JID to modify.
 | 
			
		||||
        :param node: The node to modify.
 | 
			
		||||
        :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.
 | 
			
		||||
 | 
			
		||||
        .. versionchanged:: 1.8.0
 | 
			
		||||
            This function now returns a Future.
 | 
			
		||||
 | 
			
		||||
        :param jid: The JID 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
 | 
			
		||||
        JID/node combination.
 | 
			
		||||
@@ -623,9 +674,9 @@ class XEP_0030(BasePlugin):
 | 
			
		||||
        if not 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
 | 
			
		||||
        request, find and return the appropriate identities
 | 
			
		||||
@@ -637,10 +688,10 @@ class XEP_0030(BasePlugin):
 | 
			
		||||
        if iq['type'] == 'get':
 | 
			
		||||
            log.debug("Received disco info query from " + \
 | 
			
		||||
                      "<%s> to <%s>.", iq['from'], iq['to'])
 | 
			
		||||
            info = self.api['get_info'](iq['to'],
 | 
			
		||||
                                        iq['disco_info']['node'],
 | 
			
		||||
                                        iq['from'],
 | 
			
		||||
                                        iq)
 | 
			
		||||
            info = await self.api['get_info'](iq['to'],
 | 
			
		||||
                                              iq['disco_info']['node'],
 | 
			
		||||
                                              iq['from'],
 | 
			
		||||
                                              iq)
 | 
			
		||||
            if isinstance(info, Iq):
 | 
			
		||||
                info['id'] = iq['id']
 | 
			
		||||
                info.send()
 | 
			
		||||
@@ -662,13 +713,13 @@ class XEP_0030(BasePlugin):
 | 
			
		||||
                    ito = iq['to'].full
 | 
			
		||||
                else:
 | 
			
		||||
                    ito = None
 | 
			
		||||
                self.api['cache_info'](iq['from'],
 | 
			
		||||
                                       iq['disco_info']['node'],
 | 
			
		||||
                                       ito,
 | 
			
		||||
                                       iq)
 | 
			
		||||
                await self.api['cache_info'](iq['from'],
 | 
			
		||||
                                             iq['disco_info']['node'],
 | 
			
		||||
                                             ito,
 | 
			
		||||
                                             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
 | 
			
		||||
        request, find and return the appropriate items. If it
 | 
			
		||||
@@ -679,10 +730,10 @@ class XEP_0030(BasePlugin):
 | 
			
		||||
        if iq['type'] == 'get':
 | 
			
		||||
            log.debug("Received disco items query from " + \
 | 
			
		||||
                      "<%s> to <%s>.", iq['from'], iq['to'])
 | 
			
		||||
            items = self.api['get_items'](iq['to'],
 | 
			
		||||
                                          iq['disco_items']['node'],
 | 
			
		||||
                                          iq['from'],
 | 
			
		||||
                                          iq)
 | 
			
		||||
            items = await self.api['get_items'](iq['to'],
 | 
			
		||||
                                                iq['disco_items']['node'],
 | 
			
		||||
                                                iq['from'],
 | 
			
		||||
                                                iq)
 | 
			
		||||
            if isinstance(items, Iq):
 | 
			
		||||
                items.send()
 | 
			
		||||
            else:
 | 
			
		||||
 
 | 
			
		||||
@@ -109,7 +109,7 @@ class StaticDisco(object):
 | 
			
		||||
    # the requester's JID, except for cached results. To do that,
 | 
			
		||||
    # 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.
 | 
			
		||||
 | 
			
		||||
@@ -137,8 +137,8 @@ class StaticDisco(object):
 | 
			
		||||
            return False
 | 
			
		||||
 | 
			
		||||
        try:
 | 
			
		||||
            info = self.disco.get_info(jid=jid, node=node,
 | 
			
		||||
                                       ifrom=ifrom, **data)
 | 
			
		||||
            info = await self.disco.get_info(jid=jid, node=node,
 | 
			
		||||
                                             ifrom=ifrom, **data)
 | 
			
		||||
            info = self.disco._wrap(ifrom, jid, info, True)
 | 
			
		||||
            features = info['disco_info']['features']
 | 
			
		||||
            return feature in features
 | 
			
		||||
@@ -147,7 +147,7 @@ class StaticDisco(object):
 | 
			
		||||
        except IqTimeout:
 | 
			
		||||
            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.
 | 
			
		||||
 | 
			
		||||
@@ -176,8 +176,8 @@ class StaticDisco(object):
 | 
			
		||||
                'cached': data.get('cached', True)}
 | 
			
		||||
 | 
			
		||||
        try:
 | 
			
		||||
            info = self.disco.get_info(jid=jid, node=node,
 | 
			
		||||
                                       ifrom=ifrom, **data)
 | 
			
		||||
            info = await self.disco.get_info(jid=jid, node=node,
 | 
			
		||||
                                             ifrom=ifrom, **data)
 | 
			
		||||
            info = self.disco._wrap(ifrom, jid, info, True)
 | 
			
		||||
            trunc = lambda i: (i[0], i[1], i[2])
 | 
			
		||||
            return identity in map(trunc, info['disco_info']['identities'])
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
import asyncio
 | 
			
		||||
import time
 | 
			
		||||
import threading
 | 
			
		||||
 | 
			
		||||
import unittest
 | 
			
		||||
from slixmpp.test import SlixTest
 | 
			
		||||
@@ -288,7 +288,9 @@ class TestStreamDisco(SlixTest):
 | 
			
		||||
 | 
			
		||||
        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("""
 | 
			
		||||
          <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['xep_0030'].get_items('user@localhost', 'foo')
 | 
			
		||||
        self.xmpp.wrap(self.xmpp['xep_0030'].get_items('user@localhost', 'foo'))
 | 
			
		||||
        self.wait_()
 | 
			
		||||
 | 
			
		||||
        self.send("""
 | 
			
		||||
          <iq type="get" to="user@localhost" id="1">
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user