Ignore:
Timestamp:
Jan 5, 2010, 2:55:40 PM (12 years ago)
Author:
Ralph Meijer <ralphm@…>
Branch:
default
Message:

Add support for pubsub subscription identifiers

File:
1 edited

Legend:

Unmodified
Added
Removed
  • wokkel/pubsub.py

    r83 r84  
    103103    A subscription to a node.
    104104
    105     @ivar nodeIdentifier: The identifier of the node subscribed to.
    106                           The root node is denoted by C{None}.
     105    @ivar nodeIdentifier: The identifier of the node subscribed to.  The root
     106        node is denoted by C{None}.
     107    @type nodeIdentifier: C{unicode}
     108
    107109    @ivar subscriber: The subscribing entity.
     110    @type subscriber: L{jid.JID}
     111
    108112    @ivar state: The subscription state. One of C{'subscribed'}, C{'pending'},
    109113                 C{'unconfigured'}.
     114    @type state: C{unicode}
     115
    110116    @ivar options: Optional list of subscription options.
    111     @type options: C{dict}.
    112     """
    113 
    114     def __init__(self, nodeIdentifier, subscriber, state, options=None):
     117    @type options: C{dict}
     118
     119    @ivar subscriptionIdentifier: Optional subscription identifier.
     120    @type subscriptionIdentifier: C{unicode}
     121    """
     122
     123    def __init__(self, nodeIdentifier, subscriber, state, options=None,
     124                       subscriptionIdentifier=None):
    115125        self.nodeIdentifier = nodeIdentifier
    116126        self.subscriber = subscriber
    117127        self.state = state
    118128        self.options = options or {}
     129        self.subscriptionIdentifier = subscriptionIdentifier
     130
     131
     132    @staticmethod
     133    def fromElement(element):
     134        return Subscription(
     135                element.getAttribute('node'),
     136                jid.JID(element.getAttribute('jid')),
     137                element.getAttribute('subscription'),
     138                subscriptionIdentifier=element.getAttribute('subid'))
     139
     140
     141    def toElement(self):
     142        """
     143        Return the DOM representation of this subscription.
     144
     145        @rtype: L{domish.Element}
     146        """
     147        element = domish.Element((None, 'subscription'))
     148        if self.nodeIdentifier:
     149            element['node'] = self.nodeIdentifier
     150        element['jid'] = unicode(self.subscriber)
     151        element['subscription'] = self.state
     152        if self.subscriptionIdentifier:
     153            element['subid'] = self.subscriptionIdentifier
     154        return element
    119155
    120156
     
    230266        'publish': ['node', 'items'],
    231267        'subscribe': ['nodeOrEmpty', 'jid', 'optionsWithSubscribe'],
    232         'unsubscribe': ['nodeOrEmpty', 'jid'],
    233         'optionsGet': ['nodeOrEmpty', 'jid'],
    234         'optionsSet': ['nodeOrEmpty', 'jid', 'options'],
     268        'unsubscribe': ['nodeOrEmpty', 'jid', 'subidOrNone'],
     269        'optionsGet': ['nodeOrEmpty', 'jid', 'subidOrNone'],
     270        'optionsSet': ['nodeOrEmpty', 'jid', 'options', 'subidOrNone'],
    235271        'subscriptions': [],
    236272        'affiliations': [],
     
    239275        'configureGet': ['nodeOrEmpty'],
    240276        'configureSet': ['nodeOrEmpty', 'configure'],
    241         'items': ['node', 'maxItems', 'itemIdentifiers'],
     277        'items': ['node', 'maxItems', 'itemIdentifiers', 'subidOrNone'],
    242278        'retract': ['node', 'itemIdentifiers'],
    243279        'purge': ['node'],
     
    430466    def _render_maxItems(self, verbElement):
    431467        """
    432         Parse maximum items into an items request.
     468        Render maximum items into an items request.
    433469        """
    434470        if self.maxItems:
    435471            verbElement['max_items'] = unicode(self.maxItems)
     472
     473
     474    def _parse_subidOrNone(self, verbElement):
     475        """
     476        Parse subscription identifier out of a request.
     477        """
     478        self.subscriptionIdentifier = verbElement.getAttribute("subid")
     479
     480
     481    def _render_subidOrNone(self, verbElement):
     482        """
     483        Render subscription identifier into a request.
     484        """
     485        if self.subscriptionIdentifier:
     486            verbElement['subid'] = self.subscriptionIdentifier
    436487
    437488
     
    730781        @param service: The publish subscribe service that keeps the node.
    731782        @type service: L{JID}
     783
    732784        @param nodeIdentifier: The identifier of the node.
    733785        @type nodeIdentifier: C{unicode}
     786
    734787        @param subscriber: The entity to subscribe to the node. This entity
    735                            will get notifications of new published items.
     788            will get notifications of new published items.
    736789        @type subscriber: L{JID}
     790
    737791        @param options: Subscription options.
    738         @type options: C{dict}.
     792        @type options: C{dict}
     793
     794        @return: Deferred that fires with L{Subscription} or errbacks with
     795            L{SubscriptionPending} or L{SubscriptionUnconfigured}.
     796        @rtype: L{defer.Deferred}
    739797        """
    740798        request = PubSubRequest('subscribe')
     
    751809
    752810        def cb(iq):
    753             subscription = iq.pubsub.subscription["subscription"]
    754 
    755             if subscription == 'pending':
    756                 raise SubscriptionPending
    757             elif subscription == 'unconfigured':
    758                 raise SubscriptionUnconfigured
     811            subscription = Subscription.fromElement(iq.pubsub.subscription)
     812
     813            if subscription.state == 'pending':
     814                raise SubscriptionPending()
     815            elif subscription.state == 'unconfigured':
     816                raise SubscriptionUnconfigured()
    759817            else:
    760818                # we assume subscription == 'subscribed'
    761819                # any other value would be invalid, but that should have
    762820                # yielded a stanza error.
    763                 return None
     821                return subscription
    764822
    765823        d = request.send(self.xmlstream)
     
    768826
    769827
    770     def unsubscribe(self, service, nodeIdentifier, subscriber, sender=None):
     828    def unsubscribe(self, service, nodeIdentifier, subscriber,
     829                          subscriptionIdentifier=None, sender=None):
    771830        """
    772831        Unsubscribe from a publish subscribe node.
     
    774833        @param service: The publish subscribe service that keeps the node.
    775834        @type service: L{JID}
     835
    776836        @param nodeIdentifier: The identifier of the node.
    777837        @type nodeIdentifier: C{unicode}
     838
    778839        @param subscriber: The entity to unsubscribe from the node.
    779840        @type subscriber: L{JID}
     841
     842        @param subscriptionIdentifier: Optional subscription identifier.
     843        @type subscriptionIdentifier: C{unicode}
    780844        """
    781845        request = PubSubRequest('unsubscribe')
     
    783847        request.nodeIdentifier = nodeIdentifier
    784848        request.subscriber = subscriber
     849        request.subscriptionIdentifier = subscriptionIdentifier
    785850        request.sender = sender
    786851        return request.send(self.xmlstream)
     
    806871
    807872
    808     def items(self, service, nodeIdentifier, maxItems=None, sender=None):
     873    def items(self, service, nodeIdentifier, maxItems=None,
     874              subscriptionIdentifier=None, sender=None):
    809875        """
    810876        Retrieve previously published items from a publish subscribe node.
     
    812878        @param service: The publish subscribe service that keeps the node.
    813879        @type service: L{JID}
     880
    814881        @param nodeIdentifier: The identifier of the node.
    815882        @type nodeIdentifier: C{unicode}
     883
    816884        @param maxItems: Optional limit on the number of retrieved items.
    817885        @type maxItems: C{int}
     886
     887        @param subscriptionIdentifier: Optional subscription identifier. In
     888            case the node has been subscribed to multiple times, this narrows
     889            the results to the specific subscription.
     890        @type subscriptionIdentifier: C{unicode}
    818891        """
    819892        request = PubSubRequest('items')
     
    822895        if maxItems:
    823896            request.maxItems = str(int(maxItems))
     897        request.subscriptionIdentifier = subscriptionIdentifier
    824898        request.sender = sender
    825899
     
    836910
    837911
    838     def getOptions(self, service, nodeIdentifier, subscriber, sender=None):
     912    def getOptions(self, service, nodeIdentifier, subscriber,
     913                         subscriptionIdentifier=None, sender=None):
    839914        """
    840915        Get subscription options.
     
    848923        @param subscriber: The entity subscribed to the node.
    849924        @type subscriber: L{JID}
     925
     926        @param subscriptionIdentifier: Optional subscription identifier.
     927        @type subscriptionIdentifier: C{unicode}
    850928
    851929        @rtype: L{data_form.Form}
     
    855933        request.nodeIdentifier = nodeIdentifier
    856934        request.subscriber = subscriber
     935        request.subscriptionIdentifier = subscriptionIdentifier
    857936        request.sender = sender
    858937
     
    869948
    870949    def setOptions(self, service, nodeIdentifier, subscriber,
    871                          options, sender=None):
     950                         options, subscriptionIdentifier=None, sender=None):
    872951        """
    873952        Set subscription options.
     
    884963        @param options: Subscription options.
    885964        @type options: C{dict}.
     965
     966        @param subscriptionIdentifier: Optional subscription identifier.
     967        @type subscriptionIdentifier: C{unicode}
    886968        """
    887969        request = PubSubRequest('optionsSet')
     
    889971        request.nodeIdentifier = nodeIdentifier
    890972        request.subscriber = subscriber
     973        request.subscriptionIdentifier = subscriptionIdentifier
    891974        request.sender = sender
    892975
     
    10931176    def _toResponse_subscribe(self, result, resource, request):
    10941177        response = domish.Element((NS_PUBSUB, "pubsub"))
    1095         subscription = response.addElement("subscription")
    1096         if result.nodeIdentifier:
    1097             subscription["node"] = result.nodeIdentifier
    1098         subscription["jid"] = result.subscriber.full()
    1099         subscription["subscription"] = result.state
     1178        subscription = response.addChild(result.toElement())
    11001179        return response
    11011180
     
    11051184        subscriptions = response.addElement('subscriptions')
    11061185        for subscription in result:
    1107             item = subscriptions.addElement('subscription')
    1108             item['node'] = subscription.nodeIdentifier
    1109             item['jid'] = subscription.subscriber.full()
    1110             item['subscription'] = subscription.state
     1186            subscriptions.addChild(subscription.toElement())
    11111187        return response
    11121188
Note: See TracChangeset for help on using the changeset viewer.