# HG changeset patch # User Goffi # Date 1503217913 -7200 # Node ID b1bbd2994cebd1e754e443befa4bc9df8186291b # Parent 3399971f0aa0b051eaa9f6b882da1682346d15df plugin XEP-0060: implemented subscriptions management method for node owner: added getNodeSubscriptions and setNodeSubscriptions and their bridge method (psNodeSubscriptionsGet and psNodeSubscriptionsSet) diff -r 3399971f0aa0 -r b1bbd2994ceb src/plugins/plugin_xep_0060.py --- a/src/plugins/plugin_xep_0060.py Sun Aug 20 10:29:26 2017 +0200 +++ b/src/plugins/plugin_xep_0060.py Sun Aug 20 10:31:53 2017 +0200 @@ -88,9 +88,11 @@ host.bridge.addMethod("psNodeCreate", ".plugin", in_sign='ssa{ss}s', out_sign='s', method=self._createNode, async=True) host.bridge.addMethod("psNodeConfigurationGet", ".plugin", in_sign='sss', out_sign='a{ss}', method=self._getNodeConfiguration, async=True) host.bridge.addMethod("psNodeConfigurationSet", ".plugin", in_sign='ssa{ss}s', out_sign='', method=self._setNodeConfiguration, async=True) - host.bridge.addMethod("psAffiliationsGet", ".plugin", in_sign='sss', out_sign='a{ss}', method=self._getAffiliations, async=True) host.bridge.addMethod("psNodeAffiliationsGet", ".plugin", in_sign='sss', out_sign='a{ss}', method=self._getNodeAffiliations, async=True) 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("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) @@ -663,6 +665,58 @@ # subscribe # + def _getNodeSubscriptions(self, service_s, nodeIdentifier, profile_key): + client = self.host.getClient(profile_key) + d = self.getNodeSubscriptions(client, jid.JID(service_s) if service_s else None, nodeIdentifier) + d.addCallback(lambda subscriptions: {j.full(): a for j, a in subscriptions.iteritems()}) + return d + + def getNodeSubscriptions(self, client, service, nodeIdentifier): + """Retrieve subscriptions to a node + + @param nodeIdentifier(unicode): node to get subscriptions from + """ + if not nodeIdentifier: + raise exceptions.DataError("node identifier can't be empty") + request = pubsub.PubSubRequest('subscriptionsGet') + request.recipient = service + request.nodeIdentifier = nodeIdentifier + + def cb(iq_elt): + try: + subscriptions_elt = next(iq_elt.pubsub.elements((pubsub.NS_PUBSUB, 'subscriptions'))) + except StopIteration: + raise ValueError(_(u"Invalid result: missing element: {}").format(iq_elt.toXml)) + except AttributeError as e: + raise ValueError(_(u"Invalid result: {}").format(e)) + try: + return {jid.JID(s['jid']): s['subscription'] for s in subscriptions_elt.elements((pubsub.NS_PUBSUB, 'subscription'))} + except KeyError: + raise ValueError(_(u"Invalid result: bad element: {}").format(iq_elt.toXml)) + + d = request.send(client.xmlstream) + d.addCallback(cb) + return d + + def _setNodeSubscriptions(self, service_s, nodeIdentifier, subscriptions, profile_key=C.PROF_KEY_NONE): + client = self.host.getClient(profile_key) + subscriptions = {jid.JID(jid_): subscription for jid_, subscription in subscriptions.iteritems()} + d = self.setNodeSubscriptions(client, jid.JID(service_s) if service_s else None, nodeIdentifier, subscriptions) + return d + + def setNodeSubscriptions(self, client, service, nodeIdentifier, subscriptions): + """Set or update subscriptions of a node owned by profile + + @param subscriptions(dict[jid.JID, unicode]): subscriptions to set + check https://xmpp.org/extensions/xep-0060.html#substates for a list of possible subscriptions + """ + request = pubsub.PubSubRequest('subscriptionsSet') + request.recipient = service + request.nodeIdentifier = nodeIdentifier + request.subscriptions = {pubsub.Subscription(nodeIdentifier, jid_, state) for jid_, state in subscriptions.iteritems()} + d = request.send(client.xmlstream) + return d + def _manySubscribeRTResult(self, session_id, profile_key=C.PROF_KEY_DEFAULT): """Get real-time results for subcribeToManu session