summaryrefslogtreecommitdiff
path: root/sleekxmpp
diff options
context:
space:
mode:
Diffstat (limited to 'sleekxmpp')
-rw-r--r--sleekxmpp/plugins/xep_0030/disco.py53
-rw-r--r--sleekxmpp/plugins/xep_0030/static.py87
2 files changed, 129 insertions, 11 deletions
diff --git a/sleekxmpp/plugins/xep_0030/disco.py b/sleekxmpp/plugins/xep_0030/disco.py
index 65c5ecc3..10f9ef4e 100644
--- a/sleekxmpp/plugins/xep_0030/disco.py
+++ b/sleekxmpp/plugins/xep_0030/disco.py
@@ -116,7 +116,7 @@ class xep_0030(base_plugin):
'get_items', 'set_items', 'del_items', 'add_identity',
'del_identity', 'add_feature', 'del_feature', 'add_item',
'del_item', 'del_identities', 'del_features', 'cache_info',
- 'get_cached_info']
+ 'get_cached_info', 'supports', 'has_identity']
self.default_handlers = {}
self._handlers = {}
@@ -270,17 +270,48 @@ class xep_0030(base_plugin):
cached. Defaults to false.
ifrom -- Specifiy the sender's JID.
"""
- try:
- info = self.get_info(jid=jid, node=node, local=local,
- cached=cached, ifrom=ifrom)
- info = self._wrap(ifrom, jid, info, True)
- features = info['disco_info']['features']
- return feature in features
- except IqError:
- return False
- except IqTimeout:
- return None
+ data = {'feature': feature,
+ 'local': local,
+ 'cached': cached}
+ return self._run_node_handler('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):
+ """
+ Check if a JID provides a given identity.
+
+ Return values:
+ True -- The identity is provided
+ False -- The identity is not listed
+ None -- Nothing could be found due to a timeout
+ Arguments:
+ jid -- Request info from this JID.
+ node -- The particular node to query.
+ category -- The category of the identity to check.
+ itype -- The type of the identity to check.
+ lang -- The language of the identity to check.
+ local -- If true, then the query is for a JID/node
+ combination handled by this Sleek instance and
+ no stanzas need to be sent.
+ Otherwise, a disco stanza must be sent to the
+ remove JID to retrieve the info.
+ cached -- If true, then look for the disco info data from
+ the local cache system. If no results are found,
+ send the query as usual. The self.use_cache
+ setting must be set to true for this option to
+ be useful. If set to false, then the cache will
+ be skipped, even if a result has already been
+ cached. Defaults to false.
+ ifrom -- Specifiy the sender's JID.
+ """
+ data = {'category': category,
+ 'itype': itype,
+ 'lang': lang,
+ 'local': local,
+ 'cached': cached}
+ return self._run_node_handler('has_identity', jid, node, ifrom, data)
+
def get_info(self, jid=None, node=None, local=False,
cached=None, **kwargs):
"""
diff --git a/sleekxmpp/plugins/xep_0030/static.py b/sleekxmpp/plugins/xep_0030/static.py
index d48b5649..0b196b40 100644
--- a/sleekxmpp/plugins/xep_0030/static.py
+++ b/sleekxmpp/plugins/xep_0030/static.py
@@ -51,6 +51,7 @@ class StaticDisco(object):
"""
self.nodes = {}
self.xmpp = xmpp
+ self.disco = xmpp['xep_0030']
self.lock = threading.RLock()
def add_node(self, jid=None, node=None, ifrom=None):
@@ -119,6 +120,89 @@ 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):
+ """
+ Check if a JID supports a given feature.
+
+ The data parameter may provide:
+ feature -- The feature to check for support.
+ local -- If true, then the query is for a JID/node
+ combination handled by this Sleek instance and
+ no stanzas need to be sent.
+ Otherwise, a disco stanza must be sent to the
+ remove JID to retrieve the info.
+ cached -- If true, then look for the disco info data from
+ the local cache system. If no results are found,
+ send the query as usual. The self.use_cache
+ setting must be set to true for this option to
+ be useful. If set to false, then the cache will
+ be skipped, even if a result has already been
+ cached. Defaults to false.
+ """
+ feature = data.get('feature', None)
+
+ data = {'local': data.get('local', False),
+ 'cached': data.get('cached', True)}
+
+ if not feature:
+ return False
+
+ try:
+ info = 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
+ except IqError:
+ return False
+ except IqTimeout:
+ return None
+
+ def has_identity(self, jid, node, ifrom, data):
+ """
+ Check if a JID has a given identity.
+
+ The data parameter may provide:
+ category -- The category of the identity to check.
+ itype -- The type of the identity to check.
+ lang -- The language of the identity to check.
+ local -- If true, then the query is for a JID/node
+ combination handled by this Sleek instance and
+ no stanzas need to be sent.
+ Otherwise, a disco stanza must be sent to the
+ remove JID to retrieve the info.
+ cached -- If true, then look for the disco info data from
+ the local cache system. If no results are found,
+ send the query as usual. The self.use_cache
+ setting must be set to true for this option to
+ be useful. If set to false, then the cache will
+ be skipped, even if a result has already been
+ cached. Defaults to false.
+ """
+ identity = (data.get('category', None),
+ data.get('itype', None),
+ data.get('lang', None))
+
+ data = {'local': data.get('local', False),
+ 'cached': data.get('cached', True)}
+
+ if node in (None, ''):
+ info = self.caps.get_caps(jid)
+ if info and identity in info['identities']:
+ return True
+
+ try:
+ info = 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'])
+ except IqError:
+ return False
+ except IqTimeout:
+ return None
+
+
def get_info(self, jid, node, ifrom, data):
"""
Return the stored info data for the requested JID/node combination.
@@ -348,6 +432,9 @@ class StaticDisco(object):
The data parameter is not used.
"""
with self.lock:
+ if isinstance(jid, JID):
+ jid = jid.full
+
if not self.node_exists(jid, node, ifrom):
return None
else: