Commit ff2e13a9 authored by Philipp Hörist's avatar Philipp Hörist

Extend Discovery module (XEP-0030)

Add disco_info and disco_items methods
parent 372fc63c
Pipeline #3793 passed with stages
in 34 seconds
......@@ -69,6 +69,7 @@ from nbxmpp.modules.muclumbus import Muclumbus
from nbxmpp.modules.software_version import SoftwareVersion
from nbxmpp.modules.adhoc import AdHoc
from nbxmpp.modules.ibb import IBB
from nbxmpp.modules.discovery import Discovery
from nbxmpp.modules.misc import unwrap_carbon
from nbxmpp.modules.misc import unwrap_mam
from nbxmpp.util import get_properties_struct
......@@ -206,6 +207,7 @@ class XMPPDispatcher(PlugIn):
self._modules['SoftwareVersion'] = SoftwareVersion(self._owner)
self._modules['AdHoc'] = AdHoc(self._owner)
self._modules['IBB'] = IBB(self._owner)
self._modules['Discovery'] = Discovery(self._owner)
for instance in self._modules.values():
for handler in instance.handlers:
......
......@@ -18,13 +18,100 @@
import logging
from nbxmpp.protocol import Iq
from nbxmpp.protocol import NS_DISCO_INFO
from nbxmpp.protocol import NS_DISCO_ITEMS
from nbxmpp.protocol import NS_DATA
from nbxmpp.protocol import isResultNode
from nbxmpp.modules.dataforms import extend_form
from nbxmpp.structs import DiscoIdentity
from nbxmpp.structs import DiscoInfo
from nbxmpp.structs import DiscoItems
from nbxmpp.structs import DiscoItem
from nbxmpp.util import call_on_response
from nbxmpp.util import callback
from nbxmpp.util import raise_error
log = logging.getLogger('nbxmpp.m.discovery')
class Discovery:
def __init__(self, client):
self._client = client
self.handlers = []
@call_on_response('_disco_info_received')
def disco_info(self, jid, node=None):
log.info('Disco info: %s, node: %s', jid, node)
return get_disco_request(NS_DISCO_INFO, jid, node)
@callback
def _disco_info_received(self, stanza):
if not isResultNode(stanza):
return raise_error(log.info, stanza)
idenities = []
features = []
dataforms = []
query = stanza.getQuery()
for node in query.getTags('identity'):
attrs = node.getAttrs()
try:
idenities.append(
DiscoIdentity(category=attrs['category'],
type=attrs['type'],
name=attrs.get('name'),
lang=attrs.get('xml:lang')))
except Exception:
return raise_error(log.warning, stanza, 'stanza-malformed')
for node in query.getTags('feature'):
try:
features.append(node.getAttr('var'))
except Exception:
return raise_error(log.warning, stanza, 'stanza-malformed')
for node in query.getTags('x', namespace=NS_DATA):
dataforms.append(extend_form(node))
return DiscoInfo(jid=stanza.getFrom(),
node=query.getAttr('node'),
identities=idenities,
features=features,
dataforms=dataforms)
@call_on_response('_disco_items_received')
def disco_items(self, jid, node=None):
log.info('Disco items: %s, node: %s', jid, node)
return get_disco_request(NS_DISCO_ITEMS, jid, node)
@callback
def _disco_items_received(self, stanza):
if not isResultNode(stanza):
return raise_error(log.info, stanza)
items = []
query = stanza.getQuery()
for node in query.getTags('item'):
attrs = node.getAttrs()
try:
items.append(
DiscoItem(jid=attrs['jid'],
name=attrs.get('name'),
node=attrs.get('node')))
except Exception:
return raise_error(log.warning, stanza, 'stanza-malformed')
return DiscoItems(jid=stanza.getFrom(),
node=query.getAttr('node'),
items=items)
def get_disco_request(namespace, jid, node=None):
iq = Iq('get', to=jid, queryNS=namespace)
if node is not None:
if node:
iq.getQuery().setAttr('node', node)
return iq
......@@ -112,6 +112,15 @@ AdHocCommandNote = namedtuple('AdHocCommandNote', 'text type')
IBBData = namedtuple('IBBData', 'block_size sid seq type data')
IBBData.__new__.__defaults__ = (None, None, None, None, None)
DiscoInfo = namedtuple('DiscoInfo', 'jid node identities features dataforms')
DiscoIdentity = namedtuple('DiscoIdentity', 'category type name lang')
DiscoIdentity.__new__.__defaults__ = (None, None)
DiscoItems = namedtuple('DiscoItems', 'jid node items')
DiscoItem = namedtuple('DiscoItem', 'jid name node')
DiscoItem.__new__.__defaults__ = (None, None)
class AdHocCommand(namedtuple('AdHocCommand', 'jid node name sessionid status data actions notes')):
__slots__ = []
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment