Begin experiment with a centralized API callback registry.
The API registry generalizes the node handler system from the xep_0030 plugin so that other plugins can use it.
This commit is contained in:
parent
51e5aee830
commit
488f7ed886
191
sleekxmpp/api.py
Normal file
191
sleekxmpp/api.py
Normal file
@ -0,0 +1,191 @@
|
|||||||
|
from sleekxmpp.xmlstream import JID
|
||||||
|
|
||||||
|
|
||||||
|
class APIWrapper(object):
|
||||||
|
|
||||||
|
def __init__(self, api, name):
|
||||||
|
self.api = api
|
||||||
|
self.name = name
|
||||||
|
|
||||||
|
def __getattr__(self, attr):
|
||||||
|
"""Curry API management commands with the API name."""
|
||||||
|
if attr == 'name':
|
||||||
|
return self.name
|
||||||
|
elif attr == 'settings':
|
||||||
|
return self.api.settings[self.name]
|
||||||
|
elif attr == 'register':
|
||||||
|
def curried_handler(handler, op, jid=None, node=None):
|
||||||
|
register = getattr(self.api, attr)
|
||||||
|
return register(handler, self.name, op, jid, node)
|
||||||
|
return curried_handler
|
||||||
|
elif attr == 'register_default':
|
||||||
|
def curried_handler(handler, op, jid=None, node=None):
|
||||||
|
return getattr(self.api, attr)(handler, self.name, op)
|
||||||
|
return curried_handler
|
||||||
|
elif attr in ('run', 'restore_default', 'unregister'):
|
||||||
|
def curried_handler(*args, **kwargs):
|
||||||
|
return getattr(self.api, attr)(self.name, *args, **kwargs)
|
||||||
|
return curried_handler
|
||||||
|
return None
|
||||||
|
|
||||||
|
def __getitem__(self, attr):
|
||||||
|
def curried_handler(jid=None, node=None, ifrom=None, args=None):
|
||||||
|
return self.api.run(self.name, attr, jid, node, ifrom, args)
|
||||||
|
return curried_handler
|
||||||
|
|
||||||
|
|
||||||
|
class APIRegistry(object):
|
||||||
|
|
||||||
|
def __init__(self, xmpp):
|
||||||
|
self._handlers = {}
|
||||||
|
self._handler_defaults = {}
|
||||||
|
self.xmpp = xmpp
|
||||||
|
self.settings = {}
|
||||||
|
|
||||||
|
def _setup(self, ctype, op):
|
||||||
|
"""Initialize the API callback dictionaries.
|
||||||
|
|
||||||
|
:param string ctype: The name of the API to initialize.
|
||||||
|
:param string op: The API operation to initialize.
|
||||||
|
"""
|
||||||
|
if ctype not in self.settings:
|
||||||
|
self.settings[ctype] = {}
|
||||||
|
if ctype not in self._handler_defaults:
|
||||||
|
self._handler_defaults[ctype] = {}
|
||||||
|
if ctype not in self._handlers:
|
||||||
|
self._handlers[ctype] = {}
|
||||||
|
if op not in self._handlers[ctype]:
|
||||||
|
self._handlers[ctype][op] = {'global': None,
|
||||||
|
'jid': {},
|
||||||
|
'node': {}}
|
||||||
|
|
||||||
|
def wrap(self, ctype):
|
||||||
|
"""Return a wrapper object that targets a specific API."""
|
||||||
|
return APIWrapper(self, ctype)
|
||||||
|
|
||||||
|
def purge(self, ctype):
|
||||||
|
"""Remove all information for a given API."""
|
||||||
|
del self.settings[ctype]
|
||||||
|
del self._handler_defaults[ctype]
|
||||||
|
del self._handlers[ctype]
|
||||||
|
|
||||||
|
def run(self, ctype, op, jid=None, node=None, ifrom=None, args=None):
|
||||||
|
"""Execute an API callback, based on specificity.
|
||||||
|
|
||||||
|
The API callback that is executed is chosen based on the combination
|
||||||
|
of the provided JID and node:
|
||||||
|
|
||||||
|
JID | node | Handler
|
||||||
|
==============================
|
||||||
|
Given | Given | Node handler
|
||||||
|
Given | None | JID handler
|
||||||
|
None | None | Global handler
|
||||||
|
|
||||||
|
A node handler is responsible for servicing a single node at a single
|
||||||
|
JID, while a JID handler may respond for any node at a given JID, and
|
||||||
|
the global handler will answer to any JID+node combination.
|
||||||
|
|
||||||
|
Handlers should check that the JID ``ifrom`` is authorized to perform
|
||||||
|
the desired action.
|
||||||
|
|
||||||
|
:param string ctype: The name of the API to use.
|
||||||
|
:param string op: The API operation to perform.
|
||||||
|
:param JID jid: Optionally provide specific JID.
|
||||||
|
:param string node: Optionally provide specific node.
|
||||||
|
:param JID ifrom: Optionally provide the requesting JID.
|
||||||
|
:param tuple args: Optional positional arguments to the handler.
|
||||||
|
"""
|
||||||
|
self._setup(ctype, op)
|
||||||
|
|
||||||
|
if jid in (None, ''):
|
||||||
|
jid = self.xmpp.boundjid
|
||||||
|
if jid and not isinstance(jid, JID):
|
||||||
|
jid = JID(jid)
|
||||||
|
|
||||||
|
if node is None:
|
||||||
|
node = ''
|
||||||
|
|
||||||
|
if self.xmpp.is_component:
|
||||||
|
if self.settings[ctype].get('component_bare', False):
|
||||||
|
jid = jid.bare
|
||||||
|
else:
|
||||||
|
jid = jid.full
|
||||||
|
else:
|
||||||
|
if self.settings[ctype].get('client_bare', True):
|
||||||
|
jid = jid.bare
|
||||||
|
else:
|
||||||
|
jid = jid.full
|
||||||
|
|
||||||
|
handler = self._handlers[ctype][op]['node'].get((jid, node), None)
|
||||||
|
if handler is None:
|
||||||
|
handler = self._handlers[ctype][op]['jid'].get(jid, None)
|
||||||
|
if handler is None:
|
||||||
|
handler = self._handlers[ctype][op].get('global', None)
|
||||||
|
|
||||||
|
if handler:
|
||||||
|
try:
|
||||||
|
return handler(jid, node, ifrom, args)
|
||||||
|
except TypeError:
|
||||||
|
# To preserve backward compatibility, drop the ifrom
|
||||||
|
# parameter for existing handlers that don't understand it.
|
||||||
|
return handler(jid, node, args)
|
||||||
|
|
||||||
|
def register(self, handler, ctype, op, jid=None, node=None, default=False):
|
||||||
|
"""Register an API callback, with JID+node specificity.
|
||||||
|
|
||||||
|
The API callback can later be executed based on the
|
||||||
|
specificity of the provided JID+node combination.
|
||||||
|
|
||||||
|
See :meth:`~ApiRegistry.run` for more details.
|
||||||
|
|
||||||
|
:param string ctype: The name of the API to use.
|
||||||
|
:param string op: The API operation to perform.
|
||||||
|
:param JID jid: Optionally provide specific JID.
|
||||||
|
:param string node: Optionally provide specific node.
|
||||||
|
"""
|
||||||
|
self._setup(ctype, op)
|
||||||
|
if jid is None and node is None:
|
||||||
|
if handler is None:
|
||||||
|
handler = self._handler_defaults[op]
|
||||||
|
self._handlers[ctype][op]['global'] = handler
|
||||||
|
elif jid is not None and node is None:
|
||||||
|
self._handlers[ctype][op]['jid'][jid] = handler
|
||||||
|
else:
|
||||||
|
self._handlers[ctype][op]['node'][(jid, node)] = handler
|
||||||
|
|
||||||
|
def register_default(self, handler, ctype, op):
|
||||||
|
"""Register a default, global handler for an operation.
|
||||||
|
|
||||||
|
:param func handler: The default, global handler for the operation.
|
||||||
|
:param string ctype: The name of the API to modify.
|
||||||
|
:param string op: The API operation to use.
|
||||||
|
"""
|
||||||
|
self._setup(ctype, op)
|
||||||
|
self._handler_defaults[ctype][op] = handler
|
||||||
|
|
||||||
|
def unregister(self, ctype, op, jid=None, node=None):
|
||||||
|
"""Remove an API callback.
|
||||||
|
|
||||||
|
The API callback chosen for removal is based on the
|
||||||
|
specificity of the provided JID+node combination.
|
||||||
|
|
||||||
|
See :meth:`~ApiRegistry.run` for more details.
|
||||||
|
|
||||||
|
:param string ctype: The name of the API to use.
|
||||||
|
:param string op: The API operation to perform.
|
||||||
|
:param JID jid: Optionally provide specific JID.
|
||||||
|
:param string node: Optionally provide specific node.
|
||||||
|
"""
|
||||||
|
self._setup(ctype, op)
|
||||||
|
self.register(None, ctype, op, jid, node)
|
||||||
|
|
||||||
|
def restore_default(self, ctype, op, jid=None, node=None):
|
||||||
|
"""Reset an API callback to use a default handler.
|
||||||
|
|
||||||
|
:param string ctype: The name of the API to use.
|
||||||
|
:param string op: The API operation to perform.
|
||||||
|
:param JID jid: Optionally provide specific JID.
|
||||||
|
:param string node: Optionally provide specific node.
|
||||||
|
"""
|
||||||
|
self.unregister(ctype, op, jid, node)
|
||||||
|
self.register(self._handler_defaults[ctype][op], ctype, op, jid, node)
|
@ -19,6 +19,7 @@ import logging
|
|||||||
|
|
||||||
import sleekxmpp
|
import sleekxmpp
|
||||||
from sleekxmpp import plugins, features, roster
|
from sleekxmpp import plugins, features, roster
|
||||||
|
from sleekxmpp.api import APIRegistry
|
||||||
from sleekxmpp.exceptions import IqError, IqTimeout
|
from sleekxmpp.exceptions import IqError, IqTimeout
|
||||||
|
|
||||||
from sleekxmpp.stanza import Message, Presence, Iq, StreamError
|
from sleekxmpp.stanza import Message, Presence, Iq, StreamError
|
||||||
@ -97,6 +98,22 @@ class BaseXMPP(XMLStream):
|
|||||||
#: ``'to'`` and ``'from'`` JIDs of stanzas.
|
#: ``'to'`` and ``'from'`` JIDs of stanzas.
|
||||||
self.is_component = False
|
self.is_component = False
|
||||||
|
|
||||||
|
#: The API registry is a way to process callbacks based on
|
||||||
|
#: JID+node combinations. Each callback in the registry is
|
||||||
|
#: marked with:
|
||||||
|
#:
|
||||||
|
#: - An API name, e.g. xep_0030
|
||||||
|
#: - The name of an action, e.g. get_info
|
||||||
|
#: - The JID that will be affected
|
||||||
|
#: - The node that will be affected
|
||||||
|
#:
|
||||||
|
#: API handlers with no JID or node will act as global handlers,
|
||||||
|
#: while those with a JID and no node will service all nodes
|
||||||
|
#: for a JID, and handlers with both a JID and node will be
|
||||||
|
#: used only for that specific combination. The handler that
|
||||||
|
#: provides the most specificity will be used.
|
||||||
|
self.api = APIRegistry(self)
|
||||||
|
|
||||||
#: Flag indicating that the initial presence broadcast has
|
#: Flag indicating that the initial presence broadcast has
|
||||||
#: been sent. Until this happens, some servers may not
|
#: been sent. Until this happens, some servers may not
|
||||||
#: behave as expected when sending stanzas.
|
#: behave as expected when sending stanzas.
|
||||||
|
@ -269,6 +269,7 @@ class BasePlugin(object):
|
|||||||
|
|
||||||
def __init__(self, xmpp, config=None):
|
def __init__(self, xmpp, config=None):
|
||||||
self.xmpp = xmpp
|
self.xmpp = xmpp
|
||||||
|
self.api = self.xmpp.api.wrap(self.name)
|
||||||
|
|
||||||
#: A plugin's behaviour may be configurable, in which case those
|
#: A plugin's behaviour may be configurable, in which case those
|
||||||
#: configuration settings will be provided as a dictionary.
|
#: configuration settings will be provided as a dictionary.
|
||||||
|
@ -118,16 +118,13 @@ class XEP_0030(BasePlugin):
|
|||||||
'del_item', 'del_identities', 'del_features', 'cache_info',
|
'del_item', 'del_identities', 'del_features', 'cache_info',
|
||||||
'get_cached_info', 'supports', 'has_identity']
|
'get_cached_info', 'supports', 'has_identity']
|
||||||
|
|
||||||
self.default_handlers = {}
|
|
||||||
self._handlers = {}
|
|
||||||
for op in self._disco_ops:
|
for op in self._disco_ops:
|
||||||
self._add_disco_op(op, getattr(self.static, op))
|
self.api.register(getattr(self.static, op), op)
|
||||||
|
self.api.register_default(getattr(self.static, op), op)
|
||||||
|
|
||||||
def _add_disco_op(self, op, default_handler):
|
def _add_disco_op(self, op, default_handler):
|
||||||
self.default_handlers[op] = default_handler
|
self.api.register(default_handler, op)
|
||||||
self._handlers[op] = {'global': default_handler,
|
self.api.register_default(default_handler, op)
|
||||||
'jid': {},
|
|
||||||
'node': {}}
|
|
||||||
|
|
||||||
def set_node_handler(self, htype, jid=None, node=None, handler=None):
|
def set_node_handler(self, htype, jid=None, node=None, handler=None):
|
||||||
"""
|
"""
|
||||||
@ -173,20 +170,7 @@ class XEP_0030(BasePlugin):
|
|||||||
assumed.
|
assumed.
|
||||||
handler -- The handler function to use.
|
handler -- The handler function to use.
|
||||||
"""
|
"""
|
||||||
if htype not in self._disco_ops:
|
self.api.register(handler, htype, jid, node)
|
||||||
return
|
|
||||||
if jid is None and node is None:
|
|
||||||
self._handlers[htype]['global'] = handler
|
|
||||||
elif node is None:
|
|
||||||
self._handlers[htype]['jid'][jid] = handler
|
|
||||||
elif jid is None:
|
|
||||||
if self.xmpp.is_component:
|
|
||||||
jid = self.xmpp.boundjid.full
|
|
||||||
else:
|
|
||||||
jid = self.xmpp.boundjid.bare
|
|
||||||
self._handlers[htype]['node'][(jid, node)] = handler
|
|
||||||
else:
|
|
||||||
self._handlers[htype]['node'][(jid, node)] = handler
|
|
||||||
|
|
||||||
def del_node_handler(self, htype, jid, node):
|
def del_node_handler(self, htype, jid, node):
|
||||||
"""
|
"""
|
||||||
@ -209,7 +193,7 @@ class XEP_0030(BasePlugin):
|
|||||||
jid -- The JID from which to remove the handler.
|
jid -- The JID from which to remove the handler.
|
||||||
node -- The node from which to remove the handler.
|
node -- The node from which to remove the handler.
|
||||||
"""
|
"""
|
||||||
self.set_node_handler(htype, jid, node, None)
|
self.api.unregister(htype, jid, node)
|
||||||
|
|
||||||
def restore_defaults(self, jid=None, node=None, handlers=None):
|
def restore_defaults(self, jid=None, node=None, handlers=None):
|
||||||
"""
|
"""
|
||||||
@ -232,8 +216,7 @@ class XEP_0030(BasePlugin):
|
|||||||
if handlers is None:
|
if handlers is None:
|
||||||
handlers = self._disco_ops
|
handlers = self._disco_ops
|
||||||
for op in handlers:
|
for op in handlers:
|
||||||
self.del_node_handler(op, jid, node)
|
self.api.restore_default(op, jid, node)
|
||||||
self.set_node_handler(op, jid, node, self.default_handlers[op])
|
|
||||||
|
|
||||||
def supports(self, jid=None, node=None, feature=None, local=False,
|
def supports(self, jid=None, node=None, feature=None, local=False,
|
||||||
cached=True, ifrom=None):
|
cached=True, ifrom=None):
|
||||||
@ -266,7 +249,7 @@ class XEP_0030(BasePlugin):
|
|||||||
data = {'feature': feature,
|
data = {'feature': feature,
|
||||||
'local': local,
|
'local': local,
|
||||||
'cached': cached}
|
'cached': cached}
|
||||||
return self._run_node_handler('supports', jid, node, ifrom, data)
|
return self.api['supports'](jid, node, ifrom, data)
|
||||||
|
|
||||||
def has_identity(self, jid=None, node=None, category=None, itype=None,
|
def has_identity(self, jid=None, node=None, category=None, itype=None,
|
||||||
lang=None, local=False, cached=True, ifrom=None):
|
lang=None, local=False, cached=True, ifrom=None):
|
||||||
@ -303,7 +286,7 @@ class XEP_0030(BasePlugin):
|
|||||||
'lang': lang,
|
'lang': lang,
|
||||||
'local': local,
|
'local': local,
|
||||||
'cached': cached}
|
'cached': cached}
|
||||||
return self._run_node_handler('has_identity', jid, node, ifrom, data)
|
return self.api['has_identity'](jid, node, ifrom, data)
|
||||||
|
|
||||||
def get_info(self, jid=None, node=None, local=False,
|
def get_info(self, jid=None, node=None, local=False,
|
||||||
cached=None, **kwargs):
|
cached=None, **kwargs):
|
||||||
@ -355,16 +338,18 @@ class XEP_0030(BasePlugin):
|
|||||||
if local or jid in (None, ''):
|
if local or jid in (None, ''):
|
||||||
log.debug("Looking up local disco#info data " + \
|
log.debug("Looking up local disco#info data " + \
|
||||||
"for %s, node %s.", jid, node)
|
"for %s, node %s.", jid, node)
|
||||||
info = self._run_node_handler('get_info',
|
info = self.api['get_info'](jid, node,
|
||||||
jid, node, kwargs.get('ifrom', None), kwargs)
|
kwargs.get('ifrom', None),
|
||||||
|
kwargs)
|
||||||
info = self._fix_default_info(info)
|
info = self._fix_default_info(info)
|
||||||
return self._wrap(kwargs.get('ifrom', None), jid, info)
|
return self._wrap(kwargs.get('ifrom', None), jid, info)
|
||||||
|
|
||||||
if cached:
|
if cached:
|
||||||
log.debug("Looking up cached disco#info data " + \
|
log.debug("Looking up cached disco#info data " + \
|
||||||
"for %s, node %s.", jid, node)
|
"for %s, node %s.", jid, node)
|
||||||
info = self._run_node_handler('get_cached_info',
|
info = self.api['get_cached_info'](jid, node,
|
||||||
jid, node, kwargs.get('ifrom', None), kwargs)
|
kwargs.get('ifrom', None),
|
||||||
|
kwargs)
|
||||||
if info is not None:
|
if info is not None:
|
||||||
return self._wrap(kwargs.get('ifrom', None), jid, info)
|
return self._wrap(kwargs.get('ifrom', None), jid, info)
|
||||||
|
|
||||||
@ -385,7 +370,7 @@ class XEP_0030(BasePlugin):
|
|||||||
"""
|
"""
|
||||||
if isinstance(info, Iq):
|
if isinstance(info, Iq):
|
||||||
info = info['disco_info']
|
info = info['disco_info']
|
||||||
self._run_node_handler('set_info', jid, node, None, info)
|
self.api['set_info'](jid, node, None, info)
|
||||||
|
|
||||||
def get_items(self, jid=None, node=None, local=False, **kwargs):
|
def get_items(self, jid=None, node=None, local=False, **kwargs):
|
||||||
"""
|
"""
|
||||||
@ -419,8 +404,9 @@ class XEP_0030(BasePlugin):
|
|||||||
Otherwise the parameter is ignored.
|
Otherwise the parameter is ignored.
|
||||||
"""
|
"""
|
||||||
if local or jid is None:
|
if local or jid is None:
|
||||||
items = self._run_node_handler('get_items',
|
items = self.api['get_items'](jid, node,
|
||||||
jid, node, kwargs.get('ifrom', None), kwargs)
|
kwargs.get('ifrom', None),
|
||||||
|
kwargs)
|
||||||
return self._wrap(kwargs.get('ifrom', None), jid, items)
|
return self._wrap(kwargs.get('ifrom', None), jid, items)
|
||||||
|
|
||||||
iq = self.xmpp.Iq()
|
iq = self.xmpp.Iq()
|
||||||
@ -448,7 +434,7 @@ class XEP_0030(BasePlugin):
|
|||||||
node -- Optional node to modify.
|
node -- Optional node to modify.
|
||||||
items -- A series of items in tuple format.
|
items -- A series of items in tuple format.
|
||||||
"""
|
"""
|
||||||
self._run_node_handler('set_items', jid, node, None, kwargs)
|
self.api['set_items'](jid, node, None, kwargs)
|
||||||
|
|
||||||
def del_items(self, jid=None, node=None, **kwargs):
|
def del_items(self, jid=None, node=None, **kwargs):
|
||||||
"""
|
"""
|
||||||
@ -458,7 +444,7 @@ class XEP_0030(BasePlugin):
|
|||||||
jid -- The JID to modify.
|
jid -- The JID to modify.
|
||||||
node -- Optional node to modify.
|
node -- Optional node to modify.
|
||||||
"""
|
"""
|
||||||
self._run_node_handler('del_items', jid, node, None, kwargs)
|
self.api['del_items'](jid, node, None, kwargs)
|
||||||
|
|
||||||
def add_item(self, jid='', name='', node=None, subnode='', ijid=None):
|
def add_item(self, jid='', name='', node=None, subnode='', ijid=None):
|
||||||
"""
|
"""
|
||||||
@ -479,7 +465,7 @@ class XEP_0030(BasePlugin):
|
|||||||
kwargs = {'ijid': jid,
|
kwargs = {'ijid': jid,
|
||||||
'name': name,
|
'name': name,
|
||||||
'inode': subnode}
|
'inode': subnode}
|
||||||
self._run_node_handler('add_item', ijid, node, None, kwargs)
|
self.api['add_item'](ijid, node, None, kwargs)
|
||||||
|
|
||||||
def del_item(self, jid=None, node=None, **kwargs):
|
def del_item(self, jid=None, node=None, **kwargs):
|
||||||
"""
|
"""
|
||||||
@ -491,7 +477,7 @@ class XEP_0030(BasePlugin):
|
|||||||
ijid -- The item's JID.
|
ijid -- The item's JID.
|
||||||
inode -- The item's node.
|
inode -- The item's node.
|
||||||
"""
|
"""
|
||||||
self._run_node_handler('del_item', jid, node, None, kwargs)
|
self.api['del_item'](jid, node, None, kwargs)
|
||||||
|
|
||||||
def add_identity(self, category='', itype='', name='',
|
def add_identity(self, category='', itype='', name='',
|
||||||
node=None, jid=None, lang=None):
|
node=None, jid=None, lang=None):
|
||||||
@ -518,7 +504,7 @@ class XEP_0030(BasePlugin):
|
|||||||
'itype': itype,
|
'itype': itype,
|
||||||
'name': name,
|
'name': name,
|
||||||
'lang': lang}
|
'lang': lang}
|
||||||
self._run_node_handler('add_identity', jid, node, None, kwargs)
|
self.api['add_identity'](jid, node, None, kwargs)
|
||||||
|
|
||||||
def add_feature(self, feature, node=None, jid=None):
|
def add_feature(self, feature, node=None, jid=None):
|
||||||
"""
|
"""
|
||||||
@ -530,7 +516,7 @@ class XEP_0030(BasePlugin):
|
|||||||
jid -- The JID to modify.
|
jid -- The JID to modify.
|
||||||
"""
|
"""
|
||||||
kwargs = {'feature': feature}
|
kwargs = {'feature': feature}
|
||||||
self._run_node_handler('add_feature', jid, node, None, kwargs)
|
self.api['add_feature'](jid, node, None, kwargs)
|
||||||
|
|
||||||
def del_identity(self, jid=None, node=None, **kwargs):
|
def del_identity(self, jid=None, node=None, **kwargs):
|
||||||
"""
|
"""
|
||||||
@ -544,7 +530,7 @@ class XEP_0030(BasePlugin):
|
|||||||
name -- Optional, human readable name for the identity.
|
name -- Optional, human readable name for the identity.
|
||||||
lang -- Optional, the identity's xml:lang value.
|
lang -- Optional, the identity's xml:lang value.
|
||||||
"""
|
"""
|
||||||
self._run_node_handler('del_identity', jid, node, None, kwargs)
|
self.api['del_identity'](jid, node, None, kwargs)
|
||||||
|
|
||||||
def del_feature(self, jid=None, node=None, **kwargs):
|
def del_feature(self, jid=None, node=None, **kwargs):
|
||||||
"""
|
"""
|
||||||
@ -555,7 +541,7 @@ class XEP_0030(BasePlugin):
|
|||||||
node -- The node to modify.
|
node -- The node to modify.
|
||||||
feature -- The feature's namespace.
|
feature -- The feature's namespace.
|
||||||
"""
|
"""
|
||||||
self._run_node_handler('del_feature', jid, node, None, kwargs)
|
self.api['del_feature'](jid, node, None, kwargs)
|
||||||
|
|
||||||
def set_identities(self, jid=None, node=None, **kwargs):
|
def set_identities(self, jid=None, node=None, **kwargs):
|
||||||
"""
|
"""
|
||||||
@ -570,7 +556,7 @@ class XEP_0030(BasePlugin):
|
|||||||
identities -- A set of identities in tuple form.
|
identities -- A set of identities in tuple form.
|
||||||
lang -- Optional, xml:lang value.
|
lang -- Optional, xml:lang value.
|
||||||
"""
|
"""
|
||||||
self._run_node_handler('set_identities', jid, node, None, kwargs)
|
self.api['set_identities'](jid, node, None, kwargs)
|
||||||
|
|
||||||
def del_identities(self, jid=None, node=None, **kwargs):
|
def del_identities(self, jid=None, node=None, **kwargs):
|
||||||
"""
|
"""
|
||||||
@ -585,7 +571,7 @@ class XEP_0030(BasePlugin):
|
|||||||
lang -- Optional. If given, only remove identities
|
lang -- Optional. If given, only remove identities
|
||||||
using this xml:lang value.
|
using this xml:lang value.
|
||||||
"""
|
"""
|
||||||
self._run_node_handler('del_identities', jid, node, None, kwargs)
|
self.api['del_identities'](jid, node, None, kwargs)
|
||||||
|
|
||||||
def set_features(self, jid=None, node=None, **kwargs):
|
def set_features(self, jid=None, node=None, **kwargs):
|
||||||
"""
|
"""
|
||||||
@ -597,7 +583,7 @@ class XEP_0030(BasePlugin):
|
|||||||
node -- The node to modify.
|
node -- The node to modify.
|
||||||
features -- The new set of supported features.
|
features -- The new set of supported features.
|
||||||
"""
|
"""
|
||||||
self._run_node_handler('set_features', jid, node, None, kwargs)
|
self.api['set_features'](jid, node, None, kwargs)
|
||||||
|
|
||||||
def del_features(self, jid=None, node=None, **kwargs):
|
def del_features(self, jid=None, node=None, **kwargs):
|
||||||
"""
|
"""
|
||||||
@ -607,7 +593,7 @@ class XEP_0030(BasePlugin):
|
|||||||
jid -- The JID to modify.
|
jid -- The JID to modify.
|
||||||
node -- The node to modify.
|
node -- The node to modify.
|
||||||
"""
|
"""
|
||||||
self._run_node_handler('del_features', jid, node, None, kwargs)
|
self.api['del_features'](jid, node, None, kwargs)
|
||||||
|
|
||||||
def _run_node_handler(self, htype, jid, node=None, ifrom=None, data={}):
|
def _run_node_handler(self, htype, jid, node=None, ifrom=None, data={}):
|
||||||
"""
|
"""
|
||||||
@ -620,39 +606,7 @@ class XEP_0030(BasePlugin):
|
|||||||
node -- The node requested.
|
node -- The node requested.
|
||||||
data -- Optional, custom data to pass to the handler.
|
data -- Optional, custom data to pass to the handler.
|
||||||
"""
|
"""
|
||||||
if isinstance(jid, JID):
|
return self.api[htype](jid, node, ifrom, data)
|
||||||
jid = jid.full
|
|
||||||
|
|
||||||
if jid in (None, ''):
|
|
||||||
if self.xmpp.is_component:
|
|
||||||
jid = self.xmpp.boundjid.full
|
|
||||||
else:
|
|
||||||
jid = self.xmpp.boundjid.bare
|
|
||||||
if node is None:
|
|
||||||
node = ''
|
|
||||||
|
|
||||||
try:
|
|
||||||
args = (jid, node, ifrom, data)
|
|
||||||
if self._handlers[htype]['node'].get((jid, node), False):
|
|
||||||
return self._handlers[htype]['node'][(jid, node)](*args)
|
|
||||||
elif self._handlers[htype]['jid'].get(jid, False):
|
|
||||||
return self._handlers[htype]['jid'][jid](*args)
|
|
||||||
elif self._handlers[htype]['global']:
|
|
||||||
return self._handlers[htype]['global'](*args)
|
|
||||||
else:
|
|
||||||
return None
|
|
||||||
except TypeError:
|
|
||||||
# To preserve backward compatibility, drop the ifrom parameter
|
|
||||||
# for existing handlers that don't understand it.
|
|
||||||
args = (jid, node, data)
|
|
||||||
if self._handlers[htype]['node'].get((jid, node), False):
|
|
||||||
return self._handlers[htype]['node'][(jid, node)](*args)
|
|
||||||
elif self._handlers[htype]['jid'].get(jid, False):
|
|
||||||
return self._handlers[htype]['jid'][jid](*args)
|
|
||||||
elif self._handlers[htype]['global']:
|
|
||||||
return self._handlers[htype]['global'](*args)
|
|
||||||
else:
|
|
||||||
return None
|
|
||||||
|
|
||||||
def _handle_disco_info(self, iq):
|
def _handle_disco_info(self, iq):
|
||||||
"""
|
"""
|
||||||
@ -671,11 +625,10 @@ class XEP_0030(BasePlugin):
|
|||||||
jid = iq['to'].full
|
jid = iq['to'].full
|
||||||
else:
|
else:
|
||||||
jid = iq['to'].bare
|
jid = iq['to'].bare
|
||||||
info = self._run_node_handler('get_info',
|
info = self.api['get_info'](jid,
|
||||||
jid,
|
iq['disco_info']['node'],
|
||||||
iq['disco_info']['node'],
|
iq['from'],
|
||||||
iq['from'],
|
iq)
|
||||||
iq)
|
|
||||||
if isinstance(info, Iq):
|
if isinstance(info, Iq):
|
||||||
info.send()
|
info.send()
|
||||||
else:
|
else:
|
||||||
@ -694,8 +647,7 @@ class XEP_0030(BasePlugin):
|
|||||||
ito = iq['to'].full
|
ito = iq['to'].full
|
||||||
else:
|
else:
|
||||||
ito = None
|
ito = None
|
||||||
self._run_node_handler('cache_info',
|
self.api['cache_info'](iq['from'].full,
|
||||||
iq['from'].full,
|
|
||||||
iq['disco_info']['node'],
|
iq['disco_info']['node'],
|
||||||
ito,
|
ito,
|
||||||
iq)
|
iq)
|
||||||
@ -717,8 +669,7 @@ class XEP_0030(BasePlugin):
|
|||||||
jid = iq['to'].full
|
jid = iq['to'].full
|
||||||
else:
|
else:
|
||||||
jid = iq['to'].bare
|
jid = iq['to'].bare
|
||||||
items = self._run_node_handler('get_items',
|
items = self.api['get_items'](jid,
|
||||||
jid,
|
|
||||||
iq['disco_items']['node'],
|
iq['disco_items']['node'],
|
||||||
iq['from'].full,
|
iq['from'].full,
|
||||||
iq)
|
iq)
|
||||||
|
@ -78,7 +78,9 @@ class XEP_0115(BasePlugin):
|
|||||||
self.static = StaticCaps(self.xmpp, disco.static)
|
self.static = StaticCaps(self.xmpp, disco.static)
|
||||||
|
|
||||||
for op in self._disco_ops:
|
for op in self._disco_ops:
|
||||||
disco._add_disco_op(op, getattr(self.static, op))
|
self.api.register(getattr(self.static, op), 'xep_0115', op)
|
||||||
|
self.api.register_default(getattr(self.static, op),
|
||||||
|
'xep_0115', op)
|
||||||
|
|
||||||
self._run_node_handler = disco._run_node_handler
|
self._run_node_handler = disco._run_node_handler
|
||||||
|
|
||||||
@ -279,19 +281,19 @@ class XEP_0115(BasePlugin):
|
|||||||
jid = self.xmpp.boundjid.full
|
jid = self.xmpp.boundjid.full
|
||||||
if isinstance(jid, JID):
|
if isinstance(jid, JID):
|
||||||
jid = jid.full
|
jid = jid.full
|
||||||
return self._run_node_handler('get_verstring', jid)
|
return self.api['get_verstring'](jid)
|
||||||
|
|
||||||
def assign_verstring(self, jid=None, verstring=None):
|
def assign_verstring(self, jid=None, verstring=None):
|
||||||
if jid in (None, ''):
|
if jid in (None, ''):
|
||||||
jid = self.xmpp.boundjid.full
|
jid = self.xmpp.boundjid.full
|
||||||
if isinstance(jid, JID):
|
if isinstance(jid, JID):
|
||||||
jid = jid.full
|
jid = jid.full
|
||||||
return self._run_node_handler('assign_verstring', jid,
|
return self.api['assign_verstring'](jid, args={
|
||||||
data={'verstring': verstring})
|
'verstring': verstring})
|
||||||
|
|
||||||
def cache_caps(self, verstring=None, info=None):
|
def cache_caps(self, verstring=None, info=None):
|
||||||
data = {'verstring': verstring, 'info': info}
|
data = {'verstring': verstring, 'info': info}
|
||||||
return self._run_node_handler('cache_caps', None, None, data=data)
|
return self.api['cache_caps'](args=data)
|
||||||
|
|
||||||
def get_caps(self, jid=None, verstring=None):
|
def get_caps(self, jid=None, verstring=None):
|
||||||
if verstring is None:
|
if verstring is None:
|
||||||
@ -302,4 +304,4 @@ class XEP_0115(BasePlugin):
|
|||||||
if isinstance(jid, JID):
|
if isinstance(jid, JID):
|
||||||
jid = jid.full
|
jid = jid.full
|
||||||
data = {'verstring': verstring}
|
data = {'verstring': verstring}
|
||||||
return self._run_node_handler('get_caps', jid, None, None, data)
|
return self.api['get_caps'](jid, args=data)
|
||||||
|
@ -61,7 +61,8 @@ class XEP_0128(BasePlugin):
|
|||||||
self.disco.del_extended_info = self.del_extended_info
|
self.disco.del_extended_info = self.del_extended_info
|
||||||
|
|
||||||
for op in self._disco_ops:
|
for op in self._disco_ops:
|
||||||
self.disco._add_disco_op(op, getattr(self.static, op))
|
self.api.register(getattr(self.static, op), op)
|
||||||
|
self.api.register_default(getattr(self.static, op), op)
|
||||||
|
|
||||||
def set_extended_info(self, jid=None, node=None, **kwargs):
|
def set_extended_info(self, jid=None, node=None, **kwargs):
|
||||||
"""
|
"""
|
||||||
@ -76,7 +77,7 @@ class XEP_0128(BasePlugin):
|
|||||||
as extended information, replacing any
|
as extended information, replacing any
|
||||||
existing extensions.
|
existing extensions.
|
||||||
"""
|
"""
|
||||||
self.disco._run_node_handler('set_extended_info', jid, node, None, kwargs)
|
self.api['set_extended_info'](jid, node, None, kwargs)
|
||||||
|
|
||||||
def add_extended_info(self, jid=None, node=None, **kwargs):
|
def add_extended_info(self, jid=None, node=None, **kwargs):
|
||||||
"""
|
"""
|
||||||
@ -88,7 +89,7 @@ class XEP_0128(BasePlugin):
|
|||||||
data -- Either a form, or a list of forms to add
|
data -- Either a form, or a list of forms to add
|
||||||
as extended information.
|
as extended information.
|
||||||
"""
|
"""
|
||||||
self.disco._run_node_handler('add_extended_info', jid, node, None, kwargs)
|
self.api['add_extended_info'](jid, node, None, kwargs)
|
||||||
|
|
||||||
def del_extended_info(self, jid=None, node=None, **kwargs):
|
def del_extended_info(self, jid=None, node=None, **kwargs):
|
||||||
"""
|
"""
|
||||||
@ -98,4 +99,4 @@ class XEP_0128(BasePlugin):
|
|||||||
jid -- The JID to modify.
|
jid -- The JID to modify.
|
||||||
node -- The node to modify.
|
node -- The node to modify.
|
||||||
"""
|
"""
|
||||||
self.disco._run_node_handler('del_extended_info', jid, node, None, kwargs)
|
self.api['del_extended_info'](jid, node, None, kwargs)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user