plugin XEP-0060: added node watching methods to bridge:

new methods psNodeWatchAdd and psNodeWatchRemove allows to set a watch for the time of the session on one node, to have a signal called when something change on this node.
This signal (psEventRaw) send raw data (raw XML), in opposition to psEvent which is there to send high level data (e.g. parsed blog data).
Those method are primarely there to let frontends manage local cache for pubsub nodes.
This commit is contained in:
Goffi 2017-11-19 16:51:39 +01:00
commit fbd9737b9a

View file

@ -92,8 +92,10 @@ class XEP_0060(object):
host.bridge.addMethod("psNodeAffiliationsSet", ".plugin", in_sign='ssa{ss}s', out_sign='', method=self._setNodeAffiliations, async=True)
host.bridge.addMethod("psNodeSubscriptionsGet", ".plugin", in_sign='sss', out_sign='a{ss}', method=self._getNodeSubscriptions, async=True)
host.bridge.addMethod("psNodeSubscriptionsSet", ".plugin", in_sign='ssa{ss}s', out_sign='', method=self._setNodeSubscriptions, async=True)
host.bridge.addMethod("psAffiliationsGet", ".plugin", in_sign='sss', out_sign='a{ss}', method=self._getAffiliations, async=True)
host.bridge.addMethod("psNodeDelete", ".plugin", in_sign='sss', out_sign='', method=self._deleteNode, async=True)
host.bridge.addMethod("psNodeWatchAdd", ".plugin", in_sign='sss', out_sign='', method=self._addWatch, async=False)
host.bridge.addMethod("psNodeWatchRemove", ".plugin", in_sign='sss', out_sign='', method=self._removeWatch, async=False)
host.bridge.addMethod("psAffiliationsGet", ".plugin", in_sign='sss', out_sign='a{ss}', method=self._getAffiliations, async=True)
host.bridge.addMethod("psItemsGet", ".plugin", in_sign='ssiassa{ss}s', out_sign='(asa{ss})', method=self._getItems, async=True)
host.bridge.addMethod("psItemSend", ".plugin", in_sign='ssssa{ss}s', out_sign='s', method=self._sendItem, async=True)
host.bridge.addMethod("psRetractItem", ".plugin", in_sign='sssbs', out_sign='', method=self._retractItem, async=True)
@ -105,14 +107,20 @@ class XEP_0060(object):
host.bridge.addMethod("psGetSubscribeRTResult", ".plugin", in_sign='ss', out_sign='(ua(sss))', method=self._manySubscribeRTResult, async=True)
host.bridge.addMethod("psGetFromMany", ".plugin", in_sign='a(ss)ia{ss}s', out_sign='s', method=self._getFromMany)
host.bridge.addMethod("psGetFromManyRTResult", ".plugin", in_sign='ss', out_sign='(ua(sssasa{ss}))', method=self._getFromManyRTResult, async=True)
# high level observer method
host.bridge.addSignal("psEvent", ".plugin", signature='ssssa{ss}s') # args: category, service(jid), node, type (C.PS_ITEMS, C.PS_DELETE), data, profile
# low level observer method, used if service/node is in watching list (see psNodeWatch* methods)
host.bridge.addSignal("psEventRaw", ".plugin", signature='sssass') # args: service(jid), node, type (C.PS_ITEMS, C.PS_DELETE), list of item_xml, profile
def getHandler(self, client):
client.pubsub_client = SatPubSubClient(self.host, self)
return client.pubsub_client
@defer.inlineCallbacks
def profileConnected(self, client):
client.pubsub_watching = set()
client.pubsub_service = yield self.host.findServiceEntity(client, "pubsub", "service")
def getFeatures(self, profile):
@ -577,6 +585,24 @@ class XEP_0060(object):
def deleteNode(self, client, service, nodeIdentifier):
return client.pubsub_client.deleteNode(service, nodeIdentifier)
def _addWatch(self, service_s, node, profile_key):
"""watch modifications on a node
This method should only be called from bridge
"""
client = self.host.getClient(profile_key)
service = jid.JID(service_s) if service_s else client.jid.userhostJID()
client.pubsub_watching.add((service, node))
def _removeWatch(self, service_s, node, profile_key):
"""remove a node watch
This method should only be called from bridge
"""
client = self.host.getClient(profile_key)
service = jid.JID(service_s) if service_s else client.jid.userhostJID()
client.pubsub_watching.remove((service, node))
def _retractItem(self, service_s, nodeIdentifier, itemIdentifier, notify, profile_key):
return self._retractItems(service_s, nodeIdentifier, (itemIdentifier,), notify, profile_key)
@ -897,11 +923,18 @@ class SatPubSubClient(rsm.PubSubClient):
log.debug(u"Pubsub items received")
for callback in self._getNodeCallbacks(event.nodeIdentifier, C.PS_ITEMS):
callback(self.parent, event)
client = self.parent
if (event.sender, event.nodeIdentifier) in client.pubsub_watching:
raw_items = [i.toXml() for i in event.items]
self.host.bridge.psEventRaw(event.sender.full(), event.nodeIdentifier, C.PS_ITEMS, raw_items, client.profile)
def deleteReceived(self, event):
log.debug((u"Publish node deleted"))
for callback in self._getNodeCallbacks(event.nodeIdentifier, C.PS_DELETE):
callback(self.parent, event)
client = self.parent
if (event.sender, event.nodeIdentifier) in client.pubsub_watching:
self.host.bridge.psEventRaw(event.sender.full(), event.nodeIdentifier, C.PS_DELETE, [], client.profile)
def subscriptions(self, service, nodeIdentifier, sender=None):
"""Return the list of subscriptions to the given service and node.