comparison wokkel/pubsub.py @ 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
comparison
equal deleted inserted replaced
39:2cc92af0e13a 40:03224edb88af
157 157
158 @ivar subscriber: The subscribing entity. 158 @ivar subscriber: The subscribing entity.
159 @type subscriber: L{jid.JID} 159 @type subscriber: L{jid.JID}
160 160
161 @ivar state: The subscription state. One of C{'subscribed'}, C{'pending'}, 161 @ivar state: The subscription state. One of C{'subscribed'}, C{'pending'},
162 C{'unconfigured'}. 162 C{'unconfigured'}, C{'none'}.
163 @type state: C{unicode} 163 @type state: C{unicode}
164 164
165 @ivar options: Optional list of subscription options. 165 @ivar options: Optional list of subscription options.
166 @type options: C{dict} 166 @type options: C{dict}
167 167
340 'configureSet': ['nodeOrEmpty', 'configureOrNone'], 340 'configureSet': ['nodeOrEmpty', 'configureOrNone'],
341 'items': ['node', 'maxItems', 'itemIdentifiers', 'subidOrNone'], 341 'items': ['node', 'maxItems', 'itemIdentifiers', 'subidOrNone'],
342 'retract': ['node', 'notify', 'itemIdentifiers'], 342 'retract': ['node', 'notify', 'itemIdentifiers'],
343 'purge': ['node'], 343 'purge': ['node'],
344 'delete': ['node'], 344 'delete': ['node'],
345 'affiliationsGet': ['nodeOrEmpty'], 345 'affiliationsGet': ['node'],
346 'affiliationsSet': ['nodeOrEmpty', 'affiliations'], 346 'affiliationsSet': ['node', 'affiliations'],
347 'subscriptionsGet': ['nodeOrEmpty'], 347 'subscriptionsGet': ['node'],
348 'subscriptionsSet': [], 348 'subscriptionsSet': ['node', 'subscriptions'],
349 } 349 }
350 350
351 def __init__(self, verb=None): 351 def __init__(self, verb=None):
352 self.verb = verb 352 self.verb = verb
353 353
564 self.options = form 564 self.options = form
565 else: 565 else:
566 raise BadRequest(text=u"Unexpected form type '%s'" % form.formType) 566 raise BadRequest(text=u"Unexpected form type '%s'" % form.formType)
567 else: 567 else:
568 raise BadRequest(text="Missing options form") 568 raise BadRequest(text="Missing options form")
569
570 569
571 570
572 def _render_options(self, verbElement): 571 def _render_options(self, verbElement):
573 verbElement.addChild(self.options.toElement()) 572 verbElement.addChild(self.options.toElement())
574 573
612 except KeyError: 611 except KeyError:
613 raise BadRequest(text='Missing affiliation attribute') 612 raise BadRequest(text='Missing affiliation attribute')
614 613
615 self.affiliations[entity] = affiliation 614 self.affiliations[entity] = affiliation
616 615
616
617 def _render_affiliations(self, verbElement): 617 def _render_affiliations(self, verbElement):
618 for entity, affiliation in self.affiliations.iteritems(): 618 for entity, affiliation in self.affiliations.iteritems():
619 affiliationElement = verbElement.addElement((NS_PUBSUB_OWNER, 'affiliation')) 619 affiliationElement = verbElement.addElement((NS_PUBSUB_OWNER, 'affiliation'))
620 affiliationElement['jid'] = entity.full() 620 affiliationElement['jid'] = entity.full()
621 affiliationElement['affiliation'] = affiliation 621 affiliationElement['affiliation'] = affiliation
622
623
624 def _parse_subscriptions(self, verbElement):
625 self.subscriptions = set()
626 seen_entities = set()
627 for element in verbElement.elements():
628 if (element.uri == NS_PUBSUB_OWNER and
629 element.name == 'subscription'):
630 try:
631 subscriber = jid.internJID(element['jid']).userhostJID()
632 except KeyError:
633 raise BadRequest(text='Missing jid attribute')
634
635 if subscriber in seen_entities:
636 raise BadRequest(text='Multiple subscriptions for an subscriber')
637 seen_entities.add(subscriber)
638
639 try:
640 state = element['subscription']
641 except KeyError:
642 # ยง8.8.2.1 says that value MUST NOT be changed
643 # if subscription is missing
644 continue
645
646 self.subscriptions.add(Subscription(self.nodeIdentifier,
647 subscriber,
648 state))
649
650
651 def _render_subscriptions(self, verbElement):
652 for subscription in self.subscriptions:
653 subscriptionElement = verbElement.addElement((NS_PUBSUB_OWNER, 'subscription'))
654 subscriptionElement['jid'] = subscription.subscriber.full()
655 subscriptionElement['subscription'] = subscription.state
656
622 657
623 def _parse_notify(self, verbElement): 658 def _parse_notify(self, verbElement):
624 value = verbElement.getAttribute('notify') 659 value = verbElement.getAttribute('notify')
625 660
626 if value: 661 if value:
1457 item['affiliation'] = affiliation 1492 item['affiliation'] = affiliation
1458 1493
1459 return response 1494 return response
1460 1495
1461 1496
1497 def _toResponse_subscriptionsGet(self, result, resource, request):
1498 response = domish.Element((NS_PUBSUB, 'pubsub'))
1499 subscriptions = response.addElement('subscriptions')
1500 subscriptions['node'] = request.nodeIdentifier
1501 for subscription in result:
1502 subscription_element = subscription.toElement(NS_PUBSUB)
1503 del subscription_element['node']
1504 subscriptions.addChild(subscription_element)
1505 return response
1506
1507
1462 # public methods 1508 # public methods
1463 1509
1464 def notifyPublish(self, service, nodeIdentifier, notifications): 1510 def notifyPublish(self, service, nodeIdentifier, notifications):
1465 for subscriber, subscriptions, items in notifications: 1511 for subscriber, subscriptions, items in notifications:
1466 message = self._createNotification('items', service, 1512 message = self._createNotification('items', service,