Changeset 171:4f5ee7b81ebf for wokkel


Ignore:
Timestamp:
May 9, 2012, 2:24:28 PM (8 years ago)
Author:
Ralph Meijer <ralphm@…>
Branch:
default
Message:

Add convenience method Request.parseRequest.

The new method Request.parseRequest is called from Request.fromElement
with the child element of the iq that is passed to fromElement, providing
a convenient hook for parsing the payload of incoming requests.

Location:
wokkel
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • wokkel/generic.py

    r165 r171  
    184184    @classmethod
    185185    def fromElement(Class, element):
     186        """
     187        Create a stanza from a L{domish.Element}.
     188        """
    186189        stanza = Class()
    187190        stanza.parseElement(element)
     
    190193
    191194    def parseElement(self, element):
     195        """
     196        Parse the stanza element.
     197
     198        This is called with the stanza's element when a L{Stanza} is
     199        created using L{fromElement}. It parses the stanza's core attributes
     200        (addressing, type and id), strips the namespace from the stanza
     201        element for easier transport across streams and passes on
     202        child elements for further parsing.
     203
     204        Child element parsers are defined by providing a C{childParsers}
     205        attribute on a subclass, as a mapping from (URI, name) to the name
     206        of the handler on C{self}. C{parseElement} will accumulate
     207        C{childParsers} from its class hierarchy, iterate over the child
     208        elements and pass it to matching handlers based on the child element's
     209        URI and name. The special key of C{None} can be used to pass all
     210        child elements to.
     211        """
    192212        if element.hasAttribute('from'):
    193213            self.sender = jid.internJID(element['from'])
     
    209229                handler = handlers[child.uri, child.name]
    210230            except KeyError:
    211                 pass
    212             else:
    213                 getattr(self, handler)(child)
     231                try:
     232                    handler = handlers[None]
     233                except KeyError:
     234                    continue
     235
     236            getattr(self, handler)(child)
    214237
    215238
     
    235258
    236259
     260
    237261class Request(Stanza):
    238262    """
     
    247271    timeout = None
    248272
     273    childParsers = {None: 'parseRequest'}
     274
    249275    def __init__(self, recipient=None, sender=None, stanzaType='get'):
    250276        Stanza.__init__(self, recipient=recipient, sender=sender)
    251277        self.stanzaType = stanzaType
     278
     279
     280    def parseRequest(self, element):
     281        """
     282        Called with the request's child element for parsing.
     283
     284        When a request instance is created using L{fromElement}, this method
     285        is called with the child element of the iq. Override this method for
     286        parsing the request's payload.
     287        """
    252288
    253289
  • wokkel/test/test_generic.py

    r165 r171  
    9191
    9292
     93class StanzaTest(unittest.TestCase):
     94    """
     95    Tests for L{generic.Stanza}.
     96    """
     97
     98    def test_fromElement(self):
     99        xml = """
     100        <message type='chat' from='other@example.org' to='user@example.org'/>
     101        """
     102
     103        stanza = generic.Stanza.fromElement(generic.parseXml(xml))
     104        self.assertEqual('chat', stanza.stanzaType)
     105        self.assertEqual(JID('other@example.org'), stanza.sender)
     106        self.assertEqual(JID('user@example.org'), stanza.recipient)
     107
     108
     109    def test_fromElementChildParser(self):
     110        """
     111        Child elements for which no parser is defined are ignored.
     112        """
     113        xml = """
     114        <message from='other@example.org' to='user@example.org'>
     115          <x xmlns='http://example.org/'/>
     116        </message>
     117        """
     118
     119        class Message(generic.Stanza):
     120            childParsers = {('http://example.org/', 'x'): '_childParser_x'}
     121            elements = []
     122
     123            def _childParser_x(self, element):
     124                self.elements.append(element)
     125
     126        message = Message.fromElement(generic.parseXml(xml))
     127        self.assertEqual(1, len(message.elements))
     128
     129
     130    def test_fromElementChildParserAll(self):
     131        """
     132        Child elements for which no parser is defined are ignored.
     133        """
     134        xml = """
     135        <message from='other@example.org' to='user@example.org'>
     136          <x xmlns='http://example.org/'/>
     137        </message>
     138        """
     139
     140        class Message(generic.Stanza):
     141            childParsers = {None: '_childParser'}
     142            elements = []
     143
     144            def _childParser(self, element):
     145                self.elements.append(element)
     146
     147        message = Message.fromElement(generic.parseXml(xml))
     148        self.assertEqual(1, len(message.elements))
     149
     150
     151    def test_fromElementChildParserUnknown(self):
     152        """
     153        Child elements for which no parser is defined are ignored.
     154        """
     155        xml = """
     156        <message from='other@example.org' to='user@example.org'>
     157          <x xmlns='http://example.org/'/>
     158        </message>
     159        """
     160        generic.Stanza.fromElement(generic.parseXml(xml))
     161
     162
     163
     164
    93165class RequestTest(unittest.TestCase):
    94166    """
     
    100172
    101173
     174    def test_requestParser(self):
     175        """
     176        The request's child element is passed to requestParser.
     177        """
     178        xml = """
     179        <iq type='get'>
     180          <query xmlns='jabber:iq:version'/>
     181        </iq>
     182        """
     183
     184        class VersionRequest(generic.Request):
     185            elements = []
     186
     187            def parseRequest(self, element):
     188                self.elements.append((element.uri, element.name))
     189
     190        request = VersionRequest.fromElement(generic.parseXml(xml))
     191        self.assertEqual([(NS_VERSION, 'query')], request.elements)
     192
     193
    102194    def test_toElementStanzaKind(self):
    103195        """
Note: See TracChangeset for help on using the changeset viewer.