comparison src/plugins/plugin_xep_0060.py @ 1219:16484ebb695b

plugin XEP-0059: first draft, pubsub and jabber search do not exploit it yet
author souliane <souliane@mailoo.org>
date Mon, 22 Sep 2014 22:25:44 +0200
parents 318eab3f93f8
children f584fbda4773
comparison
equal deleted inserted replaced
1218:3b1c5f723c4b 1219:16484ebb695b
21 from sat.core.constants import Const as C 21 from sat.core.constants import Const as C
22 from sat.core.log import getLogger 22 from sat.core.log import getLogger
23 log = getLogger(__name__) 23 log = getLogger(__name__)
24 from sat.memory.memory import Sessions 24 from sat.memory.memory import Sessions
25 25
26 from wokkel.compat import IQ
26 from wokkel import disco, pubsub 27 from wokkel import disco, pubsub
27 from wokkel.pubsub import PubSubRequest, NS_PUBSUB 28 from wokkel.pubsub import PubSubRequest, NS_PUBSUB
28 from zope.interface import implements 29 from zope.interface import implements
29 from twisted.internet import defer 30 from twisted.internet import defer
30 31
33 "name": "Publish-Subscribe", 34 "name": "Publish-Subscribe",
34 "import_name": "XEP-0060", 35 "import_name": "XEP-0060",
35 "type": "XEP", 36 "type": "XEP",
36 "protocols": ["XEP-0060"], 37 "protocols": ["XEP-0060"],
37 "dependencies": [], 38 "dependencies": [],
39 "recommendations": ["XEP-0059"],
38 "main": "XEP_0060", 40 "main": "XEP_0060",
39 "handler": "yes", 41 "handler": "yes",
40 "description": _("""Implementation of PubSub Protocol""") 42 "description": _("""Implementation of PubSub Protocol""")
41 } 43 }
42 44
230 def connectionInitialized(self): 232 def connectionInitialized(self):
231 pubsub.PubSubClient.connectionInitialized(self) 233 pubsub.PubSubClient.connectionInitialized(self)
232 234
233 # FIXME: we have to temporary override this method here just 235 # FIXME: we have to temporary override this method here just
234 # to set the attributes itemIdentifiers which is not used 236 # to set the attributes itemIdentifiers which is not used
235 # in pubsub.PubSubClient.items 237 # in pubsub.PubSubClient.items + use the XEP-0059
236 def items(self, service, nodeIdentifier, maxItems=None, itemIdentifiers=None, 238 def items(self, service, nodeIdentifier, maxItems=None, itemIdentifiers=None,
237 subscriptionIdentifier=None, sender=None): 239 subscriptionIdentifier=None, sender=None):
238 """ 240 """
239 Retrieve previously published items from a publish subscribe node. 241 Retrieve previously published items from a publish subscribe node.
240 242
253 @param subscriptionIdentifier: Optional subscription identifier. In 255 @param subscriptionIdentifier: Optional subscription identifier. In
254 case the node has been subscribed to multiple times, this narrows 256 case the node has been subscribed to multiple times, this narrows
255 the results to the specific subscription. 257 the results to the specific subscription.
256 @type subscriptionIdentifier: C{unicode} 258 @type subscriptionIdentifier: C{unicode}
257 """ 259 """
258 request = PubSubRequest('items') 260 # TODO: add method attributes for RSM: before, after, index
261 request = PubSubRequest('items', self.host, {'limit': maxItems} if maxItems else {})
259 request.recipient = service 262 request.recipient = service
260 request.nodeIdentifier = nodeIdentifier 263 request.nodeIdentifier = nodeIdentifier
261 if maxItems: 264 if maxItems:
262 request.maxItems = str(int(maxItems)) 265 request.maxItems = str(int(maxItems))
263 request.subscriptionIdentifier = subscriptionIdentifier 266 request.subscriptionIdentifier = subscriptionIdentifier
267 def cb(iq): 270 def cb(iq):
268 items = [] 271 items = []
269 for element in iq.pubsub.items.elements(): 272 for element in iq.pubsub.items.elements():
270 if element.uri == NS_PUBSUB and element.name == 'item': 273 if element.uri == NS_PUBSUB and element.name == 'item':
271 items.append(element) 274 items.append(element)
275 # TODO: return (items, self.host.plugins['XEP-0059'].extractMetadata(iq)) ??
272 return items 276 return items
273 277
274 d = request.send(self.xmlstream) 278 d = request.send(self.xmlstream)
275 d.addCallback(cb) 279 d.addCallback(cb)
276 return d 280 return d
329 self.host.trigger.point("PubSub Disco Info", disco_info, self.parent.profile) 333 self.host.trigger.point("PubSub Disco Info", disco_info, self.parent.profile)
330 return disco_info 334 return disco_info
331 335
332 def getDiscoItems(self, requestor, service, nodeIdentifier=''): 336 def getDiscoItems(self, requestor, service, nodeIdentifier=''):
333 return self.host.getDiscoItems(service, nodeIdentifier, self.parent.profile) 337 return self.host.getDiscoItems(service, nodeIdentifier, self.parent.profile)
338
339
340 class PubSubRequest(pubsub.PubSubRequest):
341
342 def __init__(self, verb=None, host=None, page_attrs=None):
343 """
344 @param verb (str): the type of pubsub request
345 @param host (SAT): the SAT instance
346 @param page_attrs (dict): options for RSM paging:
347 - limit (int): the maximum number of items in the page
348 - index (int): the starting index of the requested page
349 - after (str, int): the element immediately preceding the page
350 - before (str, int): the element immediately following the page
351 """
352 self.verb = verb
353 self.host = host
354 self.page_attrs = page_attrs
355
356 # FIXME: the redefinition of this wokkel method is the easiest way I found
357 # to handle RSM. We should find a proper solution, maybe just add in wokkel an
358 # empty method postProcessMessage, call it before sending and overwrite it here
359 # instead of overwriting the whole send method.
360 def send(self, xs):
361 """
362 Send this request to its recipient.
363
364 This renders all of the relevant parameters for this specific
365 requests into an L{IQ}, and invoke its C{send} method.
366 This returns a deferred that fires upon reception of a response. See
367 L{IQ} for details.
368
369 @param xs: The XML stream to send the request on.
370 @type xs: L{twisted.words.protocols.jabber.xmlstream.XmlStream}
371 @rtype: L{defer.Deferred}.
372 """
373
374 try:
375 (self.stanzaType,
376 childURI,
377 childName) = self._verbRequestMap[self.verb]
378 except KeyError:
379 raise NotImplementedError()
380
381 iq = IQ(xs, self.stanzaType)
382 iq.addElement((childURI, 'pubsub'))
383 verbElement = iq.pubsub.addElement(childName)
384
385 if self.sender:
386 iq['from'] = self.sender.full()
387 if self.recipient:
388 iq['to'] = self.recipient.full()
389
390 for parameter in self._parameters[self.verb]:
391 getattr(self, '_render_%s' % parameter)(verbElement)
392
393 # This lines have been added for RSM
394 if self.host and 'XEP-0059' in self.host.plugins and self.page_attrs:
395 self.page_attrs['stanza'] = iq
396 self.host.plugins['XEP-0059'].requestPage(**self.page_attrs)
397
398 return iq.send()