Source code for xmpp.extensions.xep0030

# -*- coding: utf-8 -*-
#
# <xmpp - stateless and concurrency-agnostic XMPP library for python>
#
# Copyright (C) <2016-2017> Gabriel Falcao <gabriel@nacaolivre.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

from speakers import Speaker as Events
from xmpp.models import Node, IQ, JID
from xmpp.extensions import Extension


class QueryInfo(Node):
    __tag__ = 'query'
    __etag__ = '{http://jabber.org/protocol/disco#info}query'
    __namespaces__ = [
        ('', 'http://jabber.org/protocol/disco#info')
    ]
    __children_of__ = IQ


class QueryItems(Node):
    __tag__ = 'query'
    __etag__ = '{http://jabber.org/protocol/disco#items}query'
    __namespaces__ = [
        ('', 'http://jabber.org/protocol/disco#items')
    ]
    __children_of__ = IQ


class Item(Node):
    __tag__ = 'item'
    __etag__ = '{http://jabber.org/protocol/disco#items}item'
    __namespaces__ = [
        ('', 'http://jabber.org/protocol/disco#items'),
    ]
    __single__ = True
    __children_of__ = QueryItems

    def to_string(self):
        if 'jid' in self.attr:
            return 'component:jid:{jid}'.format(**self.attr)

        return 'item:{0}'.format(list(self.attr.items()))

    def __repr__(self):
        return self.to_string()


class Identity(Node):
    __tag__ = 'identity'
    __etag__ = '{http://jabber.org/protocol/disco#info}identity'
    __namespaces__ = [
        ('', 'http://jabber.org/protocol/disco#info'),
    ]
    __children_of__ = QueryInfo

    def to_string(self):
        return ':'.join(filter(bool, [
            self.attr.get('category'),
            self.attr.get('type'),
            self.attr.get('name'),
        ]))

    def __repr__(self):
        return self.to_string()


class Feature(Node):
    __tag__ = 'feature'
    __etag__ = '{http://jabber.org/protocol/disco#info}feature'
    __namespaces__ = [
        ('', 'http://jabber.org/protocol/disco#info'),
    ]
    __children_of__ = QueryInfo

    def __repr__(self):
        return ":".join([
            "feature",
            self.attr.get('var', self.value),
        ])


[docs]class ServiceDiscovery(Extension): """extension for discovering information about other XMPP entities. Two kinds of information can be discovered: (1) the identity and capabilities of an entity, including the protocols and features it supports; and (2) the items associated with an entity, such as the list of rooms hosted at a multi-user chat service.""" __xep__ = '0030' def initialize(self): self.on = Events('disco', [ 'query_items', # the server returned a list of items 'query_info', # the server returned a list of identities and features ]) self.stream.on.node(self.route_nodes) def route_nodes(self, event, node): ROUTES = { QueryInfo: self.on.query_info, QueryItems: self.on.query_items, } NodeClass = type(node) event = ROUTES.get(NodeClass) if event: event.shout(node) def query_items(self, **params): to_jid = JID(params.get('to', self.stream.bound_jid.domain)).bare iq = IQ.create(type='get', to=to_jid) query = QueryItems.create(**params) iq.append(query) self.stream.send(iq) def query_info(self, **params): to_jid = JID(params.get('to', self.stream.bound_jid.domain)).bare iq = IQ.create(type='get', to=to_jid) query = QueryInfo.create(**params) iq.append(query) self.stream.send(iq)