source: wokkel/generic.py @ 27:d62d7ea14995

Last change on this file since 27:d62d7ea14995 was 24:ada867483400, checked in by Ralph Meijer <ralphm@…>, 13 years ago

PubSubService?.items should return a list of Elements representing items.

File size: 2.8 KB
Line 
1# -*- test-case-name: wokkel.test.test_generic -*-
2#
3# Copyright (c) 2003-2008 Ralph Meijer
4# See LICENSE for details.
5
6"""
7Generic XMPP protocol helpers.
8"""
9
10from zope.interface import implements
11
12from twisted.internet import defer
13from twisted.words.protocols.jabber import error
14from twisted.words.protocols.jabber.xmlstream import toResponse
15from twisted.words.xish import domish
16
17from wokkel import disco
18from wokkel.iwokkel import IDisco
19from wokkel.subprotocols import XMPPHandler
20
21IQ_GET = '/iq[@type="get"]'
22IQ_SET = '/iq[@type="set"]'
23
24NS_VERSION = 'jabber:iq:version'
25VERSION = IQ_GET + '/query[@xmlns="' + NS_VERSION + '"]'
26
27def parseXml(string):
28    """
29    Parse serialized XML into a DOM structure.
30
31    @param string: The serialized XML to be parsed, UTF-8 encoded.
32    @type string: C{str}.
33    @return: The DOM structure, or C{None} on empty or incomplete input.
34    @rtype: L{domish.Element}
35    """
36    roots = []
37    results = []
38    elementStream = domish.elementStream()
39    elementStream.DocumentStartEvent = roots.append
40    elementStream.ElementEvent = lambda elem: roots[0].addChild(elem)
41    elementStream.DocumentEndEvent = lambda: results.append(roots[0])
42    elementStream.parse(string)
43    return results and results[0] or None
44
45
46
47class FallbackHandler(XMPPHandler):
48    """
49    XMPP subprotocol handler that catches unhandled iq requests.
50
51    Unhandled iq requests are replied to with a service-unavailable stanza
52    error.
53    """
54
55    def connectionInitialized(self):
56        self.xmlstream.addObserver(IQ_SET, self.iqFallback, -1)
57        self.xmlstream.addObserver(IQ_GET, self.iqFallback, -1)
58
59    def iqFallback(self, iq):
60        if iq.handled == True:
61            return
62
63        reply = error.StanzaError('service-unavailable')
64        self.xmlstream.send(reply.toResponse(iq))
65
66
67
68class VersionHandler(XMPPHandler):
69    """
70    XMPP subprotocol handler for XMPP Software Version.
71
72    This protocol is described in
73    U{XEP-0092<http://www.xmpp.org/extensions/xep-0092.html>}.
74    """
75
76    implements(IDisco)
77
78    def __init__(self, name, version):
79        self.name = name
80        self.version = version
81
82    def connectionInitialized(self):
83        self.xmlstream.addObserver(VERSION, self.onVersion)
84
85    def onVersion(self, iq):
86        response = toResponse(iq, "result")
87
88        query = response.addElement((NS_VERSION, "query"))
89        name = query.addElement("name", content=self.name)
90        version = query.addElement("version", content=self.version)
91        self.send(response)
92
93        iq.handled = True
94
95    def getDiscoInfo(self, requestor, target, node):
96        info = set()
97
98        if not node:
99            info.add(disco.DiscoFeature(NS_VERSION))
100
101        return defer.succeed(info)
102
103    def getDiscoItems(self, requestor, target, node):
104        return defer.succeed([])
Note: See TracBrowser for help on using the repository browser.