XEP-0030 stanza: FIX PEP8, types
This commit is contained in:
parent
10611525a0
commit
e3027dabb2
2 changed files with 86 additions and 62 deletions
|
@ -1,10 +1,19 @@
|
|||
|
||||
# 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,
|
||||
List,
|
||||
Optional,
|
||||
Set,
|
||||
Tuple,
|
||||
Union,
|
||||
)
|
||||
from slixmpp.xmlstream import ElementBase, ET
|
||||
|
||||
IdentityType = Tuple[str, str, Optional[str], Optional[str]]
|
||||
|
||||
|
||||
class DiscoInfo(ElementBase):
|
||||
|
||||
|
@ -18,21 +27,23 @@ class DiscoInfo(ElementBase):
|
|||
category with a type of 'pc' to indicate the agent is a human operated
|
||||
client with a GUI, or a category of 'gateway' with a type of 'aim' to
|
||||
identify the agent as a gateway for the legacy AIM protocol. See
|
||||
<http://xmpp.org/registrar/disco-categories.html> for a full list of
|
||||
`XMPP Registrar Disco Categories`_ for a full list of
|
||||
accepted category and type combinations.
|
||||
|
||||
.. _XMPP Registrar Disco Categories: <http://xmpp.org/registrar/disco-categories.html>
|
||||
|
||||
Features are simply a set of the namespaces that identify the supported
|
||||
features. For example, a client that supports service discovery will
|
||||
include the feature 'http://jabber.org/protocol/disco#info'.
|
||||
include the feature ``http://jabber.org/protocol/disco#info``.
|
||||
|
||||
Since clients and components may operate in several roles at once, identity
|
||||
and feature information may be grouped into "nodes". If one were to write
|
||||
all of the identities and features used by a client, then node names would
|
||||
be like section headings.
|
||||
|
||||
Example disco#info stanzas:
|
||||
Example disco#info stanza:
|
||||
|
||||
::
|
||||
.. code-block:: xml
|
||||
|
||||
<iq type="get">
|
||||
<query xmlns="http://jabber.org/protocol/disco#info" />
|
||||
|
@ -46,30 +57,26 @@ class DiscoInfo(ElementBase):
|
|||
<feature var="urn:xmpp:ping" />
|
||||
</query>
|
||||
</iq>
|
||||
|
||||
Stanza Interface:
|
||||
::
|
||||
|
||||
node -- The name of the node to either
|
||||
query or return info from.
|
||||
identities -- A set of 4-tuples, where each tuple contains
|
||||
the category, type, xml:lang, and name
|
||||
of an identity.
|
||||
features -- A set of namespaces for features.
|
||||
|
||||
"""
|
||||
|
||||
name = 'query'
|
||||
namespace = 'http://jabber.org/protocol/disco#info'
|
||||
plugin_attrib = 'disco_info'
|
||||
#: Stanza interfaces:
|
||||
#:
|
||||
#: - ``node``: The name of the node to either query or return the info from
|
||||
#: - ``identities``: A set of 4-tuples, where each tuple contains the
|
||||
#: category, type, xml:lang and name of an identity
|
||||
#: - ``features``: A set of namespaces for features
|
||||
#:
|
||||
interfaces = {'node', 'features', 'identities'}
|
||||
lang_interfaces = {'identities'}
|
||||
|
||||
# Cache identities and features
|
||||
_identities = set()
|
||||
_features = set()
|
||||
_identities: Set[Tuple[str, str, Optional[str]]]
|
||||
_features: Set[str]
|
||||
|
||||
def setup(self, xml=None):
|
||||
def setup(self, xml: Optional[ET.ElementTree] = None):
|
||||
"""
|
||||
Populate the stanza object using an optional XML object.
|
||||
|
||||
|
@ -84,7 +91,9 @@ class DiscoInfo(ElementBase):
|
|||
self._identities = {id[0:3] for id in self['identities']}
|
||||
self._features = self['features']
|
||||
|
||||
def add_identity(self, category, itype, name=None, lang=None):
|
||||
def add_identity(self, category: str, itype: str,
|
||||
name: Optional[str] = None, lang: Optional[str] = None
|
||||
) -> bool:
|
||||
"""
|
||||
Add a new identity element. Each identity must be unique
|
||||
in terms of all four identity components.
|
||||
|
@ -113,7 +122,8 @@ class DiscoInfo(ElementBase):
|
|||
return True
|
||||
return False
|
||||
|
||||
def del_identity(self, category, itype, name=None, lang=None):
|
||||
def del_identity(self, category: str, itype: str, name=None,
|
||||
lang: Optional[str] = None) -> bool:
|
||||
"""
|
||||
Remove a given identity.
|
||||
|
||||
|
@ -134,7 +144,8 @@ class DiscoInfo(ElementBase):
|
|||
return True
|
||||
return False
|
||||
|
||||
def get_identities(self, lang=None, dedupe=True):
|
||||
def get_identities(self, lang: Optional[str] = None, dedupe: bool = True
|
||||
) -> Iterable[IdentityType]:
|
||||
"""
|
||||
Return a set of all identities in tuple form as so:
|
||||
|
||||
|
@ -147,6 +158,7 @@ class DiscoInfo(ElementBase):
|
|||
:param dedupe: If True, de-duplicate identities, otherwise
|
||||
return a list of all identities.
|
||||
"""
|
||||
identities: Union[List[IdentityType], Set[IdentityType]]
|
||||
if dedupe:
|
||||
identities = set()
|
||||
else:
|
||||
|
@ -158,13 +170,14 @@ class DiscoInfo(ElementBase):
|
|||
id_xml.attrib['type'],
|
||||
id_xml.attrib.get('{%s}lang' % self.xml_ns, None),
|
||||
id_xml.attrib.get('name', None))
|
||||
if dedupe:
|
||||
if isinstance(identities, set):
|
||||
identities.add(id)
|
||||
else:
|
||||
identities.append(id)
|
||||
return identities
|
||||
|
||||
def set_identities(self, identities, lang=None):
|
||||
def set_identities(self, identities: Iterable[IdentityType],
|
||||
lang: Optional[str] = None):
|
||||
"""
|
||||
Add or replace all identities. The identities must be a in set
|
||||
where each identity is a tuple of the form:
|
||||
|
@ -187,7 +200,7 @@ class DiscoInfo(ElementBase):
|
|||
category, itype, lang, name = identity
|
||||
self.add_identity(category, itype, name, lang)
|
||||
|
||||
def del_identities(self, lang=None):
|
||||
def del_identities(self, lang: Optional[str] = None):
|
||||
"""
|
||||
Remove all identities. If a language was specified, only
|
||||
remove identities using that language.
|
||||
|
@ -204,7 +217,7 @@ class DiscoInfo(ElementBase):
|
|||
id_xml.attrib.get('{%s}lang' % self.xml_ns, None)))
|
||||
self.xml.remove(id_xml)
|
||||
|
||||
def add_feature(self, feature):
|
||||
def add_feature(self, feature: str) -> bool:
|
||||
"""
|
||||
Add a single, new feature.
|
||||
|
||||
|
@ -218,7 +231,7 @@ class DiscoInfo(ElementBase):
|
|||
return True
|
||||
return False
|
||||
|
||||
def del_feature(self, feature):
|
||||
def del_feature(self, feature: str) -> bool:
|
||||
"""
|
||||
Remove a single feature.
|
||||
|
||||
|
@ -232,20 +245,21 @@ class DiscoInfo(ElementBase):
|
|||
return True
|
||||
return False
|
||||
|
||||
def get_features(self, dedupe=True):
|
||||
def get_features(self, dedupe: bool = True) -> Iterable[str]:
|
||||
"""Return the set of all supported features."""
|
||||
features: Union[List[str], Set[str]]
|
||||
if dedupe:
|
||||
features = set()
|
||||
else:
|
||||
features = []
|
||||
for feature_xml in self.xml.findall('{%s}feature' % self.namespace):
|
||||
if dedupe:
|
||||
if isinstance(features, set):
|
||||
features.add(feature_xml.attrib['var'])
|
||||
else:
|
||||
features.append(feature_xml.attrib['var'])
|
||||
return features
|
||||
|
||||
def set_features(self, features):
|
||||
def set_features(self, features: Iterable[str]):
|
||||
"""
|
||||
Add or replace the set of supported features.
|
||||
|
||||
|
|
|
@ -1,9 +1,34 @@
|
|||
|
||||
# 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 slixmpp.xmlstream import ElementBase, register_stanza_plugin
|
||||
from typing import (
|
||||
Iterable,
|
||||
Optional,
|
||||
Set,
|
||||
Tuple,
|
||||
)
|
||||
from slixmpp import JID
|
||||
from slixmpp.xmlstream import (
|
||||
ElementBase,
|
||||
ET,
|
||||
register_stanza_plugin,
|
||||
)
|
||||
|
||||
|
||||
class DiscoItem(ElementBase):
|
||||
name = 'item'
|
||||
namespace = 'http://jabber.org/protocol/disco#items'
|
||||
plugin_attrib = name
|
||||
interfaces = {'jid', 'node', 'name'}
|
||||
|
||||
def get_node(self) -> Optional[str]:
|
||||
"""Return the item's node name or ``None``."""
|
||||
return self._get_attr('node', None)
|
||||
|
||||
def get_name(self) -> Optional[str]:
|
||||
"""Return the item's human readable name, or ``None``."""
|
||||
return self._get_attr('name', None)
|
||||
|
||||
|
||||
class DiscoItems(ElementBase):
|
||||
|
@ -11,7 +36,7 @@ class DiscoItems(ElementBase):
|
|||
"""
|
||||
Example disco#items stanzas:
|
||||
|
||||
::
|
||||
.. code-block:: xml
|
||||
|
||||
<iq type="get">
|
||||
<query xmlns="http://jabber.org/protocol/disco#items" />
|
||||
|
@ -28,25 +53,24 @@ class DiscoItems(ElementBase):
|
|||
</query>
|
||||
</iq>
|
||||
|
||||
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.
|
||||
|
||||
"""
|
||||
|
||||
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()
|
||||
_items: Set[Tuple[JID, Optional[str]]]
|
||||
|
||||
def setup(self, xml=None):
|
||||
def setup(self, xml: Optional[ET.ElementTree] = None):
|
||||
"""
|
||||
Populate the stanza object using an optional XML object.
|
||||
|
||||
|
@ -59,7 +83,8 @@ class DiscoItems(ElementBase):
|
|||
ElementBase.setup(self, xml)
|
||||
self._items = {item[0:2] for item in self['items']}
|
||||
|
||||
def add_item(self, jid, node=None, name=None):
|
||||
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
|
||||
|
@ -80,7 +105,7 @@ class DiscoItems(ElementBase):
|
|||
return True
|
||||
return False
|
||||
|
||||
def del_item(self, jid, node=None):
|
||||
def del_item(self, jid: JID, node: Optional[str] = None) -> bool:
|
||||
"""
|
||||
Remove a single item.
|
||||
|
||||
|
@ -96,7 +121,7 @@ class DiscoItems(ElementBase):
|
|||
return True
|
||||
return False
|
||||
|
||||
def get_items(self):
|
||||
def get_items(self) -> Set[DiscoItem]:
|
||||
"""Return all items."""
|
||||
items = set()
|
||||
for item in self['substanzas']:
|
||||
|
@ -104,7 +129,7 @@ class DiscoItems(ElementBase):
|
|||
items.add((item['jid'], item['node'], item['name']))
|
||||
return items
|
||||
|
||||
def set_items(self, items):
|
||||
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:
|
||||
|
@ -127,19 +152,4 @@ class DiscoItems(ElementBase):
|
|||
self.iterables.remove(item)
|
||||
|
||||
|
||||
class DiscoItem(ElementBase):
|
||||
name = 'item'
|
||||
namespace = 'http://jabber.org/protocol/disco#items'
|
||||
plugin_attrib = name
|
||||
interfaces = {'jid', 'node', 'name'}
|
||||
|
||||
def get_node(self):
|
||||
"""Return the item's node name or ``None``."""
|
||||
return self._get_attr('node', None)
|
||||
|
||||
def get_name(self):
|
||||
"""Return the item's human readable name, or ``None``."""
|
||||
return self._get_attr('name', None)
|
||||
|
||||
|
||||
register_stanza_plugin(DiscoItems, DiscoItem, iterable=True)
|
||||
|
|
Loading…
Reference in a new issue