Changeset 4:c8c73d9e5496 in ralphm-patches


Ignore:
Timestamp:
Mar 23, 2009, 9:42:55 PM (12 years ago)
Author:
Ralph Meijer <ralphm@…>
Branch:
default
Message:

Save bunch of work.

Files:
1 added
3 edited

Legend:

Unmodified
Added
Removed
  • pubsub_client_sender.patch

    r3 r4  
    1 diff -r 52898d5828ee wokkel/pubsub.py
    2 --- a/wokkel/pubsub.py  Thu Mar 05 19:41:28 2009 +0100
    3 +++ b/wokkel/pubsub.py  Fri Mar 06 21:15:35 2009 +0100
    4 @@ -150,8 +150,11 @@
    5                     C{verb}.
    6      """
    7  
    8 -    def __init__(self, xs, verb, namespace=NS_PUBSUB, method='set'):
    9 +    def __init__(self, xs, verb, namespace=NS_PUBSUB, method='set',
    10 +                       sender=None):
    11          xmlstream.IQ.__init__(self, xs, method)
    12 +        if sender:
    13 +            self['from'] = sender.full()
    14          self.addElement((namespace, 'pubsub'))
    15  
    16          self.command = self.pubsub.addElement(verb)
    17 @@ -295,7 +298,7 @@
     1diff -r 8be0600d2c32 wokkel/pubsub.py
     2--- a/wokkel/pubsub.py  Mon Mar 23 09:00:16 2009 +0100
     3+++ b/wokkel/pubsub.py  Mon Mar 23 09:00:24 2009 +0100
     4@@ -605,7 +605,7 @@
    185         pass
    196 
     
    2411         Create a publish subscribe node.
    2512 
    26 @@ -306,7 +309,7 @@
    27          """
    28  
    29  
    30 -        request = _PubSubRequest(self.xmlstream, 'create')
    31 +        request = _PubSubRequest(self.xmlstream, 'create', sender=sender)
    32          if nodeIdentifier:
    33              request.command['node'] = nodeIdentifier
    34  
    35 @@ -321,7 +324,7 @@
    36          return request.send(service).addCallback(cb)
     13@@ -617,6 +617,7 @@
     14         request = PubSubRequest('create')
     15         request.recipient = service
     16         request.nodeIdentifier = nodeIdentifier
     17+        request.sender = sender
     18 
     19         def cb(iq):
     20             try:
     21@@ -631,7 +632,7 @@
     22         return d
    3723 
    3824 
     
    4228         Delete a publish subscribe node.
    4329 
    44 @@ -330,12 +333,13 @@
    45          @param nodeIdentifier: The identifier of the node.
    46          @type nodeIdentifier: C{unicode}
    47          """
    48 -        request = _PubSubRequest(self.xmlstream, 'delete', NS_PUBSUB_OWNER)
    49 +        request = _PubSubRequest(self.xmlstream, 'delete', NS_PUBSUB_OWNER,
    50 +                                 sender=None)
    51          request.command['node'] = nodeIdentifier
    52          return request.send(service)
     30@@ -643,10 +644,11 @@
     31         request = PubSubRequest('delete')
     32         request.recipient = service
     33         request.nodeIdentifier = nodeIdentifier
     34+        request.sender = sender
     35         return request.send(self.xmlstream)
    5336 
    5437 
     
    5841         Subscribe to a publish subscribe node.
    5942 
    60 @@ -347,7 +351,7 @@
    61                             will get notifications of new published items.
    62          @type subscriber: L{JID}
    63          """
    64 -        request = _PubSubRequest(self.xmlstream, 'subscribe')
    65 +        request = _PubSubRequest(self.xmlstream, 'subscribe', sender=sender)
    66          if nodeIdentifier:
    67              request.command['node'] = nodeIdentifier
    68          request.command['jid'] = subscriber.full()
    69 @@ -368,7 +372,7 @@
    70          return request.send(service).addCallback(cb)
     43@@ -662,6 +664,7 @@
     44         request.recipient = service
     45         request.nodeIdentifier = nodeIdentifier
     46         request.subscriber = subscriber
     47+        request.sender = sender
     48 
     49         def cb(iq):
     50             subscription = iq.pubsub.subscription["subscription"]
     51@@ -681,7 +684,7 @@
     52         return d
    7153 
    7254 
     
    7658         Unsubscribe from a publish subscribe node.
    7759 
    78 @@ -379,14 +383,14 @@
    79          @param subscriber: The entity to unsubscribe from the node.
    80          @type subscriber: L{JID}
    81          """
    82 -        request = _PubSubRequest(self.xmlstream, 'unsubscribe')
    83 +        request = _PubSubRequest(self.xmlstream, 'unsubscribe', sender=sender)
    84          if nodeIdentifier:
    85              request.command['node'] = nodeIdentifier
    86          request.command['jid'] = subscriber.full()
    87          return request.send(service)
     60@@ -696,10 +699,11 @@
     61         request.recipient = service
     62         request.nodeIdentifier = nodeIdentifier
     63         request.subscriber = subscriber
     64+        request.sender = sender
     65         return request.send(self.xmlstream)
    8866 
    8967 
     
    9371         Publish to a publish subscribe node.
    9472 
    95 @@ -397,7 +401,7 @@
    96          @param items: Optional list of L{Item}s to publish.
    97          @type items: C{list}
    98          """
    99 -        request = _PubSubRequest(self.xmlstream, 'publish')
    100 +        request = _PubSubRequest(self.xmlstream, 'publish', sender=sender)
    101          request.command['node'] = nodeIdentifier
    102          if items:
    103              for item in items:
    104 @@ -406,7 +410,7 @@
    105          return request.send(service)
     73@@ -714,10 +718,11 @@
     74         request.recipient = service
     75         request.nodeIdentifier = nodeIdentifier
     76         request.items = items
     77+        request.sender = sender
     78         return request.send(self.xmlstream)
    10679 
    10780 
     
    11184         Retrieve previously published items from a publish subscribe node.
    11285 
    113 @@ -417,7 +421,8 @@
    114          @param maxItems: Optional limit on the number of retrieved items.
    115          @type maxItems: C{int}
    116          """
    117 -        request = _PubSubRequest(self.xmlstream, 'items', method='get')
    118 +        request = _PubSubRequest(self.xmlstream, 'items', method='get',
    119 +                                 sender=sender)
    120          if nodeIdentifier:
    121              request.command['node'] = nodeIdentifier
     86@@ -733,6 +738,7 @@
     87         request.nodeIdentifier = nodeIdentifier
    12288         if maxItems:
     89             request.maxItems = str(int(maxItems))
     90+        request.sender = sender
     91 
     92         def cb(iq):
     93             items = []
     94diff -r 8be0600d2c32 wokkel/test/test_pubsub.py
     95--- a/wokkel/test/test_pubsub.py        Mon Mar 23 09:00:16 2009 +0100
     96+++ b/wokkel/test/test_pubsub.py        Mon Mar 23 09:00:24 2009 +0100
     97@@ -257,6 +257,22 @@
     98         return d
     99 
     100 
     101+    def test_createNodeWithSender(self):
     102+        """
     103+        Test sending create request from a specific JID.
     104+        """
     105+
     106+        d = self.protocol.createNode(JID('pubsub.example.org'), 'test',
     107+                                     sender=JID('user@example.org'))
     108+
     109+        iq = self.stub.output[-1]
     110+        self.assertEquals('user@example.org', iq['from'])
     111+
     112+        response = toResponse(iq, 'result')
     113+        self.stub.send(response)
     114+        return d
     115+
     116+
     117     def test_deleteNode(self):
     118         """
     119         Test sending delete request.
     120@@ -280,6 +296,22 @@
     121         return d
     122 
     123 
     124+    def test_deleteNodeWithSender(self):
     125+        """
     126+        Test sending delete request.
     127+        """
     128+
     129+        d = self.protocol.deleteNode(JID('pubsub.example.org'), 'test',
     130+                                     sender=JID('user@example.org'))
     131+
     132+        iq = self.stub.output[-1]
     133+        self.assertEquals('user@example.org', iq['from'])
     134+
     135+        response = toResponse(iq, 'result')
     136+        self.stub.send(response)
     137+        return d
     138+
     139+
     140     def test_publish(self):
     141         """
     142         Test sending publish request.
     143@@ -331,6 +363,23 @@
     144         return d
     145 
     146 
     147+    def test_publishWithSender(self):
     148+        """
     149+        Test sending publish request from a specific JID.
     150+        """
     151+
     152+        item = pubsub.Item()
     153+        d = self.protocol.publish(JID('pubsub.example.org'), 'test', [item],
     154+                                  JID('user@example.org'))
     155+
     156+        iq = self.stub.output[-1]
     157+        self.assertEquals('user@example.org', iq['from'])
     158+
     159+        response = toResponse(iq, 'result')
     160+        self.stub.send(response)
     161+        return d
     162+
     163+
     164     def test_subscribe(self):
     165         """
     166         Test sending subscription request.
     167@@ -400,6 +449,27 @@
     168         return d
     169 
     170 
     171+    def test_subscribeWithSender(self):
     172+        """
     173+        Test sending subscription request from a specific JID.
     174+        """
     175+        d = self.protocol.subscribe(JID('pubsub.example.org'), 'test',
     176+                                      JID('user@example.org'),
     177+                                      sender=JID('user@example.org'))
     178+
     179+        iq = self.stub.output[-1]
     180+        self.assertEquals('user@example.org', iq['from'])
     181+
     182+        response = toResponse(iq, 'result')
     183+        pubsub = response.addElement((NS_PUBSUB, 'pubsub'))
     184+        subscription = pubsub.addElement('subscription')
     185+        subscription['node'] = 'test'
     186+        subscription['jid'] = 'user@example.org'
     187+        subscription['subscription'] = 'subscribed'
     188+        self.stub.send(response)
     189+        return d
     190+
     191+
     192     def test_unsubscribe(self):
     193         """
     194         Test sending unsubscription request.
     195@@ -423,6 +493,20 @@
     196         return d
     197 
     198 
     199+    def test_unsubscribeWithSender(self):
     200+        """
     201+        Test sending unsubscription request from a specific JID.
     202+        """
     203+        d = self.protocol.unsubscribe(JID('pubsub.example.org'), 'test',
     204+                                      JID('user@example.org'),
     205+                                      sender=JID('user@example.org'))
     206+
     207+        iq = self.stub.output[-1]
     208+        self.assertEquals('user@example.org', iq['from'])
     209+        self.stub.send(toResponse(iq, 'result'))
     210+        return d
     211+
     212+
     213     def test_items(self):
     214         """
     215         Test sending items request.
     216@@ -489,6 +573,25 @@
     217         return d
     218 
     219 
     220+    def test_itemsWithSender(self):
     221+        """
     222+        Test sending items request from a specific JID.
     223+        """
     224+
     225+        d = self.protocol.items(JID('pubsub.example.org'), 'test',
     226+                               sender=JID('user@example.org'))
     227+
     228+        iq = self.stub.output[-1]
     229+        self.assertEquals('user@example.org', iq['from'])
     230+
     231+        response = toResponse(iq, 'result')
     232+        items = response.addElement((NS_PUBSUB, 'pubsub')).addElement('items')
     233+        items['node'] = 'test'
     234+
     235+        self.stub.send(response)
     236+        return d
     237+
     238+
     239 
     240 class PubSubServiceTest(unittest.TestCase, TestableRequestHandlerMixin):
     241     """
  • pubsub_request.patch

    r1 r4  
    1111that is passed to the corresponding handler methods.
    1212
    13 diff -r fafe0148a94c wokkel/iwokkel.py
    14 --- a/wokkel/iwokkel.py Wed Feb 25 09:21:33 2009 +0100
    15 +++ b/wokkel/iwokkel.py Thu Feb 26 09:29:59 2009 +0100
     13diff -r 884ac8d88411 wokkel/generic.py
     14--- a/wokkel/generic.py Thu Mar 05 16:29:12 2009 +0100
     15+++ b/wokkel/generic.py Wed Mar 18 09:26:20 2009 +0100
     16@@ -10,7 +10,7 @@
     17 from zope.interface import implements
     18 
     19 from twisted.internet import defer
     20-from twisted.words.protocols.jabber import error
     21+from twisted.words.protocols.jabber import error, jid
     22 from twisted.words.protocols.jabber.xmlstream import toResponse
     23 from twisted.words.xish import domish, utility
     24 
     25@@ -155,3 +155,34 @@
     26         self.sink = utility.EventDispatcher()
     27         self.source.send = lambda obj: self.sink.dispatch(obj)
     28         self.sink.send = lambda obj: self.source.dispatch(obj)
     29+
     30+
     31+
     32+class Stanza(object):
     33+    """
     34+    Abstract representation of a stanza.
     35+
     36+    @ivar sender: The sending entity.
     37+    @type sender: L{jid.JID}
     38+    @ivar recipient: The receiving entity.
     39+    @type recipient: L{jid.JID}
     40+    """
     41+
     42+    sender = None
     43+    recipient = None
     44+    stanzaType = None
     45+
     46+    @classmethod
     47+    def fromElement(Class, element):
     48+        stanza = Class()
     49+        stanza.parseElement(element)
     50+        return stanza
     51+
     52+
     53+    def parseElement(self, element):
     54+        self.sender = jid.internJID(element['from'])
     55+        if element.hasAttribute('from'):
     56+            self.sender = jid.internJID(element['from'])
     57+        if element.hasAttribute('to'):
     58+            self.recipient = jid.internJID(element['to'])
     59+        self.stanzaType = element.getAttribute('type')
     60diff -r 884ac8d88411 wokkel/iwokkel.py
     61--- a/wokkel/iwokkel.py Thu Mar 05 16:29:12 2009 +0100
     62+++ b/wokkel/iwokkel.py Wed Mar 18 09:26:20 2009 +0100
    1663@@ -278,6 +278,7 @@
    1764                              C{list} of L{domish.Element})
     
    120167                  C{tuple}s of (node identifier as C{unicode}, affiliation state
    121168                  as C{str}). The affiliation can be C{'owner'}, C{'publisher'},
    122 @@ -373,23 +357,18 @@
     169@@ -373,24 +357,19 @@
    123170         @rtype: L{defer.Deferred}
    124171         """
     
    145192         @rtype: L{defer.Deferred}
    146193         """
    147 +
    148  
     194 
     195+
    149196     def getConfigurationOptions():
    150197         """
     198         Retrieve all known node configuration options.
    151199@@ -426,17 +405,13 @@
    152200         @rtype: C{dict}.
     
    292340+        @rtype: L{defer.Deferred}
    293341         """
    294 diff -r fafe0148a94c wokkel/pubsub.py
    295 --- a/wokkel/pubsub.py  Wed Feb 25 09:21:33 2009 +0100
    296 +++ b/wokkel/pubsub.py  Thu Feb 26 09:29:59 2009 +0100
     342diff -r 884ac8d88411 wokkel/pubsub.py
     343--- a/wokkel/pubsub.py  Thu Mar 05 16:29:12 2009 +0100
     344+++ b/wokkel/pubsub.py  Wed Mar 18 09:26:20 2009 +0100
     345@@ -16,7 +16,7 @@
     346 from twisted.words.protocols.jabber import jid, error, xmlstream
     347 from twisted.words.xish import domish
     348 
     349-from wokkel import disco, data_form, shim
     350+from wokkel import disco, data_form, generic, shim
     351 from wokkel.subprotocols import IQHandlerMixin, XMPPHandler
     352 from wokkel.iwokkel import IPubSubClient, IPubSubService
     353 
    297354@@ -32,42 +32,10 @@
    298355 NS_PUBSUB_NODE_CONFIG = NS_PUBSUB + "#node_config"
     
    342399 class SubscriptionPending(Exception):
    343400     """
    344 @@ -466,6 +434,219 @@
    345  
    346  
    347  
    348 +class Request(object):
    349 +    """
    350 +    An IQ request.
    351 +
    352 +    @ivar sender: The entity from which the request was received.
    353 +    @type sender: L{jid.JID}
    354 +    @ivar recipient: The entity to which the request was sent.
    355 +    @type recipient: L{jid.JID}
    356 +    """
    357 +
    358 +    sender = None
    359 +    recipient = None
    360 +    stanzaType = None
    361 +
    362 +    @classmethod
    363 +    def fromElement(Class, element):
    364 +        request = Class()
    365 +        request.parseElement(element)
    366 +        return request
    367 +
    368 +
    369 +    def parseElement(self, element):
    370 +        self.sender = jid.internJID(element['from'])
    371 +        if element.hasAttribute('from'):
    372 +            self.sender = jid.internJID(element['from'])
    373 +        if element.hasAttribute('to'):
    374 +            self.recipient = jid.internJID(element['to'])
    375 +        self.stanzaType = element.getAttribute('type')
    376 +
    377 +
    378 +
    379 +class PubSubRequest(Request):
    380 +    """
     401@@ -167,40 +135,350 @@
     402 
     403 
     404 
     405-class _PubSubRequest(xmlstream.IQ):
     406+class PubSubRequest(generic.Stanza):
     407     """
     408-    Publish subscribe request.
    381409+    A publish-subscribe request.
    382 +
     410 
     411-    @ivar verb: Request verb
     412-    @type verb: C{str}
     413-    @ivar namespace: Request namespace.
     414-    @type namespace: C{str}
     415-    @ivar method: Type attribute of the IQ request. Either C{'set'} or C{'get'}
     416-    @type method: C{str}
     417-    @ivar command: Command element of the request. This is the direct child of
     418-                   the C{pubsub} element in the C{namespace} with the name
     419-                   C{verb}.
    383420+    The set of instance variables used depends on the type of request. If
    384421+    a variable is not applicable or not passed in the request, its value is
    385422+    C{None}.
     423+
     424+    @ivar verb: The type of publish-subscribe request. See L{_requestVerbMap}.
     425+    @type verb: C{str}.
    386426+
    387427+    @ivar affiliations: Affiliations to be modified.
     
    409449+                         L{Subscription}.
    410450+    @type subscriptions: C{set}
    411 +    """
    412 +
     451     """
     452 
     453-    def __init__(self, xs, verb, namespace=NS_PUBSUB, method='set'):
     454-        xmlstream.IQ.__init__(self, xs, method)
     455-        self.addElement((namespace, 'pubsub'))
    413456+    verb = None
    414 +
     457 
     458-        self.command = self.pubsub.addElement(verb)
    415459+    affiliations = None
    416460+    items = None
     
    423467+    subscriptionIdentifier = None
    424468+    subscriptions = None
    425 +
    426 +
    427 +    _verbs = {
    428 +        ('set', NS_PUBSUB, 'publish'): ('publish', ['node', 'items']),
    429 +        ('set', NS_PUBSUB, 'subscribe'): ('subscribe', ['nodeOrEmpty', 'jid']),
    430 +        ('set', NS_PUBSUB, 'unsubscribe'): ('unsubscribe', ['node', 'jid']),
    431 +        ('get', NS_PUBSUB, 'options'): ('optionsGet', []),
    432 +        ('set', NS_PUBSUB, 'options'): ('optionsSet', []),
    433 +        ('get', NS_PUBSUB, 'subscriptions'): ('subscriptions', []),
    434 +        ('get', NS_PUBSUB, 'affiliations'): ('affiliations', []),
    435 +        ('set', NS_PUBSUB, 'create'): ('create', ['nodeOrNone']),
    436 +        ('get', NS_PUBSUB_OWNER, 'default'): ('default', ['default']),
    437 +        ('get', NS_PUBSUB_OWNER, 'configure'): ('configureGet',
    438 +                                                ['nodeOrEmpty']),
    439 +        ('set', NS_PUBSUB_OWNER, 'configure'): ('configureSet',
    440 +                                                ['nodeOrEmpty', 'configure']),
    441 +        ('get', NS_PUBSUB, 'items'): ('items', ['node', 'maxItems',
    442 +                                                'itemIdentifiers']),
    443 +        ('set', NS_PUBSUB, 'retract'): ('retract', ['node',
    444 +                                                    'itemIdentifiers']),
    445 +        ('set', NS_PUBSUB_OWNER, 'purge'): ('purge', ['node']),
    446 +        ('set', NS_PUBSUB_OWNER, 'delete'): ('delete', ['node']),
    447 +        ('get', NS_PUBSUB_OWNER, 'affiliations'): ('affiliationsGet', []),
    448 +        ('set', NS_PUBSUB_OWNER, 'affiliations'): ('affiliationsSet', []),
    449 +        ('get', NS_PUBSUB_OWNER, 'subscriptions'): ('subscriptionsGet', []),
    450 +        ('set', NS_PUBSUB_OWNER, 'subscriptions'): ('subscriptionsSet', []),
     469 
     470+    # Map request iq type and subelement name to request verb
     471+    _requestVerbMap = {
     472+        ('set', NS_PUBSUB, 'publish'): 'publish',
     473+        ('set', NS_PUBSUB, 'subscribe'): 'subscribe',
     474+        ('set', NS_PUBSUB, 'unsubscribe'): 'unsubscribe',
     475+        ('get', NS_PUBSUB, 'options'): 'optionsGet',
     476+        ('set', NS_PUBSUB, 'options'): 'optionsSet',
     477+        ('get', NS_PUBSUB, 'subscriptions'): 'subscriptions',
     478+        ('get', NS_PUBSUB, 'affiliations'): 'affiliations',
     479+        ('set', NS_PUBSUB, 'create'): 'create',
     480+        ('get', NS_PUBSUB_OWNER, 'default'): 'default',
     481+        ('get', NS_PUBSUB_OWNER, 'configure'): 'configureGet',
     482+        ('set', NS_PUBSUB_OWNER, 'configure'): 'configureSet',
     483+        ('get', NS_PUBSUB, 'items'): 'items',
     484+        ('set', NS_PUBSUB, 'retract'): 'retract',
     485+        ('set', NS_PUBSUB_OWNER, 'purge'): 'purge',
     486+        ('set', NS_PUBSUB_OWNER, 'delete'): 'delete',
     487+        ('get', NS_PUBSUB_OWNER, 'affiliations'): 'affiliationsGet',
     488+        ('set', NS_PUBSUB_OWNER, 'affiliations'): 'affiliationsSet',
     489+        ('get', NS_PUBSUB_OWNER, 'subscriptions'): 'subscriptionsGet',
     490+        ('set', NS_PUBSUB_OWNER, 'subscriptions'): 'subscriptionsSet',
    451491+    }
     492 
     493-    def send(self, to):
     494+    # Map request verb to request iq type and subelement name
     495+    _verbRequestMap = dict(((v, k) for k, v in _requestVerbMap.iteritems()))
     496+
     497+    # Map request verb to parameter handler names
     498+    _parameters = {
     499+        'publish': ['node', 'items'],
     500+        'subscribe': ['nodeOrEmpty', 'jid'],
     501+        'unsubscribe': ['nodeOrEmpty', 'jid'],
     502+        'optionsGet': [],
     503+        'optionsSet': [],
     504+        'subscriptions': [],
     505+        'affiliations': [],
     506+        'create': ['nodeOrNone'],
     507+        'default': ['default'],
     508+        'configureGet': ['nodeOrEmpty'],
     509+        'configureSet': ['nodeOrEmpty', 'configure'],
     510+        'items': ['node', 'maxItems', 'itemIdentifiers'],
     511+        'retract': ['node', 'itemIdentifiers'],
     512+        'purge': ['node'],
     513+        'delete': ['node'],
     514+        'affiliationsGet': [],
     515+        'affiliationsSet': [],
     516+        'subscriptionsGet': [],
     517+        'subscriptionsSet': [],
     518+    }
     519+
     520+    def __init__(self, verb=None):
     521+        self.verb = verb
     522+
    452523+
    453524+    @staticmethod
    454525+    def _findForm(element, formNamespace):
     526         """
     527-        Send out request.
     528+        Find a Data Form.
     529 
     530-        Extends L{xmlstream.IQ.send} by requiring the C{to} parameter to be
     531-        a L{JID} instance.
     532+        Look for an element that represents a Data Form with the specified
     533+        form namespace as a child element of the given element.
     534+        """
    455535+        if not element:
    456536+            return None
    457 +
     537 
     538-        @param to: Entity to send the request to.
     539-        @type to: L{JID}
    458540+        form = None
    459541+        for child in element.elements():
     
    470552+
    471553+    def _parse_node(self, verbElement):
     554         """
     555-        destination = to.full()
     556-        return xmlstream.IQ.send(self, destination)
     557+        Parse the required node identifier out of the verbElement.
     558+        """
    472559+        try:
    473560+            self.nodeIdentifier = verbElement["node"]
     
    476563+
    477564+
     565+    def _render_node(self, verbElement):
     566+        """
     567+        Render the required node identifier on the verbElement.
     568+        """
     569+        if not self.nodeIdentifier:
     570+            raise Exception("Node identifier is required")
     571+
     572+        verbElement['node'] = self.nodeIdentifier
     573+
     574+
    478575+    def _parse_nodeOrEmpty(self, verbElement):
     576+        """
     577+        Parse the node identifier out of the verbElement. May be empty.
     578+        """
    479579+        self.nodeIdentifier = verbElement.getAttribute("node", '')
    480580+
    481581+
     582+    def _render_nodeOrEmpty(self, verbElement):
     583+        """
     584+        Render the node identifier on the verbElement. May be empty.
     585+        """
     586+        if self.nodeIdentifier:
     587+            verbElement['node'] = self.nodeIdentifier
     588+
     589+
    482590+    def _parse_nodeOrNone(self, verbElement):
     591+        """
     592+        Parse the optional node identifier out of the verbElement.
     593+        """
    483594+        self.nodeIdentifier = verbElement.getAttribute("node")
    484595+
    485596+
     597+    def _render_nodeOrNone(self, verbElement):
     598+        """
     599+        Render the optional node identifier on the verbElement.
     600+        """
     601+        if self.nodeIdentifier:
     602+            verbElement['node'] = self.nodeIdentifier
     603+
     604+
    486605+    def _parse_items(self, verbElement):
     606+        """
     607+        Parse items out of the verbElement for publish requests.
     608+        """
    487609+        self.items = []
    488610+        for element in verbElement.elements():
     
    491613+
    492614+
     615+    def _render_items(self, verbElement):
     616+        """
     617+        Render items into the verbElement for publish requests.
     618+        """
     619+        if self.items:
     620+            for item in self.items:
     621+                verbElement.addChild(item)
     622+
     623+
    493624+    def _parse_jid(self, verbElement):
     625+        """
     626+        Parse subscriber out of the verbElement for un-/subscribe requests.
     627+        """
    494628+        try:
    495629+            self.subscriber = jid.internJID(verbElement["jid"])
     
    498632+
    499633+
     634+    def _render_jid(self, verbElement):
     635+        """
     636+        Render subscriber into the verbElement for un-/subscribe requests.
     637+        """
     638+        verbElement['jid'] = self.subscriber.full()
     639+
     640+
    500641+    def _parse_default(self, verbElement):
     642+        """
     643+        Parse node type out of a request for the default node configuration.
     644+        """
    501645+        form = PubSubRequest._findForm(verbElement, NS_PUBSUB_NODE_CONFIG)
    502646+        if form and form.formType == 'submit':
     
    508652+
    509653+    def _parse_configure(self, verbElement):
     654+        """
     655+        Parse options out of a request for setting the node configuration.
     656+        """
    510657+        form = PubSubRequest._findForm(verbElement, NS_PUBSUB_NODE_CONFIG)
    511658+        if form:
     
    522669+
    523670+    def _parse_itemIdentifiers(self, verbElement):
     671+        """
     672+        Parse item identifiers out of items and retract requests.
     673+        """
    524674+        self.itemIdentifiers = []
    525675+        for element in verbElement.elements():
     
    531681+
    532682+
     683+    def _render_itemIdentifiers(self, verbElement):
     684+        """
     685+        Render item identifiers into items and retract requests.
     686+        """
     687+        if self.itemIdentifiers:
     688+            for itemIdentifier in self.itemIdentifiers:
     689+                item = verbElement.addElement('item')
     690+                item['id'] = itemIdentifier
     691+
     692+
    533693+    def _parse_maxItems(self, verbElement):
     694+        """
     695+        Parse maximum items out of an items request.
     696+        """
    534697+        value = verbElement.getAttribute('max_items')
    535698+
     
    542705+
    543706+
     707+    def _render_maxItems(self, verbElement):
     708+        """
     709+        Parse maximum items into an items request.
     710+        """
     711+        if self.maxItems:
     712+            verbElement['max_items'] = unicode(self.maxItems)
     713+
     714+
    544715+    def parseElement(self, element):
    545 +        Request.parseElement(self, element)
     716+        """
     717+        Parse the publish-subscribe verb and parameters out of a request.
     718+        """
     719+        generic.Stanza.parseElement(self, element)
    546720+
    547721+        for child in element.pubsub.elements():
    548722+            key = (self.stanzaType, child.uri, child.name)
    549 +            self.verb, parsers = PubSubRequest._verbs.get(key)
    550 +            if self.verb:
     723+            try:
     724+                verb = self._requestVerbMap[key]
     725+            except KeyError:
     726+                continue
     727+            else:
     728+                self.verb = verb
    551729+                break
    552730+
     
    554732+            raise NotImplementedError()
    555733+
    556 +        for parser in parsers:
    557 +            getattr(self, '_parse_%s' % parser)(child)
    558 +
    559 +
    560 +
    561  class PubSubService(XMPPHandler, IQHandlerMixin):
    562      """
    563      Protocol implementation for a XMPP Publish Subscribe Service.
    564 @@ -497,27 +678,7 @@
     734+        for parameter in self._parameters[verb]:
     735+            getattr(self, '_parse_%s' % parameter)(child)
     736+
     737+
     738+    def send(self, xs):
     739+        """
     740+        Send this request to its recipient.
     741+
     742+        This renders all of the relevant parameters for this specific
     743+        requests into an L{xmlstream.IQ}, and invoke its C{send} method.
     744+        This returns a deferred that fires upon reception of a response. See
     745+        L{xmlstream.IQ} for details.
     746+
     747+        @param xs: The XML stream to send the request on.
     748+        @type xs: L{xmlstream.XmlStream}
     749+        @rtype: L{defer.Deferred}.
     750+        """
     751+
     752+        try:
     753+            (self.stanzaType,
     754+             childURI,
     755+             childName) = self._verbRequestMap[self.verb]
     756+        except KeyError:
     757+            raise NotImplementedError()
     758+
     759+        iq = xmlstream.IQ(xs, self.stanzaType)
     760+        iq.addElement((childURI, 'pubsub'))
     761+        verbElement = iq.pubsub.addElement(childName)
     762+
     763+        if self.sender:
     764+            iq['from'] = self.sender.full()
     765+        if self.recipient:
     766+            iq['to'] = self.recipient.full()
     767+
     768+        for parameter in self._parameters[self.verb]:
     769+            getattr(self, '_render_%s' % parameter)(verbElement)
     770+
     771+        return iq.send()
     772 
     773 
     774 
     775@@ -336,11 +614,9 @@
     776         @param nodeIdentifier: Optional suggestion for the id of the node.
     777         @type nodeIdentifier: C{unicode}
     778         """
     779-
     780-
     781-        request = _PubSubRequest(self.xmlstream, 'create')
     782-        if nodeIdentifier:
     783-            request.command['node'] = nodeIdentifier
     784+        request = PubSubRequest('create')
     785+        request.recipient = service
     786+        request.nodeIdentifier = nodeIdentifier
     787 
     788         def cb(iq):
     789             try:
     790@@ -350,7 +626,9 @@
     791                 new_node = nodeIdentifier
     792             return new_node
     793 
     794-        return request.send(service).addCallback(cb)
     795+        d = request.send(self.xmlstream)
     796+        d.addCallback(cb)
     797+        return d
     798 
     799 
     800     def deleteNode(self, service, nodeIdentifier):
     801@@ -362,9 +640,10 @@
     802         @param nodeIdentifier: The identifier of the node.
     803         @type nodeIdentifier: C{unicode}
     804         """
     805-        request = _PubSubRequest(self.xmlstream, 'delete', NS_PUBSUB_OWNER)
     806-        request.command['node'] = nodeIdentifier
     807-        return request.send(service)
     808+        request = PubSubRequest('delete')
     809+        request.recipient = service
     810+        request.nodeIdentifier = nodeIdentifier
     811+        return request.send(self.xmlstream)
     812 
     813 
     814     def subscribe(self, service, nodeIdentifier, subscriber):
     815@@ -379,10 +658,10 @@
     816                            will get notifications of new published items.
     817         @type subscriber: L{JID}
     818         """
     819-        request = _PubSubRequest(self.xmlstream, 'subscribe')
     820-        if nodeIdentifier:
     821-            request.command['node'] = nodeIdentifier
     822-        request.command['jid'] = subscriber.full()
     823+        request = PubSubRequest('subscribe')
     824+        request.recipient = service
     825+        request.nodeIdentifier = nodeIdentifier
     826+        request.subscriber = subscriber
     827 
     828         def cb(iq):
     829             subscription = iq.pubsub.subscription["subscription"]
     830@@ -397,7 +676,9 @@
     831                 # yielded a stanza error.
     832                 return None
     833 
     834-        return request.send(service).addCallback(cb)
     835+        d = request.send(self.xmlstream)
     836+        d.addCallback(cb)
     837+        return d
     838 
     839 
     840     def unsubscribe(self, service, nodeIdentifier, subscriber):
     841@@ -411,11 +692,11 @@
     842         @param subscriber: The entity to unsubscribe from the node.
     843         @type subscriber: L{JID}
     844         """
     845-        request = _PubSubRequest(self.xmlstream, 'unsubscribe')
     846-        if nodeIdentifier:
     847-            request.command['node'] = nodeIdentifier
     848-        request.command['jid'] = subscriber.full()
     849-        return request.send(service)
     850+        request = PubSubRequest('unsubscribe')
     851+        request.recipient = service
     852+        request.nodeIdentifier = nodeIdentifier
     853+        request.subscriber = subscriber
     854+        return request.send(self.xmlstream)
     855 
     856 
     857     def publish(self, service, nodeIdentifier, items=None):
     858@@ -429,13 +710,11 @@
     859         @param items: Optional list of L{Item}s to publish.
     860         @type items: C{list}
     861         """
     862-        request = _PubSubRequest(self.xmlstream, 'publish')
     863-        request.command['node'] = nodeIdentifier
     864-        if items:
     865-            for item in items:
     866-                request.command.addChild(item)
     867-
     868-        return request.send(service)
     869+        request = PubSubRequest('publish')
     870+        request.recipient = service
     871+        request.nodeIdentifier = nodeIdentifier
     872+        request.items = items
     873+        return request.send(self.xmlstream)
     874 
     875 
     876     def items(self, service, nodeIdentifier, maxItems=None):
     877@@ -449,11 +728,11 @@
     878         @param maxItems: Optional limit on the number of retrieved items.
     879         @type maxItems: C{int}
     880         """
     881-        request = _PubSubRequest(self.xmlstream, 'items', method='get')
     882-        if nodeIdentifier:
     883-            request.command['node'] = nodeIdentifier
     884+        request = PubSubRequest('items')
     885+        request.recipient = service
     886+        request.nodeIdentifier = nodeIdentifier
     887         if maxItems:
     888-            request.command["max_items"] = str(int(maxItems))
     889+            request.maxItems = str(int(maxItems))
     890 
     891         def cb(iq):
     892             items = []
     893@@ -462,7 +741,9 @@
     894                     items.append(element)
     895             return items
     896 
     897-        return request.send(service).addCallback(cb)
     898+        d = request.send(self.xmlstream)
     899+        d.addCallback(cb)
     900+        return d
     901 
     902 
     903 
     904@@ -497,27 +778,7 @@
    565905     implements(IPubSubService)
    566906 
     
    591931 
    592932 
    593 @@ -530,10 +691,7 @@
     933@@ -530,10 +791,7 @@
    594934 
    595935 
     
    603943 
    604944     def getDiscoInfo(self, requestor, target, nodeIdentifier):
    605 @@ -585,92 +743,17 @@
     945@@ -585,92 +843,17 @@
    606946         return d
    607947 
     
    612952+    def _onPubSubRequest(self, iq):
    613953+        request = PubSubRequest.fromElement(iq)
    614 +        handler = getattr(self, '_on_%s' % (request.verb))
     954+        handler = getattr(self, '_on_%s' % request.verb)
    615955+        return handler(request)
    616956 
     
    7031043         def toResponse(result):
    7041044             response = domish.Element((NS_PUBSUB, "pubsub"))
    705 @@ -681,28 +764,24 @@
     1045@@ -681,28 +864,24 @@
    7061046             subscription["subscription"] = result.state
    7071047             return response
     
    7381078         def toResponse(result):
    7391079             response = domish.Element((NS_PUBSUB, 'pubsub'))
    740 @@ -714,13 +793,12 @@
     1080@@ -714,13 +893,12 @@
    7411081                 item['subscription'] = subscription.state
    7421082             return response
     
    7541094         def toResponse(result):
    7551095             response = domish.Element((NS_PUBSUB, 'pubsub'))
    756 @@ -733,17 +811,15 @@
     1096@@ -733,17 +911,15 @@
    7571097 
    7581098             return response
     
    7751115                 create = response.addElement('create')
    7761116                 create['node'] = result
    777 @@ -751,7 +827,7 @@
     1117@@ -751,7 +927,7 @@
    7781118             else:
    7791119                 return None
     
    7841124         return d
    7851125 
    786 @@ -771,6 +847,7 @@
     1126@@ -771,6 +947,7 @@
    7871127             fields.append(data_form.Field.fromDict(option))
    7881128         return fields
     
    7921132         options = self.getConfigurationOptions()
    7931133         fields = self._makeFields(options, values)
    794 @@ -779,6 +856,7 @@
    795                                fields=fields)
     1134@@ -780,6 +957,7 @@
    7961135 
    7971136         return form
    798 +
    799  
     1137 
     1138+
    8001139     def _checkConfiguration(self, values):
    8011140         options = self.getConfigurationOptions()
    802 @@ -805,8 +883,7 @@
     1141         processedValues = {}
     1142@@ -805,8 +983,7 @@
    8031143         return processedValues
    8041144 
     
    8101150         def toResponse(options):
    8111151             response = domish.Element((NS_PUBSUB_OWNER, "pubsub"))
    812 @@ -814,127 +891,82 @@
     1152@@ -814,127 +991,82 @@
    8131153             default.addChild(self._formFromConfiguration(options).toElement())
    8141154             return response
     
    9651305 
    9661306     # public methods
    967 @@ -990,27 +1022,27 @@
     1307@@ -990,27 +1122,27 @@
    9681308         return []
    9691309 
     
    9991339 
    10001340 
    1001 @@ -1018,30 +1050,29 @@
     1341@@ -1018,30 +1150,29 @@
    10021342         return {}
    10031343 
     
    10371377+    def delete(self, request):
    10381378         raise Unsupported('delete-nodes')
    1039 diff -r fafe0148a94c wokkel/test/test_pubsub.py
    1040 --- a/wokkel/test/test_pubsub.py        Wed Feb 25 09:21:33 2009 +0100
    1041 +++ b/wokkel/test/test_pubsub.py        Thu Feb 26 09:29:59 2009 +0100
     1379diff -r 884ac8d88411 wokkel/test/test_pubsub.py
     1380--- a/wokkel/test/test_pubsub.py        Thu Mar 05 16:29:12 2009 +0100
     1381+++ b/wokkel/test/test_pubsub.py        Wed Mar 18 09:26:20 2009 +0100
    10421382@@ -507,6 +507,29 @@
    10431383         verify.verifyObject(iwokkel.IPubSubService, self.service)
     
    10701410         """
    10711411         Test getDiscoInfo calls getNodeInfo and returns some minimal info.
    1072 @@ -561,24 +584,178 @@
     1412@@ -561,20 +584,149 @@
    10731413         </iq>
    10741414         """
     
    10891429+        verify.verifyObject(iwokkel.IPubSubService, self.service)
    10901430         return self.handleRequest(xml)
    1091 +
    1092 +
     1431 
     1432 
    10931433+    def test_onPublishItems(self):
    10941434+        """
     
    12171557+        d.addCallback(cb)
    12181558+        return d
    1219  
    1220  
     1559+
     1560+
    12211561     def test_onOptionsGet(self):
    12221562         """
     
    12261566 
    12271567         xml = """
    1228          <iq type='get' to='pubsub.example.org'
     1568@@ -597,6 +749,31 @@
     1569         return d
     1570 
     1571 
     1572+    def test_onOptionsSet(self):
     1573+        """
     1574+        Setting subscription options is not supported.
     1575+        """
     1576+
     1577+        xml = """
     1578+        <iq type='set' to='pubsub.example.org'
    12291579+                       from='user@example.org'>
    12301580+          <pubsub xmlns='http://jabber.org/protocol/pubsub'>
     
    12451595+
    12461596+
    1247 +    def test_onOptionsSet(self):
    1248 +        """
    1249 +        Setting subscription options is not supported.
    1250 +        """
    1251 +
    1252 +        xml = """
    1253 +        <iq type='set' to='pubsub.example.org'
    1254                         from='user@example.org'>
    1255            <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    1256              <options/>
     1597     def test_onSubscriptions(self):
     1598         """
     1599         A subscriptions request should result in
    12571600@@ -627,14 +804,149 @@
    12581601             self.assertEqual('subscribed', subscription['subscription'])
     
    14231766 
    14241767         def cb(element):
    1425 @@ -682,6 +994,95 @@
    1426          self.service.getDefaultConfiguration = getDefaultConfiguration
    1427          verify.verifyObject(iwokkel.IPubSubService, self.service)
    1428          d = self.handleRequest(xml)
    1429 +        d.addCallback(cb)
    1430 +        return d
    1431 +
    1432 +
     1768@@ -686,6 +998,95 @@
     1769         return d
     1770 
     1771 
    14331772+    def test_onDefaultCollection(self):
    14341773+        """
     
    15161855+        d = self.handleRequest(xml)
    15171856+        self.assertFailure(d, error.StanzaError)
    1518          d.addCallback(cb)
    1519          return d
    1520  
     1857+        d.addCallback(cb)
     1858+        return d
     1859+
     1860+
     1861     def test_onConfigureGet(self):
     1862         """
     1863         On a node configuration get request L{PubSubService.getConfiguration}
    15211864@@ -714,14 +1115,15 @@
    15221865                      "label": "Owner of the node"}
     
    15891932 
    15901933 
    1591 @@ -862,12 +1270,45 @@
     1934@@ -862,14 +1270,47 @@
    15921935                      "label": "Deliver payloads with event notifications"}
    15931936                 }
     
    16031946+        verify.verifyObject(iwokkel.IPubSubService, self.service)
    16041947         return self.handleRequest(xml)
    1605 +
    1606 +
     1948 
     1949 
    16071950+    def test_onConfigureSetBadFormType(self):
    16081951+        """
     
    16341977+        d.addCallback(cb)
    16351978+        return d
    1636  
    1637  
     1979+
     1980+
    16381981     def test_onItems(self):
     1982         """
     1983         On a items request, return all items for the given node.
    16391984@@ -883,12 +1324,12 @@
    16401985         </iq>
  • series

    r3 r4  
    33component_multiple.patch
    44pubsub_client_sender.patch
     5pubsub_resource.patch
    56compat-pre-twisted-8.0.0.patch
    67release-0.5.patch
Note: See TracChangeset for help on using the changeset viewer.