Mercurial > libervia-backend
view src/plugins/plugin_xep_0059.py @ 1225:82dabb442e2e
frontends (primitivus): new command :search <pattern>
author | souliane <souliane@mailoo.org> |
---|---|
date | Sat, 04 Oct 2014 10:26:10 +0200 |
parents | 16484ebb695b |
children | ea692d51a0ee |
line wrap: on
line source
#!/usr/bin/python # -*- coding: utf-8 -*- # SAT plugin for Result Set Management (XEP-0059) # Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014 Jérôme Poisson (goffi@goffi.org) # Copyright (C) 2013, 2014 Adrien Cossa (souliane@mailoo.org) # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. from sat.core.i18n import _ from sat.core.log import getLogger log = getLogger(__name__) from twisted.words.xish import domish from wokkel import disco, iwokkel try: from twisted.words.protocols.xmlstream import XMPPHandler except ImportError: from wokkel.subprotocols import XMPPHandler from zope.interface import implements NS_RSM = 'http://jabber.org/protocol/rsm' PLUGIN_INFO = { "name": "Result Set Management", "import_name": "XEP-0059", "type": "XEP", "protocols": ["XEP-0059"], "main": "XEP_0059", "handler": "no", "description": _("""Implementation of Result Set Management""") } class XEP_0059(object): def __init__(self, host): log.info(_("Result Set Management plugin initialization")) self.host = host def requestPage(self, stanza, limit=10, index=None, after=None, before=None): """Embed a RSM page request in the given stanza. @param stanza (domish.Element): any stanza to which RSM applies @param limit (int): the maximum number of items in the page @param index (int): the starting index of the requested page @param after (str, int): the element immediately preceding the page @param before (str, int): the element immediately following the page """ main_elt = None try: main_elt = domish.generateElementsNamed(stanza.elements(), name="query").next() except StopIteration: try: main_elt = domish.generateElementsNamed(stanza.elements(), name="pubsub").next() except StopIteration: log.warning("Injection of a RSM element only applies to query or pubsub stanzas") return limit = str(int(limit)) # in case the service doesn't support RSM, do this at least main_elt.items.attributes['max_items'] = limit set_elt = main_elt.addElement('set', NS_RSM) set_elt.addElement('max').addContent(limit) if index: assert(after is None and before is None) set_elt.addElement('index').addContent(str(int(index))) if after: assert(before is None) # could not specify both at the same time set_elt.addElement('after').addContent(str(after)) if before is not None: if before == '': # request the last page, according to http://xmpp.org/extensions/xep-0059.html#last set_elt.addElement('before') else: set_elt.addElement('before').addContent(str(before)) def countItems(self, stanza): """Count the items without retrieving any of them. @param stanza (domish.Element): any stanza to which RSM applies """ self.requestPage(stanza, limit=0) def extractMetadata(self, stanza): """Extract the RSM metadata from the given stanza. @param stanza (domish.Element, wokkel.pubsub.PubSubRequest): any stanza to which RSM applies. When used by XEP-0060, wokkel's PubSubRequest instance is also accepted. @return: dict containing the page metadata """ try: main_elt = domish.generateElementsNamed(stanza.elements(), name="query").next() except StopIteration: try: main_elt = domish.generateElementsNamed(stanza.elements(), name="pubsub").next() except StopIteration: log.warning("Extracting data from a RSM element only applies to query or pubsub stanzas") return {} try: set_elt = domish.generateElementsQNamed(main_elt.elements(), name="set", uri=NS_RSM).next() except StopIteration: log.debug("There's no RSM element in the stanza") return {} data = {} elts = set_elt.elements() try: elt = elts.next() if elt.name == "first": data["first"] = "".join(elt.children) data["first_index"] = int(elt.getAttribute("index")) elif elt.name == "last": data["last"] = "".join(elt.children) elif elt.name == "count": data["count"] = int("".join(elt.children)) except StopIteration: pass if "count" not in data: log.warning("There's no 'count' element in the RSM element!") return data class XEP_0059_handler(XMPPHandler): implements(iwokkel.IDisco) def __init__(self, plugin_parent, profile): self.plugin_parent = plugin_parent self.host = plugin_parent.host self.profile = profile def getDiscoInfo(self, requestor, target, nodeIdentifier=''): return [disco.DiscoFeature(NS_RSM)] def getDiscoItems(self, requestor, target, nodeIdentifier=''): return []