plugin XEP-0060: add_managed_node now do strict matching by default:
`add_managed_node` now match node when they are exactly the same by default, but if the new `strict_match` argument is set to `False`, the old behaviour of matching all node which start with the given `node` argument is used. rel 475
This commit is contained in:
parent
ad409de6a5
commit
c21ac3af16
4 changed files with 37 additions and 19 deletions
|
|
@ -97,7 +97,7 @@ class PubsubHook(object):
|
|||
else:
|
||||
# first hook on this node
|
||||
self.host.plugins["XEP-0060"].add_managed_node(
|
||||
node, items_cb=self._items_received
|
||||
node, strict_match=False, items_cb=self._items_received
|
||||
)
|
||||
self.node_hooks[node] = 0
|
||||
log.info(_("node manager installed on {node}").format(node=node))
|
||||
|
|
|
|||
|
|
@ -81,6 +81,7 @@ class PubsubCache:
|
|||
self.host.trigger.add("XEP-0060_getItems", self._get_items_trigger)
|
||||
self._p.add_managed_node(
|
||||
"",
|
||||
strict_match=False,
|
||||
items_cb=self.on_items_event,
|
||||
delete_cb=self.on_delete_event,
|
||||
purge_db=self.on_purge_event,
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
|
||||
from collections import namedtuple
|
||||
from dataclasses import dataclass, field
|
||||
from functools import reduce
|
||||
from typing import (
|
||||
Any,
|
||||
|
|
@ -58,7 +59,6 @@ from libervia.backend.tools import sat_defer
|
|||
from libervia.backend.tools import xml_tools
|
||||
from libervia.backend.tools.common import data_format
|
||||
|
||||
|
||||
log = getLogger(__name__)
|
||||
|
||||
PLUGIN_INFO = {
|
||||
|
|
@ -225,6 +225,12 @@ class NodeMetadata(BaseModel):
|
|||
return self.to_data_form().toElement()
|
||||
|
||||
|
||||
@dataclass
|
||||
class NodeMonitorData:
|
||||
strict_match: bool = True
|
||||
callbacks: dict[str, list[tuple[Callable, int]]] = field(default_factory=dict)
|
||||
|
||||
|
||||
class XEP_0060:
|
||||
OPT_ACCESS_MODEL = "pubsub#access_model"
|
||||
OPT_PERSIST_ITEMS = "pubsub#persist_items"
|
||||
|
|
@ -260,9 +266,7 @@ class XEP_0060:
|
|||
self.host = host
|
||||
self._rsm = host.plugins.get("XEP-0059")
|
||||
self._mam = host.plugins.get("XEP-0313")
|
||||
self._node_cb = (
|
||||
{}
|
||||
) # dictionnary of callbacks for node (key: node, value: list of callbacks)
|
||||
self._node_cb: dict[str, NodeMonitorData] = {}
|
||||
self.rt_sessions = sat_defer.RTDeferredSessions()
|
||||
host.bridge.add_method(
|
||||
"ps_node_create",
|
||||
|
|
@ -576,13 +580,17 @@ class XEP_0060:
|
|||
|
||||
return Extra(rsm_request, extra)
|
||||
|
||||
def add_managed_node(self, node: str, priority: int = 0, **kwargs: Callable):
|
||||
def add_managed_node(
|
||||
self, node: str, priority: int = 0, strict_match=True, **kwargs: Callable
|
||||
):
|
||||
"""Add a handler for a node
|
||||
|
||||
@param node: node to monitor
|
||||
all node *prefixed* with this one will be triggered
|
||||
@param priority: priority of the callback. Callbacks with higher priority will be
|
||||
called first.
|
||||
@param strict_match: if True, will match exactly "node". Otherwise, will match all
|
||||
nodes which start with "node"
|
||||
@param **kwargs: method(s) to call when the node is found
|
||||
the method must be named after PubSub constants in lower case
|
||||
and suffixed with "_cb"
|
||||
|
|
@ -591,11 +599,13 @@ class XEP_0060:
|
|||
"""
|
||||
assert node is not None
|
||||
assert kwargs
|
||||
callbacks = self._node_cb.setdefault(node, {})
|
||||
monitor_data = self._node_cb.setdefault(
|
||||
node, NodeMonitorData(strict_match=strict_match)
|
||||
)
|
||||
for event, cb in kwargs.items():
|
||||
event_name = event[:-3]
|
||||
assert event_name in C.PS_EVENTS
|
||||
cb_list = callbacks.setdefault(event_name, [])
|
||||
cb_list = monitor_data.callbacks.setdefault(event_name, [])
|
||||
cb_list.append((cb, priority))
|
||||
cb_list.sort(key=lambda c: c[1], reverse=True)
|
||||
|
||||
|
|
@ -607,13 +617,13 @@ class XEP_0060:
|
|||
"""
|
||||
assert args
|
||||
try:
|
||||
registred_cb = self._node_cb[node]
|
||||
monitor_data = self._node_cb[node]
|
||||
except KeyError:
|
||||
pass
|
||||
else:
|
||||
removed = False
|
||||
for callback in args:
|
||||
for event, cb_list in registred_cb.items():
|
||||
for event, cb_list in monitor_data.callbacks.items():
|
||||
to_remove = []
|
||||
for cb in cb_list:
|
||||
if cb[0] == callback:
|
||||
|
|
@ -621,8 +631,8 @@ class XEP_0060:
|
|||
for cb in to_remove:
|
||||
cb_list.remove(cb)
|
||||
if not cb_list:
|
||||
del registred_cb[event]
|
||||
if not registred_cb:
|
||||
del monitor_data[event]
|
||||
if not monitor_data:
|
||||
del self._node_cb[node]
|
||||
removed = True
|
||||
break
|
||||
|
|
@ -850,7 +860,7 @@ class XEP_0060:
|
|||
try:
|
||||
return [
|
||||
item["id"]
|
||||
for item in iq_result.pubsub.publish.elements(pubsub.NS_PUBSUB, "item", extra=extra)
|
||||
for item in iq_result.pubsub.publish.elements(pubsub.NS_PUBSUB, "item")
|
||||
]
|
||||
except AttributeError:
|
||||
return []
|
||||
|
|
@ -988,7 +998,10 @@ class XEP_0060:
|
|||
# possible with XEP-0059's plugin RSMRequest, and convert to Wokkel
|
||||
# rsm.RSMRequest only when we need to work with wokkel directly.
|
||||
if isinstance(rsm_request, rsm.RSMRequest):
|
||||
log.warning("Use for rsm.RSMRequest is deprecated")
|
||||
log.warning(
|
||||
"Use of rsm.RSMRequest is deprecated, use plugin_xep_0059.RSMRequest "
|
||||
"instead."
|
||||
)
|
||||
else:
|
||||
rsm_request = rsm_request.to_wokkel_request()
|
||||
if item_ids and max_items is not None:
|
||||
|
|
@ -1966,11 +1979,14 @@ class SatPubSubClient(rsm.PubSubClient):
|
|||
@param event(unicode): one of C.PS_ITEMS, C.PS_RETRACT, C.PS_DELETE
|
||||
@return (iterator[callable]): callbacks for this node/event
|
||||
"""
|
||||
for registered_node, callbacks_dict in self.parent_plugin._node_cb.items():
|
||||
if not node.startswith(registered_node):
|
||||
for registered_node, monitor_data in self.parent_plugin._node_cb.items():
|
||||
if monitor_data.strict_match:
|
||||
if node != registered_node:
|
||||
continue
|
||||
elif not node.startswith(registered_node):
|
||||
continue
|
||||
try:
|
||||
for callback_data in callbacks_dict[event]:
|
||||
for callback_data in monitor_data.callbacks[event]:
|
||||
yield callback_data[0]
|
||||
except KeyError:
|
||||
continue
|
||||
|
|
|
|||
|
|
@ -56,7 +56,6 @@ from libervia.backend.tools.common import data_format
|
|||
from libervia.backend.tools.common import uri as xmpp_uri
|
||||
from libervia.backend.tools.common import regex
|
||||
|
||||
|
||||
log = getLogger(__name__)
|
||||
|
||||
|
||||
|
|
@ -761,7 +760,9 @@ class XEP_0277:
|
|||
}
|
||||
)
|
||||
self.rt_sessions = sat_defer.RTDeferredSessions()
|
||||
self._p.add_managed_node(NS_MICROBLOG, items_cb=self._items_received)
|
||||
self._p.add_managed_node(
|
||||
NS_MICROBLOG, strict_match=False, items_cb=self._items_received
|
||||
)
|
||||
|
||||
host.bridge.add_method(
|
||||
"mb_send",
|
||||
|
|
|
|||
Loading…
Reference in a new issue