# HG changeset patch # User Ralph Meijer # Date 1146944873 0 # Node ID 753b8432460fc3e29e9b4bf8ab4f93bfe647d64c # Parent ea8b4189ae3b825372abddbf23c9862be2647a22 Work towards JEP-0060 1.8 - Remove subscription information from result. - Add handling of entity use case. - Make return instead of . - Move and to owner namespace. - Don't use 'self' in interfaces. diff -r ea8b4189ae3b -r 753b8432460f idavoll/backend.py --- a/idavoll/backend.py Tue Dec 06 15:18:30 2005 +0000 +++ b/idavoll/backend.py Sat May 06 19:47:53 2006 +0000 @@ -34,7 +34,7 @@ class IBackendService(Interface): """ Interface to a backend service of a pubsub service. """ - def __init__(self, storage): + def __init__(storage): """ @param storage: L{storage} object. """ @@ -57,7 +57,7 @@ @rtype: C{bool} """ - def get_node_type(self, node_id): + def get_node_type(node_id): """ Return type of a node. @return: a deferred that returns either 'leaf' or 'collection' @@ -69,7 +69,7 @@ @return: a deferred that returns a C{list} of node ids. """ - def get_node_meta_data(self, node_id): + def get_node_meta_data(node_id): """ Return meta data for a node. @return: a deferred that returns a C{list} of C{dict}s with the @@ -79,7 +79,7 @@ class INodeCreationService(Interface): """ A service for creating nodes """ - def create_node(self, node_id, requestor): + def create_node(node_id, requestor): """ Create a node. @return: a deferred that fires when the node has been created. @@ -88,7 +88,7 @@ class INodeDeletionService(Interface): """ A service for deleting nodes. """ - def register_pre_delete(self, pre_delete_fn): + def register_pre_delete(pre_delete_fn): """ Register a callback that is called just before a node deletion. The function C{pre_deleted_fn} is added to a list of functions @@ -107,13 +107,13 @@ deferred is returned in the list of deferreds. """ - def get_subscribers(self, node_id): + def get_subscribers(node_id): """ Get node subscriber list. @return: a deferred that fires with the list of subscribers. """ - def delete_node(self, node_id, requestor): + def delete_node(node_id, requestor): """ Delete a node. @return: a deferred that fires when the node has been deleted. @@ -122,7 +122,7 @@ class IPublishService(Interface): """ A service for publishing items to a node. """ - def publish(self, node_id, items, requestor): + def publish(node_id, items, requestor): """ Publish items to a pubsub node. @return: a deferred that fires when the items have been published. @@ -130,16 +130,16 @@ class INotificationService(Interface): """ A service for notification of published items. """ - def register_notifier(self, observerfn, *args, **kwargs): + def register_notifier(observerfn, *args, **kwargs): """ Register callback which is called for notification. """ - def get_notification_list(self, node_id, items): + def get_notification_list(node_id, items): pass class ISubscriptionService(Interface): """ A service for managing subscriptions. """ - def subscribe(self, node_id, subscriber, requestor): + def subscribe(node_id, subscriber, requestor): """ Request the subscription of an entity to a pubsub node. Depending on the node's configuration and possible business rules, the @@ -151,7 +151,7 @@ @return: a deferred that returns the subscription state """ - def unsubscribe(self, node_id, subscriber, requestor): + def unsubscribe(node_id, subscriber, requestor): """ Cancel the subscription of an entity to a pubsub node. The subscription of C{subscriber} is removed from the list of @@ -162,33 +162,42 @@ @return: a deferred that fires when unsubscription is complete. """ + def get_subscriptions(entity): + """ Report the list of current subscriptions with this pubsub service. + + Report the list of the current subscriptions with all nodes within this + pubsub service, for the C{entity}. + + @return: a deferred that returns the list of all current subscriptions + as tuples C{(node_id, subscriber, subscription)}. + """ + class IAffiliationsService(Interface): """ A service for retrieving the affiliations with this pubsub service. """ - def get_affiliations(self, entity): + def get_affiliations(entity): """ Report the list of current affiliations with this pubsub service. Report the list of the current affiliations with all nodes within this - pubsub service, along with subscriptions to such nodes, for the - C{entity}. + pubsub service, for the C{entity}. @return: a deferred that returns the list of all current affiliations - and subscriptions. + as tuples C{(node_id, affiliation)}. """ class IRetractionService(Interface): """ A service for retracting published items """ - def retract_item(self, node_id, item_id, requestor): + def retract_item(node_id, item_id, requestor): """ Removes item in node from persistent storage """ - def purge_node(self, node_id, requestor): + def purge_node(node_id, requestor): """ Removes all items in node from persistent storage """ class IItemRetrievalService(Interface): """ A service for retrieving previously published items. """ - def get_items(self, node_id, requestor, max_items=None, item_ids=[]): + def get_items(node_id, requestor, max_items=None, item_ids=[]): """ Retrieve items from persistent storage If C{max_items} is given, return the C{max_items} last published diff -r ea8b4189ae3b -r 753b8432460f idavoll/generic_backend.py --- a/idavoll/generic_backend.py Tue Dec 06 15:18:30 2005 +0000 +++ b/idavoll/generic_backend.py Sat May 06 19:47:53 2006 +0000 @@ -162,17 +162,15 @@ d = node.add_subscription(subscriber, 'subscribed') d.addCallback(lambda _: 'subscribed') d.addErrback(self._get_subscription, node, subscriber) - d.addCallback(self._return_subscription, affiliation, node.id) + d.addCallback(self._return_subscription, node.id) return d def _get_subscription(self, failure, node, subscriber): failure.trap(storage.SubscriptionExists) return node.get_subscription(subscriber) - def _return_subscription(self, result, affiliation, node_id): - return {'affiliation': affiliation, - 'node': node_id, - 'state': result} + def _return_subscription(self, result, node_id): + return node_id, result def unsubscribe(self, node_id, subscriber, requestor): if subscriber.userhostJID() != requestor: @@ -182,6 +180,9 @@ d.addCallback(lambda node: node.remove_subscription(subscriber)) return d + def get_subscriptions(self, entity): + return self.parent.storage.get_subscriptions(entity) + class NodeCreationService(service.Service): implements(backend.INodeCreationService) @@ -246,37 +247,7 @@ implements(backend.IAffiliationsService) def get_affiliations(self, entity): - d1 = self.parent.storage.get_affiliations(entity) - d2 = self.parent.storage.get_subscriptions(entity) - d = defer.DeferredList([d1, d2], fireOnOneErrback=1, consumeErrors=1) - d.addErrback(lambda x: x.value[0]) - d.addCallback(self._affiliations_result, entity) - return d - - def _affiliations_result(self, result, entity): - affiliations = result[0][1] - subscriptions = result[1][1] - - new_affiliations = {} - - for node, affiliation in affiliations: - new_affiliations[(node, entity.full())] = {'node': node, - 'jid': entity, - 'affiliation': affiliation, - 'subscription': None - } - - for node, subscriber, subscription in subscriptions: - key = node, subscriber.full() - if new_affiliations.has_key(key): - new_affiliations[key]['subscription'] = subscription - else: - new_affiliations[key] = {'node': node, - 'jid': subscriber, - 'affiliation': None, - 'subscription': subscription} - - return new_affiliations.values() + return self.parent.storage.get_affiliations(entity) class ItemRetrievalService(service.Service): diff -r ea8b4189ae3b -r 753b8432460f idavoll/pubsub.py --- a/idavoll/pubsub.py Tue Dec 06 15:18:30 2005 +0000 +++ b/idavoll/pubsub.py Sat May 06 19:47:53 2006 +0000 @@ -39,11 +39,12 @@ PUBSUB_OPTIONS_SET = PUBSUB_SET + '/options' PUBSUB_CONFIGURE_GET = PUBSUB_OWNER_GET + '/configure' PUBSUB_CONFIGURE_SET = PUBSUB_OWNER_SET + '/configure' +PUBSUB_SUBSCRIPTIONS = PUBSUB_GET + '/subscriptions' PUBSUB_AFFILIATIONS = PUBSUB_GET + '/affiliations' PUBSUB_ITEMS = PUBSUB_GET + '/items' PUBSUB_RETRACT = PUBSUB_SET + '/retract' -PUBSUB_PURGE = PUBSUB_SET + '/purge' -PUBSUB_DELETE = PUBSUB_SET + '/delete' +PUBSUB_PURGE = PUBSUB_OWNER_SET + '/purge' +PUBSUB_DELETE = PUBSUB_OWNER_SET + '/delete' class Error(Exception): pubsub_error = None @@ -270,12 +271,14 @@ xmlstream.addObserver(PUBSUB_UNSUBSCRIBE, self.onUnsubscribe) xmlstream.addObserver(PUBSUB_OPTIONS_GET, self.onOptionsGet) xmlstream.addObserver(PUBSUB_OPTIONS_SET, self.onOptionsSet) + xmlstream.addObserver(PUBSUB_SUBSCRIPTIONS, self.onSubscriptions) def get_disco_info(self, node): info = [] if not node: info.append(disco.Feature(NS_PUBSUB + '#subscribe')) + info.append(disco.Feature(NS_PUBSUB + '#retrieve-subscriptions')) return defer.succeed(info) @@ -295,12 +298,13 @@ return d def return_subscription(self, result, subscriber): + node, state = result + reply = domish.Element((NS_PUBSUB, "pubsub")) - entity = reply.addElement("entity") - entity["node"] = result["node"] - entity["jid"] = subscriber.full() - entity["affiliation"] = result["affiliation"] or 'none' - entity["subscription"] = result["state"] + subscription = reply.addElement("subscription") + subscription["node"] = nod + subscription["jid"] = subscriber.full() + subscription["subscription"] = state return [reply] def onUnsubscribe(self, iq): @@ -328,6 +332,25 @@ def _onOptionsSet(self, iq): raise OptionsUnavailable + def onSubscriptions(self, iq): + self.handler_wrapper(self._onSubscriptions, iq) + + def _onSubscriptions(self, iq): + entity = jid.internJID(iq["from"]).userhostJID() + d = self.backend.get_subscriptions(entity) + d.addCallback(self._return_subscriptions_response, iq) + return d + + def _return_subscriptions_response(self, result, iq): + reply = domish.Element((NS_PUBSUB, 'pubsub')) + subscriptions = reply.addElement('subscriptions') + for node, subscriber, state in result: + item = subscriptions.addElement('subscription') + item['node'] = node + item['jid'] = subscriber.full() + item['subscription'] = state + return [reply] + components.registerAdapter(ComponentServiceFromSubscriptionService, backend.ISubscriptionService, component.IService) @@ -472,12 +495,10 @@ def _return_affiliations_response(self, result, iq): reply = domish.Element((NS_PUBSUB, 'pubsub')) affiliations = reply.addElement('affiliations') - for r in result: - entity = affiliations.addElement('entity') - entity['node'] = r['node'] - entity['jid'] = r['jid'].full() - entity['affiliation'] = r['affiliation'] or 'none' - entity['subscription'] = r['subscription'] or 'none' + for node, affiliation in result: + item = affiliations.addElement('affiliation') + item['node'] = node + item['affiliation'] = affiliation return [reply] components.registerAdapter(ComponentServiceFromAffiliationsService,