[36] | 1 | diff -r 7b9f484b0b44 wokkel/xmppim.py |
---|
| 2 | --- a/wokkel/xmppim.py Fri Feb 12 19:49:36 2010 +0100 |
---|
[37] | 3 | +++ b/wokkel/xmppim.py Sat Feb 13 18:57:26 2010 +0100 |
---|
[34] | 4 | @@ -12,6 +12,7 @@ |
---|
| 5 | All of it should eventually move to Twisted. |
---|
| 6 | """ |
---|
| 7 | |
---|
| 8 | +from twisted.words.protocols.jabber import error, xmlstream |
---|
| 9 | from twisted.words.protocols.jabber.jid import JID |
---|
| 10 | from twisted.words.xish import domish |
---|
| 11 | |
---|
| 12 | @@ -22,6 +23,9 @@ |
---|
| 13 | NS_XML = 'http://www.w3.org/XML/1998/namespace' |
---|
| 14 | NS_ROSTER = 'jabber:iq:roster' |
---|
| 15 | |
---|
| 16 | +XPATH_ROSTER_GET = "//iq[@type='get']/query[@xmlns='%s']" % NS_ROSTER |
---|
| 17 | +XPATH_ROSTER_SET = "//iq[@type='set']/query[@xmlns='%s']" % NS_ROSTER |
---|
| 18 | + |
---|
| 19 | class Presence(domish.Element): |
---|
| 20 | def __init__(self, to=None, type=None): |
---|
| 21 | domish.Element.__init__(self, (None, "presence")) |
---|
[36] | 22 | @@ -636,6 +640,7 @@ |
---|
| 23 | |
---|
[34] | 24 | |
---|
| 25 | |
---|
| 26 | + |
---|
| 27 | class RosterClientProtocol(XMPPHandler): |
---|
| 28 | """ |
---|
| 29 | Client side XMPP roster protocol. |
---|
[36] | 30 | @@ -645,6 +650,7 @@ |
---|
[34] | 31 | ROSTER_SET = "/iq[@type='set']/query[@xmlns='%s']" % NS_ROSTER |
---|
| 32 | self.xmlstream.addObserver(ROSTER_SET, self._onRosterSet) |
---|
| 33 | |
---|
| 34 | + |
---|
| 35 | def _parseRosterItem(self, element): |
---|
| 36 | jid = JID(element['jid']) |
---|
| 37 | item = RosterItem(jid) |
---|
[36] | 38 | @@ -659,6 +665,7 @@ |
---|
[34] | 39 | |
---|
| 40 | return item |
---|
| 41 | |
---|
| 42 | + |
---|
| 43 | def getRoster(self): |
---|
| 44 | """ |
---|
| 45 | Retrieve contact list. |
---|
[36] | 46 | @@ -713,6 +720,7 @@ |
---|
[34] | 47 | item = self._parseRosterItem(iq.query.item) |
---|
| 48 | self.onRosterSet(item) |
---|
| 49 | |
---|
| 50 | + |
---|
| 51 | def onRosterSet(self, item): |
---|
| 52 | """ |
---|
| 53 | Called when a roster push for a new or update item was received. |
---|
[36] | 54 | @@ -721,6 +729,7 @@ |
---|
[34] | 55 | @type item: L{RosterItem} |
---|
| 56 | """ |
---|
| 57 | |
---|
| 58 | + |
---|
| 59 | def onRosterRemove(self, entity): |
---|
| 60 | """ |
---|
| 61 | Called when a roster push for the removal of an item was received. |
---|
[36] | 62 | @@ -729,6 +738,48 @@ |
---|
[34] | 63 | @type entity: L{JID} |
---|
| 64 | """ |
---|
| 65 | |
---|
| 66 | + |
---|
| 67 | + |
---|
| 68 | +class RosterServerProtocol(XMPPHandler): |
---|
| 69 | + """ |
---|
| 70 | + XMPP subprotocol handler for the roster, server side. |
---|
| 71 | + """ |
---|
| 72 | + |
---|
| 73 | + def connectionInitialized(self): |
---|
[37] | 74 | + self.xmlstream.addObserver(XPATH_ROSTER_GET, self._onRosterGet) |
---|
| 75 | + self.xmlstream.addObserver(XPATH_ROSTER_SET, self._onRosterSet) |
---|
[34] | 76 | + |
---|
| 77 | + |
---|
[36] | 78 | + def _toRosterReply(self, roster, iq): |
---|
[34] | 79 | + response = xmlstream.toResponse(iq, 'result') |
---|
| 80 | + response.addElement((NS_ROSTER, 'query')) |
---|
| 81 | + |
---|
[36] | 82 | + for item in roster: |
---|
| 83 | + response.query.addChild(item.toElement()) |
---|
[34] | 84 | + |
---|
| 85 | + return response |
---|
| 86 | + |
---|
| 87 | + |
---|
| 88 | + def _onRosterGet(self, iq): |
---|
| 89 | + iq.handled = True |
---|
| 90 | + |
---|
| 91 | + d = self.getRoster(JID(iq["from"])) |
---|
| 92 | + d.addCallback(self._toRosterReply, iq) |
---|
| 93 | + d.addErrback(lambda _: error.ErrorStanza('internal-error').toResponse(iq)) |
---|
| 94 | + d.addBoth(self.send) |
---|
| 95 | + |
---|
| 96 | + |
---|
| 97 | + def _onRosterSet(self, iq): |
---|
| 98 | + iq.handled = True |
---|
| 99 | + response = error.StanzaError('bad-request').toResponse(iq) |
---|
| 100 | + self.send(response) |
---|
| 101 | + |
---|
| 102 | + |
---|
| 103 | + def getRoster(self, entity): |
---|
| 104 | + raise NotImplemented |
---|
| 105 | + |
---|
| 106 | + |
---|
| 107 | + |
---|
| 108 | class MessageProtocol(XMPPHandler): |
---|
| 109 | """ |
---|
| 110 | Generic XMPP subprotocol handler for incoming message stanzas. |
---|