changeset 40:03224edb88af

tmp (wokkel/pubsub): subscriptions improvments: - added "none" state to Subscription, it is needed to remove existing subscription - implemented subscriptionsGet and subscriptionsSet - replaced "nodeOrEmpty" by "node" for affiliationsGet, affiliationsSet and subscriptionsGet as node is mandatory for these commands
author Goffi <goffi@goffi.org>
date Sun, 20 Aug 2017 10:29:26 +0200
parents 2cc92af0e13a
children f9d14d3d0835
files wokkel/pubsub.py
diffstat 1 files changed, 52 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/wokkel/pubsub.py	Mon Apr 03 00:13:33 2017 +0200
+++ b/wokkel/pubsub.py	Sun Aug 20 10:29:26 2017 +0200
@@ -159,7 +159,7 @@
     @type subscriber: L{jid.JID}
 
     @ivar state: The subscription state. One of C{'subscribed'}, C{'pending'},
-                 C{'unconfigured'}.
+                 C{'unconfigured'}, C{'none'}.
     @type state: C{unicode}
 
     @ivar options: Optional list of subscription options.
@@ -342,10 +342,10 @@
         'retract': ['node', 'notify', 'itemIdentifiers'],
         'purge': ['node'],
         'delete': ['node'],
-        'affiliationsGet': ['nodeOrEmpty'],
-        'affiliationsSet': ['nodeOrEmpty', 'affiliations'],
-        'subscriptionsGet': ['nodeOrEmpty'],
-        'subscriptionsSet': [],
+        'affiliationsGet': ['node'],
+        'affiliationsSet': ['node', 'affiliations'],
+        'subscriptionsGet': ['node'],
+        'subscriptionsSet': ['node', 'subscriptions'],
     }
 
     def __init__(self, verb=None):
@@ -568,7 +568,6 @@
             raise BadRequest(text="Missing options form")
 
 
-
     def _render_options(self, verbElement):
         verbElement.addChild(self.options.toElement())
 
@@ -614,12 +613,48 @@
 
                 self.affiliations[entity] = affiliation
 
+
     def _render_affiliations(self, verbElement):
         for entity, affiliation in self.affiliations.iteritems():
             affiliationElement = verbElement.addElement((NS_PUBSUB_OWNER, 'affiliation'))
             affiliationElement['jid'] = entity.full()
             affiliationElement['affiliation'] = affiliation
 
+
+    def _parse_subscriptions(self, verbElement):
+        self.subscriptions = set()
+        seen_entities = set()
+        for element in verbElement.elements():
+            if (element.uri == NS_PUBSUB_OWNER and
+                element.name == 'subscription'):
+                try:
+                    subscriber = jid.internJID(element['jid']).userhostJID()
+                except KeyError:
+                    raise BadRequest(text='Missing jid attribute')
+
+                if subscriber in seen_entities:
+                    raise BadRequest(text='Multiple subscriptions for an subscriber')
+                seen_entities.add(subscriber)
+
+                try:
+                    state = element['subscription']
+                except KeyError:
+                    # ยง8.8.2.1 says that value MUST NOT be changed
+                    # if subscription is missing
+                    continue
+
+                self.subscriptions.add(Subscription(self.nodeIdentifier,
+                                                    subscriber,
+                                                    state))
+
+
+    def _render_subscriptions(self, verbElement):
+        for subscription in self.subscriptions:
+            subscriptionElement = verbElement.addElement((NS_PUBSUB_OWNER, 'subscription'))
+            subscriptionElement['jid'] = subscription.subscriber.full()
+            subscriptionElement['subscription'] = subscription.state
+
+
     def _parse_notify(self, verbElement):
         value = verbElement.getAttribute('notify')
 
@@ -1459,6 +1494,17 @@
         return response
 
 
+    def _toResponse_subscriptionsGet(self, result, resource, request):
+        response = domish.Element((NS_PUBSUB, 'pubsub'))
+        subscriptions = response.addElement('subscriptions')
+        subscriptions['node'] = request.nodeIdentifier
+        for subscription in result:
+            subscription_element = subscription.toElement(NS_PUBSUB)
+            del subscription_element['node']
+            subscriptions.addChild(subscription_element)
+        return response
+
+
     # public methods
 
     def notifyPublish(self, service, nodeIdentifier, notifications):