comparison src/plugins/plugin_xep_0060.py @ 2444:30278ea1ca7c

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.
author Goffi <goffi@goffi.org>
date Sun, 19 Nov 2017 16:51:39 +0100
parents b8ffb7f8056b
children a9c092bf4ee9
comparison
equal deleted inserted replaced
2443:81a45e7886c9 2444:30278ea1ca7c
90 host.bridge.addMethod("psNodeConfigurationSet", ".plugin", in_sign='ssa{ss}s', out_sign='', method=self._setNodeConfiguration, async=True) 90 host.bridge.addMethod("psNodeConfigurationSet", ".plugin", in_sign='ssa{ss}s', out_sign='', method=self._setNodeConfiguration, async=True)
91 host.bridge.addMethod("psNodeAffiliationsGet", ".plugin", in_sign='sss', out_sign='a{ss}', method=self._getNodeAffiliations, async=True) 91 host.bridge.addMethod("psNodeAffiliationsGet", ".plugin", in_sign='sss', out_sign='a{ss}', method=self._getNodeAffiliations, async=True)
92 host.bridge.addMethod("psNodeAffiliationsSet", ".plugin", in_sign='ssa{ss}s', out_sign='', method=self._setNodeAffiliations, async=True) 92 host.bridge.addMethod("psNodeAffiliationsSet", ".plugin", in_sign='ssa{ss}s', out_sign='', method=self._setNodeAffiliations, async=True)
93 host.bridge.addMethod("psNodeSubscriptionsGet", ".plugin", in_sign='sss', out_sign='a{ss}', method=self._getNodeSubscriptions, async=True) 93 host.bridge.addMethod("psNodeSubscriptionsGet", ".plugin", in_sign='sss', out_sign='a{ss}', method=self._getNodeSubscriptions, async=True)
94 host.bridge.addMethod("psNodeSubscriptionsSet", ".plugin", in_sign='ssa{ss}s', out_sign='', method=self._setNodeSubscriptions, async=True) 94 host.bridge.addMethod("psNodeSubscriptionsSet", ".plugin", in_sign='ssa{ss}s', out_sign='', method=self._setNodeSubscriptions, async=True)
95 host.bridge.addMethod("psNodeDelete", ".plugin", in_sign='sss', out_sign='', method=self._deleteNode, async=True)
96 host.bridge.addMethod("psNodeWatchAdd", ".plugin", in_sign='sss', out_sign='', method=self._addWatch, async=False)
97 host.bridge.addMethod("psNodeWatchRemove", ".plugin", in_sign='sss', out_sign='', method=self._removeWatch, async=False)
95 host.bridge.addMethod("psAffiliationsGet", ".plugin", in_sign='sss', out_sign='a{ss}', method=self._getAffiliations, async=True) 98 host.bridge.addMethod("psAffiliationsGet", ".plugin", in_sign='sss', out_sign='a{ss}', method=self._getAffiliations, async=True)
96 host.bridge.addMethod("psNodeDelete", ".plugin", in_sign='sss', out_sign='', method=self._deleteNode, async=True)
97 host.bridge.addMethod("psItemsGet", ".plugin", in_sign='ssiassa{ss}s', out_sign='(asa{ss})', method=self._getItems, async=True) 99 host.bridge.addMethod("psItemsGet", ".plugin", in_sign='ssiassa{ss}s', out_sign='(asa{ss})', method=self._getItems, async=True)
98 host.bridge.addMethod("psItemSend", ".plugin", in_sign='ssssa{ss}s', out_sign='s', method=self._sendItem, async=True) 100 host.bridge.addMethod("psItemSend", ".plugin", in_sign='ssssa{ss}s', out_sign='s', method=self._sendItem, async=True)
99 host.bridge.addMethod("psRetractItem", ".plugin", in_sign='sssbs', out_sign='', method=self._retractItem, async=True) 101 host.bridge.addMethod("psRetractItem", ".plugin", in_sign='sssbs', out_sign='', method=self._retractItem, async=True)
100 host.bridge.addMethod("psRetractItems", ".plugin", in_sign='ssasbs', out_sign='', method=self._retractItems, async=True) 102 host.bridge.addMethod("psRetractItems", ".plugin", in_sign='ssasbs', out_sign='', method=self._retractItems, async=True)
101 host.bridge.addMethod("psSubscribe", ".plugin", in_sign='ssa{ss}s', out_sign='s', method=self._subscribe, async=True) 103 host.bridge.addMethod("psSubscribe", ".plugin", in_sign='ssa{ss}s', out_sign='s', method=self._subscribe, async=True)
103 host.bridge.addMethod("psSubscriptionsGet", ".plugin", in_sign='sss', out_sign='aa{ss}', method=self._subscriptions, async=True) 105 host.bridge.addMethod("psSubscriptionsGet", ".plugin", in_sign='sss', out_sign='aa{ss}', method=self._subscriptions, async=True)
104 host.bridge.addMethod("psSubscribeToMany", ".plugin", in_sign='a(ss)sa{ss}s', out_sign='s', method=self._subscribeToMany) 106 host.bridge.addMethod("psSubscribeToMany", ".plugin", in_sign='a(ss)sa{ss}s', out_sign='s', method=self._subscribeToMany)
105 host.bridge.addMethod("psGetSubscribeRTResult", ".plugin", in_sign='ss', out_sign='(ua(sss))', method=self._manySubscribeRTResult, async=True) 107 host.bridge.addMethod("psGetSubscribeRTResult", ".plugin", in_sign='ss', out_sign='(ua(sss))', method=self._manySubscribeRTResult, async=True)
106 host.bridge.addMethod("psGetFromMany", ".plugin", in_sign='a(ss)ia{ss}s', out_sign='s', method=self._getFromMany) 108 host.bridge.addMethod("psGetFromMany", ".plugin", in_sign='a(ss)ia{ss}s', out_sign='s', method=self._getFromMany)
107 host.bridge.addMethod("psGetFromManyRTResult", ".plugin", in_sign='ss', out_sign='(ua(sssasa{ss}))', method=self._getFromManyRTResult, async=True) 109 host.bridge.addMethod("psGetFromManyRTResult", ".plugin", in_sign='ss', out_sign='(ua(sssasa{ss}))', method=self._getFromManyRTResult, async=True)
110
111 # high level observer method
108 host.bridge.addSignal("psEvent", ".plugin", signature='ssssa{ss}s') # args: category, service(jid), node, type (C.PS_ITEMS, C.PS_DELETE), data, profile 112 host.bridge.addSignal("psEvent", ".plugin", signature='ssssa{ss}s') # args: category, service(jid), node, type (C.PS_ITEMS, C.PS_DELETE), data, profile
113
114 # low level observer method, used if service/node is in watching list (see psNodeWatch* methods)
115 host.bridge.addSignal("psEventRaw", ".plugin", signature='sssass') # args: service(jid), node, type (C.PS_ITEMS, C.PS_DELETE), list of item_xml, profile
109 116
110 def getHandler(self, client): 117 def getHandler(self, client):
111 client.pubsub_client = SatPubSubClient(self.host, self) 118 client.pubsub_client = SatPubSubClient(self.host, self)
112 return client.pubsub_client 119 return client.pubsub_client
113 120
114 @defer.inlineCallbacks 121 @defer.inlineCallbacks
115 def profileConnected(self, client): 122 def profileConnected(self, client):
123 client.pubsub_watching = set()
116 client.pubsub_service = yield self.host.findServiceEntity(client, "pubsub", "service") 124 client.pubsub_service = yield self.host.findServiceEntity(client, "pubsub", "service")
117 125
118 def getFeatures(self, profile): 126 def getFeatures(self, profile):
119 try: 127 try:
120 client = self.host.getClient(profile) 128 client = self.host.getClient(profile)
575 return self.deleteNode(client, jid.JID(service_s) if service_s else None, nodeIdentifier) 583 return self.deleteNode(client, jid.JID(service_s) if service_s else None, nodeIdentifier)
576 584
577 def deleteNode(self, client, service, nodeIdentifier): 585 def deleteNode(self, client, service, nodeIdentifier):
578 return client.pubsub_client.deleteNode(service, nodeIdentifier) 586 return client.pubsub_client.deleteNode(service, nodeIdentifier)
579 587
588 def _addWatch(self, service_s, node, profile_key):
589 """watch modifications on a node
590
591 This method should only be called from bridge
592 """
593 client = self.host.getClient(profile_key)
594 service = jid.JID(service_s) if service_s else client.jid.userhostJID()
595 client.pubsub_watching.add((service, node))
596
597 def _removeWatch(self, service_s, node, profile_key):
598 """remove a node watch
599
600 This method should only be called from bridge
601 """
602 client = self.host.getClient(profile_key)
603 service = jid.JID(service_s) if service_s else client.jid.userhostJID()
604 client.pubsub_watching.remove((service, node))
605
580 def _retractItem(self, service_s, nodeIdentifier, itemIdentifier, notify, profile_key): 606 def _retractItem(self, service_s, nodeIdentifier, itemIdentifier, notify, profile_key):
581 return self._retractItems(service_s, nodeIdentifier, (itemIdentifier,), notify, profile_key) 607 return self._retractItems(service_s, nodeIdentifier, (itemIdentifier,), notify, profile_key)
582 608
583 def _retractItems(self, service_s, nodeIdentifier, itemIdentifiers, notify, profile_key): 609 def _retractItems(self, service_s, nodeIdentifier, itemIdentifiers, notify, profile_key):
584 return self.retractItems(jid.JID(service_s) if service_s else None, nodeIdentifier, itemIdentifiers, notify, profile_key) 610 return self.retractItems(jid.JID(service_s) if service_s else None, nodeIdentifier, itemIdentifiers, notify, profile_key)
895 921
896 def itemsReceived(self, event): 922 def itemsReceived(self, event):
897 log.debug(u"Pubsub items received") 923 log.debug(u"Pubsub items received")
898 for callback in self._getNodeCallbacks(event.nodeIdentifier, C.PS_ITEMS): 924 for callback in self._getNodeCallbacks(event.nodeIdentifier, C.PS_ITEMS):
899 callback(self.parent, event) 925 callback(self.parent, event)
926 client = self.parent
927 if (event.sender, event.nodeIdentifier) in client.pubsub_watching:
928 raw_items = [i.toXml() for i in event.items]
929 self.host.bridge.psEventRaw(event.sender.full(), event.nodeIdentifier, C.PS_ITEMS, raw_items, client.profile)
900 930
901 def deleteReceived(self, event): 931 def deleteReceived(self, event):
902 log.debug((u"Publish node deleted")) 932 log.debug((u"Publish node deleted"))
903 for callback in self._getNodeCallbacks(event.nodeIdentifier, C.PS_DELETE): 933 for callback in self._getNodeCallbacks(event.nodeIdentifier, C.PS_DELETE):
904 callback(self.parent, event) 934 callback(self.parent, event)
935 client = self.parent
936 if (event.sender, event.nodeIdentifier) in client.pubsub_watching:
937 self.host.bridge.psEventRaw(event.sender.full(), event.nodeIdentifier, C.PS_DELETE, [], client.profile)
905 938
906 def subscriptions(self, service, nodeIdentifier, sender=None): 939 def subscriptions(self, service, nodeIdentifier, sender=None):
907 """Return the list of subscriptions to the given service and node. 940 """Return the list of subscriptions to the given service and node.
908 941
909 @param service: The publish subscribe service to retrieve the subscriptions from. 942 @param service: The publish subscribe service to retrieve the subscriptions from.