Changeset 18:4812cc70807d for wokkel
- Timestamp:
- Apr 16, 2008, 4:08:15 PM (14 years ago)
- Branch:
- default
- Convert:
- svn:b33ecbfc-034c-dc11-8662-000475d9059e/trunk@48
- Location:
- wokkel
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
wokkel/pubsub.py
r17 r18 78 78 79 79 80 80 81 class SubscriptionPending(Exception): 81 82 """ 82 83 Raised when the requested subscription is pending acceptance. 83 84 """ 85 84 86 85 87 … … 89 91 becoming active. 90 92 """ 93 91 94 92 95 … … 104 107 105 108 109 106 110 class Unsupported(PubSubError): 107 111 def __init__(self, feature, text=None): … … 112 116 113 117 118 114 119 class OptionsUnavailable(Unsupported): 115 120 def __init__(self): 116 121 Unsupported.__init__(self, 'subscription-options-unavailable') 122 117 123 118 124 … … 136 142 """ 137 143 138 domish.Element.__init__(self, (N one, 'item'))144 domish.Element.__init__(self, (NS_PUBSUB, 'item')) 139 145 if id is not None: 140 146 self['id'] = id … … 146 152 147 153 148 class PubSubRequest(xmlstream.IQ): 149 """ 150 Base class for publish subscribe user requests. 151 152 @cvar namespace: request namespace 153 @cvar verb: request verb 154 @cvar method: type attribute of the IQ request. Either C{'set'} or C{'get'} 155 @ivar command: command element of the request. This is the direct child of 154 155 class _PubSubRequest(xmlstream.IQ): 156 """ 157 Publish subscribe request. 158 159 @ivar verb: Request verb 160 @type verb: C{str} 161 @ivar namespace: Request namespace. 162 @type namespace: C{str} 163 @ivar method: Type attribute of the IQ request. Either C{'set'} or C{'get'} 164 @type method: C{str} 165 @ivar command: Command element of the request. This is the direct child of 156 166 the C{pubsub} element in the C{namespace} with the name 157 167 C{verb}. 158 168 """ 159 169 160 namespace = NS_PUBSUB 161 method = 'set' 162 163 def __init__(self, xs): 164 xmlstream.IQ.__init__(self, xs, self.method) 165 self.addElement((self.namespace, 'pubsub')) 166 167 self.command = self.pubsub.addElement(self.verb) 170 def __init__(self, xs, verb, namespace=NS_PUBSUB, method='set'): 171 xmlstream.IQ.__init__(self, xs, method) 172 self.addElement((namespace, 'pubsub')) 173 174 self.command = self.pubsub.addElement(verb) 168 175 169 176 def send(self, to): … … 181 188 182 189 183 class CreateNode(PubSubRequest):184 verb = 'create'185 186 def __init__(self, xs, node=None):187 PubSubRequest.__init__(self, xs)188 if node:189 self.command["node"] = node190 191 192 class DeleteNode(PubSubRequest):193 verb = 'delete'194 def __init__(self, xs, node):195 PubSubRequest.__init__(self, xs)196 self.command["node"] = node197 198 199 class Subscribe(PubSubRequest):200 verb = 'subscribe'201 202 def __init__(self, xs, node, subscriber):203 PubSubRequest.__init__(self, xs)204 self.command["node"] = node205 self.command["jid"] = subscriber.full()206 207 208 class Unsubscribe(PubSubRequest):209 verb = 'unsubscribe'210 211 def __init__(self, xs, node, subscriber):212 PubSubRequest.__init__(self, xs)213 self.command["node"] = node214 self.command["jid"] = subscriber.full()215 216 217 class Publish(PubSubRequest):218 verb = 'publish'219 220 def __init__(self, xs, node):221 PubSubRequest.__init__(self, xs)222 self.command["node"] = node223 224 def addItem(self, id=None, payload=None):225 item = self.command.addElement("item")226 item.addChild(payload)227 228 if id is not None:229 item["id"] = id230 231 return item232 233 class Items(PubSubRequest):234 verb = 'items'235 method = 'get'236 237 def __init__(self, xs, node):238 PubSubRequest.__init__(self, xs)239 self.command["node"] = node240 190 241 191 class PubSubClient(XMPPHandler): … … 297 247 298 248 def createNode(self, service, nodeIdentifier=None): 299 request = CreateNode(self.xmlstream, nodeIdentifier) 249 """ 250 Create a publish subscribe node. 251 252 @param service: The publish subscribe service to create the node at. 253 @type service: L{JID} 254 @param nodeIdentifier: Optional suggestion for the id of the node. 255 @type nodeIdentifier: C{unicode} 256 """ 257 258 259 request = _PubSubRequest(self.xmlstream, 'create') 260 if nodeIdentifier: 261 request.command['node'] = nodeIdentifier 300 262 301 263 def cb(iq): … … 310 272 311 273 def deleteNode(self, service, nodeIdentifier): 312 return DeleteNode(self.xmlstream, nodeIdentifier).send(service) 274 """ 275 Delete a publish subscribe node. 276 277 @param service: The publish subscribe service to delete the node from. 278 @type service: L{JID} 279 @param nodeIdentifier: The identifier of the node. 280 @type nodeIdentifier: C{unicode} 281 """ 282 request = _PubSubRequest(self.xmlstream, 'delete') 283 request.command['node'] = nodeIdentifier 284 return request.send(service) 313 285 314 286 def subscribe(self, service, nodeIdentifier, subscriber): 315 request = Subscribe(self.xmlstream, nodeIdentifier, subscriber) 287 """ 288 Subscribe to a publish subscribe node. 289 290 @param service: The publish subscribe service that keeps the node. 291 @type service: L{JID} 292 @param nodeIdentifier: The identifier of the node. 293 @type nodeIdentifier: C{unicode} 294 @param subscriber: The entity to subscribe to the node. This entity 295 will get notifications of new published items. 296 @type subscriber: L{JID} 297 """ 298 request = _PubSubRequest(self.xmlstream, 'subscribe') 299 request.command['node'] = nodeIdentifier 300 request.command['jid'] = subscriber.full() 316 301 317 302 def cb(iq): … … 331 316 332 317 def unsubscribe(self, service, nodeIdentifier, subscriber): 333 request = Unsubscribe(self.xmlstream, nodeIdentifier, subscriber) 318 """ 319 Unsubscribe from a publish subscribe node. 320 321 @param service: The publish subscribe service that keeps the node. 322 @type service: L{JID} 323 @param nodeIdentifier: The identifier of the node. 324 @type nodeIdentifier: C{unicode} 325 @param subscriber: The entity to unsubscribe from the node. 326 @type subscriber: L{JID} 327 """ 328 request = _PubSubRequest(self.xmlstream, 'unsubscribe') 329 request.command['node'] = nodeIdentifier 330 request.command['jid'] = subscriber.full() 334 331 return request.send(service) 335 332 336 def publish(self, service, nodeIdentifier, items=[]): 337 request = Publish(self.xmlstream, nodeIdentifier) 338 for item in items: 339 request.command.addChild(item) 333 def publish(self, service, nodeIdentifier, items=None): 334 """ 335 Publish to a publish subscribe node. 336 337 @param service: The publish subscribe service that keeps the node. 338 @type service: L{JID} 339 @param nodeIdentifier: The identifier of the node. 340 @type nodeIdentifier: C{unicode} 341 @param items: Optional list of L{Item}s to publish. 342 @type items: C{list} 343 """ 344 request = _PubSubRequest(self.xmlstream, 'publish') 345 request.command['node'] = nodeIdentifier 346 if items: 347 for item in items: 348 request.command.addChild(item) 340 349 341 350 return request.send(service) 342 351 343 def items(self, service, nodeIdentifier): 352 def items(self, service, nodeIdentifier, maxItems=None): 353 """ 354 Retrieve previously published items from a publish subscribe node. 355 356 @param service: The publish subscribe service that keeps the node. 357 @type service: L{JID} 358 @param nodeIdentifier: The identifier of the node. 359 @type nodeIdentifier: C{unicode} 360 @param maxItems: Optional limit on the number of retrieved items. 361 @type maxItems: C{int} 362 """ 363 request = _PubSubRequest(self.xmlstream, 'items', method='get') 364 request.command['node'] = nodeIdentifier 365 if maxItems: 366 request.command["max_items"] = str(int(maxItems)) 367 344 368 def cb(iq): 345 369 items = [] … … 349 373 return items 350 374 351 request = Items(self.xmlstream, nodeIdentifier)352 375 return request.send(service).addCallback(cb) 376 377 353 378 354 379 class PubSubService(XMPPHandler, IQHandlerMixin): -
wokkel/test/test_pubsub.py
r17 r18 51 51 self.protocol.connectionInitialized() 52 52 53 def test_unsubscribe(self):54 """55 Test sending unsubscription request.56 """57 d = self.protocol.unsubscribe(JID('pubsub.example.org'), 'test',58 JID('user@example.org'))59 60 iq = self.stub.output[-1]61 self.assertEquals('pubsub.example.org', iq.getAttribute('to'))62 self.assertEquals('set', iq.getAttribute('type'))63 self.assertEquals('pubsub', iq.pubsub.name)64 self.assertEquals(NS_PUBSUB, iq.pubsub.uri)65 children = list(domish.generateElementsQNamed(iq.pubsub.children,66 'unsubscribe', NS_PUBSUB))67 self.assertEquals(1, len(children))68 child = children[0]69 self.assertEquals('test', child['node'])70 self.assertEquals('user@example.org', child['jid'])71 72 self.stub.send(toResponse(iq, 'result'))73 return d74 53 75 54 def test_event_items(self): … … 100 79 return d 101 80 81 102 82 def test_event_delete(self): 103 83 """ … … 120 100 return d 121 101 102 122 103 def test_event_purge(self): 123 104 """ … … 141 122 142 123 124 def test_createNode(self): 125 """ 126 Test sending create request. 127 """ 128 129 def cb(nodeIdentifier): 130 self.assertEquals('test', nodeIdentifier) 131 132 d = self.protocol.createNode(JID('pubsub.example.org'), 'test') 133 d.addCallback(cb) 134 135 iq = self.stub.output[-1] 136 self.assertEquals('pubsub.example.org', iq.getAttribute('to')) 137 self.assertEquals('set', iq.getAttribute('type')) 138 self.assertEquals('pubsub', iq.pubsub.name) 139 self.assertEquals(NS_PUBSUB, iq.pubsub.uri) 140 children = list(domish.generateElementsQNamed(iq.pubsub.children, 141 'create', NS_PUBSUB)) 142 self.assertEquals(1, len(children)) 143 child = children[0] 144 self.assertEquals('test', child['node']) 145 146 response = toResponse(iq, 'result') 147 self.stub.send(response) 148 return d 149 150 151 def test_createNodeInstant(self): 152 """ 153 Test sending create request resulting in an instant node. 154 """ 155 156 def cb(nodeIdentifier): 157 self.assertEquals('test', nodeIdentifier) 158 159 d = self.protocol.createNode(JID('pubsub.example.org')) 160 d.addCallback(cb) 161 162 iq = self.stub.output[-1] 163 children = list(domish.generateElementsQNamed(iq.pubsub.children, 164 'create', NS_PUBSUB)) 165 child = children[0] 166 self.assertFalse(child.hasAttribute('node')) 167 168 response = toResponse(iq, 'result') 169 command = response.addElement((NS_PUBSUB, 'pubsub')) 170 create = command.addElement('create') 171 create['node'] = 'test' 172 self.stub.send(response) 173 return d 174 175 176 def test_createNodeRenamed(self): 177 """ 178 Test sending create request resulting in renamed node. 179 """ 180 181 def cb(nodeIdentifier): 182 self.assertEquals('test2', nodeIdentifier) 183 184 d = self.protocol.createNode(JID('pubsub.example.org'), 'test') 185 d.addCallback(cb) 186 187 iq = self.stub.output[-1] 188 children = list(domish.generateElementsQNamed(iq.pubsub.children, 189 'create', NS_PUBSUB)) 190 child = children[0] 191 self.assertEquals('test', child['node']) 192 193 response = toResponse(iq, 'result') 194 command = response.addElement((NS_PUBSUB, 'pubsub')) 195 create = command.addElement('create') 196 create['node'] = 'test2' 197 self.stub.send(response) 198 return d 199 200 201 def test_deleteNode(self): 202 """ 203 Test sending delete request. 204 """ 205 206 d = self.protocol.deleteNode(JID('pubsub.example.org'), 'test') 207 208 iq = self.stub.output[-1] 209 self.assertEquals('pubsub.example.org', iq.getAttribute('to')) 210 self.assertEquals('set', iq.getAttribute('type')) 211 self.assertEquals('pubsub', iq.pubsub.name) 212 self.assertEquals(NS_PUBSUB, iq.pubsub.uri) 213 children = list(domish.generateElementsQNamed(iq.pubsub.children, 214 'delete', NS_PUBSUB)) 215 self.assertEquals(1, len(children)) 216 child = children[0] 217 self.assertEquals('test', child['node']) 218 219 response = toResponse(iq, 'result') 220 self.stub.send(response) 221 return d 222 223 224 def test_publish(self): 225 """ 226 Test sending publish request. 227 """ 228 229 item = pubsub.Item() 230 d = self.protocol.publish(JID('pubsub.example.org'), 'test', [item]) 231 232 iq = self.stub.output[-1] 233 self.assertEquals('pubsub.example.org', iq.getAttribute('to')) 234 self.assertEquals('set', iq.getAttribute('type')) 235 self.assertEquals('pubsub', iq.pubsub.name) 236 self.assertEquals(NS_PUBSUB, iq.pubsub.uri) 237 children = list(domish.generateElementsQNamed(iq.pubsub.children, 238 'publish', NS_PUBSUB)) 239 self.assertEquals(1, len(children)) 240 child = children[0] 241 self.assertEquals('test', child['node']) 242 items = list(domish.generateElementsQNamed(child.children, 243 'item', NS_PUBSUB)) 244 self.assertEquals(1, len(items)) 245 self.assertIdentical(item, items[0]) 246 247 response = toResponse(iq, 'result') 248 self.stub.send(response) 249 return d 250 251 252 def test_publishNoItems(self): 253 """ 254 Test sending publish request without items. 255 """ 256 257 d = self.protocol.publish(JID('pubsub.example.org'), 'test') 258 259 iq = self.stub.output[-1] 260 self.assertEquals('pubsub.example.org', iq.getAttribute('to')) 261 self.assertEquals('set', iq.getAttribute('type')) 262 self.assertEquals('pubsub', iq.pubsub.name) 263 self.assertEquals(NS_PUBSUB, iq.pubsub.uri) 264 children = list(domish.generateElementsQNamed(iq.pubsub.children, 265 'publish', NS_PUBSUB)) 266 self.assertEquals(1, len(children)) 267 child = children[0] 268 self.assertEquals('test', child['node']) 269 270 response = toResponse(iq, 'result') 271 self.stub.send(response) 272 return d 273 274 275 def test_subscribe(self): 276 """ 277 Test sending subscription request. 278 """ 279 d = self.protocol.subscribe(JID('pubsub.example.org'), 'test', 280 JID('user@example.org')) 281 282 iq = self.stub.output[-1] 283 self.assertEquals('pubsub.example.org', iq.getAttribute('to')) 284 self.assertEquals('set', iq.getAttribute('type')) 285 self.assertEquals('pubsub', iq.pubsub.name) 286 self.assertEquals(NS_PUBSUB, iq.pubsub.uri) 287 children = list(domish.generateElementsQNamed(iq.pubsub.children, 288 'subscribe', NS_PUBSUB)) 289 self.assertEquals(1, len(children)) 290 child = children[0] 291 self.assertEquals('test', child['node']) 292 self.assertEquals('user@example.org', child['jid']) 293 294 response = toResponse(iq, 'result') 295 pubsub = response.addElement((NS_PUBSUB, 'pubsub')) 296 subscription = pubsub.addElement('subscription') 297 subscription['node'] = 'test' 298 subscription['jid'] = 'user@example.org' 299 subscription['subscription'] = 'subscribed' 300 self.stub.send(response) 301 return d 302 303 304 def test_subscribePending(self): 305 """ 306 Test sending subscription request that results in a pending 307 subscription. 308 """ 309 d = self.protocol.subscribe(JID('pubsub.example.org'), 'test', 310 JID('user@example.org')) 311 312 iq = self.stub.output[-1] 313 response = toResponse(iq, 'result') 314 command = response.addElement((NS_PUBSUB, 'pubsub')) 315 subscription = command.addElement('subscription') 316 subscription['node'] = 'test' 317 subscription['jid'] = 'user@example.org' 318 subscription['subscription'] = 'pending' 319 self.stub.send(response) 320 self.assertFailure(d, pubsub.SubscriptionPending) 321 return d 322 323 324 def test_subscribePending(self): 325 """ 326 Test sending subscription request that results in an unconfigured 327 subscription. 328 """ 329 d = self.protocol.subscribe(JID('pubsub.example.org'), 'test', 330 JID('user@example.org')) 331 332 iq = self.stub.output[-1] 333 response = toResponse(iq, 'result') 334 command = response.addElement((NS_PUBSUB, 'pubsub')) 335 subscription = command.addElement('subscription') 336 subscription['node'] = 'test' 337 subscription['jid'] = 'user@example.org' 338 subscription['subscription'] = 'unconfigured' 339 self.stub.send(response) 340 self.assertFailure(d, pubsub.SubscriptionUnconfigured) 341 return d 342 343 344 def test_unsubscribe(self): 345 """ 346 Test sending unsubscription request. 347 """ 348 d = self.protocol.unsubscribe(JID('pubsub.example.org'), 'test', 349 JID('user@example.org')) 350 351 iq = self.stub.output[-1] 352 self.assertEquals('pubsub.example.org', iq.getAttribute('to')) 353 self.assertEquals('set', iq.getAttribute('type')) 354 self.assertEquals('pubsub', iq.pubsub.name) 355 self.assertEquals(NS_PUBSUB, iq.pubsub.uri) 356 children = list(domish.generateElementsQNamed(iq.pubsub.children, 357 'unsubscribe', NS_PUBSUB)) 358 self.assertEquals(1, len(children)) 359 child = children[0] 360 self.assertEquals('test', child['node']) 361 self.assertEquals('user@example.org', child['jid']) 362 363 self.stub.send(toResponse(iq, 'result')) 364 return d 365 366 143 367 def test_items(self): 144 368 """ … … 169 393 170 394 return d 395 396 397 def test_itemsMaxItems(self): 398 """ 399 Test sending items request, with limit on the number of items. 400 """ 401 def cb(items): 402 self.assertEquals(2, len(items)) 403 self.assertEquals([item1, item2], items) 404 405 d = self.protocol.items(JID('pubsub.example.org'), 'test', maxItems=2) 406 d.addCallback(cb) 407 408 iq = self.stub.output[-1] 409 self.assertEquals('pubsub.example.org', iq.getAttribute('to')) 410 self.assertEquals('get', iq.getAttribute('type')) 411 self.assertEquals('pubsub', iq.pubsub.name) 412 self.assertEquals(NS_PUBSUB, iq.pubsub.uri) 413 children = list(domish.generateElementsQNamed(iq.pubsub.children, 414 'items', NS_PUBSUB)) 415 self.assertEquals(1, len(children)) 416 child = children[0] 417 self.assertEquals('test', child['node']) 418 self.assertEquals('2', child['max_items']) 419 420 response = toResponse(iq, 'result') 421 items = response.addElement((NS_PUBSUB, 'pubsub')).addElement('items') 422 items['node'] = 'test' 423 item1 = items.addElement('item') 424 item1['id'] = 'item1' 425 item2 = items.addElement('item') 426 item2['id'] = 'item2' 427 428 self.stub.send(response) 429 430 return d 431 432 171 433 172 434 class PubSubServiceTest(unittest.TestCase):
Note: See TracChangeset
for help on using the changeset viewer.