changeset 2203:427391c706eb

plugin XEP-0060: added affiliation handling: New methods getAffiliations (for checking affiliation by any entity) and getNodeAffiliations (for checking the affiliations of a node, for the owner), and theirs corresponding bridge methods.
author Goffi <goffi@goffi.org>
date Thu, 23 Mar 2017 21:01:51 +0100
parents 7f91b894bfdf
children afc703419186
files src/plugins/plugin_xep_0060.py
diffstat 1 files changed, 57 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/src/plugins/plugin_xep_0060.py	Thu Mar 23 20:59:25 2017 +0100
+++ b/src/plugins/plugin_xep_0060.py	Thu Mar 23 21:01:51 2017 +0100
@@ -88,6 +88,8 @@
         self.rt_sessions = sat_defer.RTDeferredSessions()
         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("psDeleteNode", ".plugin", in_sign='sss', out_sign='', method=self._deleteNode, async=True)
         host.bridge.addMethod("psItemGet", ".plugin", in_sign='ssiassa{ss}s', out_sign='(asa{ss})', method=self._getItems, async=True)
         host.bridge.addMethod("psRetractItem", ".plugin", in_sign='sssbs', out_sign='', method=self._retractItem, async=True)
@@ -436,6 +438,60 @@
         d = request.send(client.xmlstream)
         return d
 
+    def _getAffiliations(self, service_s, nodeIdentifier, profile_key):
+        client = self.host.getClient(profile_key)
+        d = self.getAffiliations(client, jid.JID(service_s) if service_s else None, nodeIdentifier or None)
+        return d
+
+    def getAffiliations(self, client, service, nodeIdentifier=None):
+        """Retrieve affiliations of an entity
+
+        @param nodeIdentifier(unicode, None): node to get affiliation from
+            None to get all nodes affiliations for this service
+        """
+        request = pubsub.PubSubRequest('affiliations')
+        request.recipient = service
+        request.nodeIdentifier = nodeIdentifier
+
+        def cb(iq_elt):
+            try:
+                affiliations_elt = next(iq_elt.pubsub.elements((pubsub.NS_PUBSUB, 'affiliations')))
+            except StopIteration:
+                raise ValueError(_(u"Invalid result: missing <affiliations> element: {}").format(iq_elt.toXml))
+            try:
+                return {e['node']: e['affiliation'] for e in affiliations_elt.elements((pubsub.NS_PUBSUB, 'affiliation'))}
+            except KeyError:
+                raise ValueError(_(u"Invalid result: bad <affiliation> element: {}").format(iq_elt.toXml))
+
+        d = request.send(client.xmlstream)
+        d.addCallback(cb)
+        return d
+
+    def _getNodeAffiliations(self, service_s, nodeIdentifier, profile_key):
+        client = self.host.getClient(profile_key)
+        d = self.getNodeAffiliations(client, jid.JID(service_s) if service_s else None, nodeIdentifier)
+        return d
+
+    def getNodeAffiliations(self, client, service, nodeIdentifier):
+        """Retrieve affiliations of a node owned by profile"""
+        request = pubsub.PubSubRequest('affiliationsGet')
+        request.recipient = service
+        request.nodeIdentifier = nodeIdentifier
+
+        def cb(iq_elt):
+            try:
+                affiliations_elt = next(iq_elt.pubsub.elements((pubsub.NS_PUBSUB_OWNER, 'affiliations')))
+            except StopIteration:
+                raise ValueError(_(u"Invalid result: missing <affiliations> element: {}").format(iq_elt.toXml))
+            try:
+                return {e['jid']: e['affiliation'] for e in affiliations_elt.elements((pubsub.NS_PUBSUB_OWNER, 'affiliation'))}
+            except KeyError:
+                raise ValueError(_(u"Invalid result: bad <affiliation> element: {}").format(iq_elt.toXml))
+
+        d = request.send(client.xmlstream)
+        d.addCallback(cb)
+        return d
+
     def _deleteNode(self, service_s, nodeIdentifier, profile_key):
         return self.deleteNode(jid.JID(service_s) if service_s else None, nodeIdentifier, profile_key)
 
@@ -623,6 +679,7 @@
 
     def getFromMany(self, node_data, max_item=None, rsm_request=None, extra=None, profile_key=C.PROF_KEY_NONE):
         """Get items from many nodes at once
+
         @param node_data (iterable[tuple]): iterable of tuple (service, node) where:
             - service (jid.JID) is the pubsub service
             - node (unicode) is the node to get items from