Source code for slixmpp.plugins.xep_0030.stanza.items

# Slixmpp: The Slick XMPP Library
# Copyright (C) 2010 Nathanael C. Fritz, Lance J.T. Stout
# This file is part of Slixmpp.
# See the file LICENSE for copying permission.
from typing import (
    Iterable,
    Optional,
    Set,
    Tuple,
)
from slixmpp import JID
from slixmpp.xmlstream import (
    ElementBase,
    ET,
    register_stanza_plugin,
)


[docs] class DiscoItem(ElementBase): name = 'item' namespace = 'http://jabber.org/protocol/disco#items' plugin_attrib = name interfaces = {'jid', 'node', 'name'}
[docs] def get_node(self) -> Optional[str]: """Return the item's node name or ``None``.""" return self._get_attr('node', None)
[docs] def get_name(self) -> Optional[str]: """Return the item's human readable name, or ``None``.""" return self._get_attr('name', None)
[docs] class DiscoItems(ElementBase): """ Example disco#items stanzas: .. code-block:: xml <iq type="get"> <query xmlns="http://jabber.org/protocol/disco#items" /> </iq> <iq type="result"> <query xmlns="http://jabber.org/protocol/disco#items"> <item jid="chat.example.com" node="xmppdev" name="XMPP Dev" /> <item jid="chat.example.com" node="slixdev" name="Slixmpp Dev" /> </query> </iq> """ name = 'query' namespace = 'http://jabber.org/protocol/disco#items' plugin_attrib = 'disco_items' #: Stanza Interface: #: #: - ``node``: The name of the node to either #: query or return info from. #: - ``items``: A list of 3-tuples, where each tuple contains #: the JID, node, and name of an item. #: interfaces = {'node', 'items'} # Cache items _items: Set[Tuple[JID, Optional[str]]]
[docs] def setup(self, xml: Optional[ET.ElementTree] = None): """ Populate the stanza object using an optional XML object. Overrides ElementBase.setup Caches item information. :param xml: Use an existing XML object for the stanza's values. """ ElementBase.setup(self, xml) self._items = {item[0:2] for item in self['items']}
[docs] def add_item(self, jid: JID, node: Optional[str] = None, name: Optional[str] = None): """ Add a new item element. Each item is required to have a JID, but may also specify a node value to reference non-addressable entitities. :param jid: The JID for the item. :param node: Optional additional information to reference non-addressable items. :param name: Optional human readable name for the item. """ if (jid, node) not in self._items: self._items.add((jid, node)) item = DiscoItem(parent=self) item['jid'] = jid item['node'] = node item['name'] = name self.iterables.append(item) return True return False
[docs] def del_item(self, jid: JID, node: Optional[str] = None) -> bool: """ Remove a single item. :param jid: JID of the item to remove. :param node: Optional extra identifying information. """ if (jid, node) in self._items: for item_xml in self.xml.findall('{%s}item' % self.namespace): item = (item_xml.attrib['jid'], item_xml.attrib.get('node', None)) if item == (jid, node): self.xml.remove(item_xml) return True return False
[docs] def get_items(self) -> Set[DiscoItem]: """Return all items.""" items = set() for item in self['substanzas']: if isinstance(item, DiscoItem): items.add((item['jid'], item['node'], item['name'])) return items
[docs] def set_items(self, items: Iterable[DiscoItem]): """ Set or replace all items. The given items must be in a list or set where each item is a tuple of the form: (jid, node, name) :param items: A series of items in tuple format. """ self.del_items() for item in items: jid, node, name = item self.add_item(jid, node, name)
[docs] def del_items(self): """Remove all items.""" self._items = set() items = [i for i in self.iterables if isinstance(i, DiscoItem)] for item in items: self.xml.remove(item.xml) self.iterables.remove(item)
register_stanza_plugin(DiscoItems, DiscoItem, iterable=True)