Changeset 72:727b4d29c48e in ralphm-patches for roster_server.patch
- Timestamp:
- Jan 27, 2013, 10:40:32 PM (10 years ago)
- Branch:
- default
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
roster_server.patch
r68 r72 1 1 Add server side support for the roster protocol. 2 2 3 * Implements roster get by calling `getRoster` and using the returned `list`4 of `RosterItem`sto send back the roster.3 * Implements roster get by calling `getRoster` and using the returned 4 `Roster` to send back the roster. 5 5 6 6 TODO: 7 * Add more docstrings.8 * Use `dict` instead of `list` as return value of `getRoster`.9 7 * Add support for roster sets? 10 8 … … 12 10 --- a/wokkel/test/test_xmppim.py 13 11 +++ b/wokkel/test/test_xmppim.py 14 @@ -1330,3 +1330,81 @@ 15 d = self.handleRequest(xml) 16 d.addCallback(cb) 17 return d 18 + 19 + 20 + 12 @@ -1339,6 +1339,85 @@ 13 14 15 21 16 +class RosterServerProtocolTest(unittest.TestCase, TestableRequestHandlerMixin): 22 17 + """ … … 45 40 + item = xmppim.RosterItem(JID('other@example.org'), True, False, 46 41 + 'The User') 47 + return defer.succeed([item]) 42 + roster = xmppim.Roster({item.entity: item}) 43 + return defer.succeed(roster) 48 44 + 49 45 + def cb(element): … … 94 90 + self.assertFailure(d, NotImplementedError) 95 91 + return d 92 + 93 + 94 + 95 class MessageTest(unittest.TestCase): 96 """ 97 Tests for L{xmppim.Message}. 96 98 diff --git a/wokkel/xmppim.py b/wokkel/xmppim.py 97 99 --- a/wokkel/xmppim.py 98 100 +++ b/wokkel/xmppim.py 99 @@ -2 5,6 +25,7 @@101 @@ -26,6 +26,7 @@ 100 102 NS_ROSTER = 'jabber:iq:roster' 101 103 … … 105 107 106 108 107 @@ -1063,3 +1064,40 @@ 108 """ 109 Called when a message stanza was received. 110 """ 111 + 112 + 113 + 109 @@ -739,9 +740,9 @@ 110 111 112 @classmethod 113 - def fromElement(Class, element): 114 + def fromElement(cls, element): 115 entity = JID(element['jid']) 116 - item = Class(entity) 117 + item = cls(entity) 118 subscription = element.getAttribute('subscription') 119 if subscription == 'remove': 120 item.remove = True 121 @@ -780,21 +781,26 @@ 122 version = None 123 rosterSet = False 124 125 + 126 def parseRequest(self, element): 127 - self.version = element.getAttribute('ver') 128 - 129 - for child in element.elements(NS_ROSTER, 'item'): 130 - self.item = RosterItem.fromElement(child) 131 + roster = Roster.fromElement(element) 132 + self.version = roster.version 133 + for item in roster.itervalues(): 134 + self.item = item 135 break 136 + return roster 137 138 139 def toElement(self): 140 element = Request.toElement(self) 141 - query = element.addElement((NS_ROSTER, 'query')) 142 - if self.version is not None: 143 - query['ver'] = self.version 144 + 145 + roster = Roster() 146 + roster.version = self.version 147 if self.item: 148 - query.addChild(self.item.toElement(rosterSet=self.rosterSet)) 149 + roster[self.item.entity] = self.item 150 + 151 + element.addChild(roster.toElement(rosterSet=self.rosterSet)) 152 + 153 return element 154 155 156 @@ -812,7 +818,7 @@ 157 158 class Roster(dict): 159 """ 160 - In-memory roster container. 161 + Roster container. 162 163 This provides a roster as a mapping from L{JID} to L{RosterItem}. If 164 roster versioning is used, the C{version} attribute holds the version 165 @@ -825,6 +831,28 @@ 166 version = None 167 168 169 + @classmethod 170 + def fromElement(cls, element): 171 + roster = cls() 172 + roster.version = element.getAttribute('ver') 173 + for element in element.elements(NS_ROSTER, 'item'): 174 + item = RosterItem.fromElement(element) 175 + roster[item.entity] = item 176 + return roster 177 + 178 + 179 + def toElement(self, rosterSet=False): 180 + element = domish.Element((NS_ROSTER, 'query')) 181 + 182 + if self.version: 183 + element['ver'] = self.version 184 + 185 + for item in self.itervalues(): 186 + element.addChild(item.toElement(rosterSet)) 187 + 188 + return element 189 + 190 + 191 192 class RosterClientProtocol(XMPPHandler, IQHandlerMixin): 193 """ 194 @@ -898,12 +926,7 @@ 195 196 def processRoster(result): 197 if result.query is not None: 198 - roster = Roster() 199 - roster.version = result.query.getAttribute('ver') 200 - for element in result.query.elements(NS_ROSTER, 'item'): 201 - item = RosterItem.fromElement(element) 202 - roster[item.entity] = item 203 - return roster 204 + return Roster.fromElement(result.query) 205 else: 206 return None 207 208 @@ -1002,6 +1025,43 @@ 209 210 211 114 212 +class RosterServerProtocol(XMPPHandler, IQHandlerMixin): 115 213 + """ … … 127 225 + 128 226 + 129 + def _toRosterReply(self, roster, request):130 + response = domish.Element((NS_ROSTER, 'query'))131 +132 + for item in roster:133 + response.addChild(item.toElement())134 +135 + return response136 +137 +138 227 + def _onRosterGet(self, iq): 139 + request = Stanza.fromElement(iq) 228 + request = RosterRequest.fromElement(iq) 229 + 230 + def toResponse(roster): 231 + return roster.toElement() 140 232 + 141 233 + d = self.getRoster(request) 142 + d.addCallback( self._toRosterReply, request)234 + d.addCallback(toResponse) 143 235 + return d 144 236 + 145 237 + 146 238 + def getRoster(self, request): 239 + """ 240 + Called when the roster is requested. 241 + 242 + @returns: Deferred that fires with a L{Roster}. 243 + @rtype: L{defer.Deferred} 244 + """ 147 245 + raise NotImplementedError() 246 + 247 + 248 + 249 class Message(Stanza): 250 """ 251 A message stanza.
Note: See TracChangeset
for help on using the changeset viewer.