diff options
Diffstat (limited to 'sleekxmpp/stanza/iq.py')
-rw-r--r-- | sleekxmpp/stanza/iq.py | 281 |
1 files changed, 0 insertions, 281 deletions
diff --git a/sleekxmpp/stanza/iq.py b/sleekxmpp/stanza/iq.py deleted file mode 100644 index 088de4c0..00000000 --- a/sleekxmpp/stanza/iq.py +++ /dev/null @@ -1,281 +0,0 @@ -""" - SleekXMPP: The Sleek XMPP Library - Copyright (C) 2010 Nathanael C. Fritz - This file is part of SleekXMPP. - - See the file LICENSE for copying permission. -""" - -from sleekxmpp.stanza.rootstanza import RootStanza -from sleekxmpp.xmlstream import StanzaBase, ET -from sleekxmpp.xmlstream.handler import Waiter, Callback -from sleekxmpp.xmlstream.matcher import MatchIDSender, MatcherId -from sleekxmpp.exceptions import IqTimeout, IqError - - -class Iq(RootStanza): - - """ - XMPP <iq> stanzas, or info/query stanzas, are XMPP's method of - requesting and modifying information, similar to HTTP's GET and - POST methods. - - Each <iq> stanza must have an 'id' value which associates the - stanza with the response stanza. XMPP entities must always - be given a response <iq> stanza with a type of 'result' after - sending a stanza of type 'get' or 'set'. - - Most uses cases for <iq> stanzas will involve adding a <query> - element whose namespace indicates the type of information - desired. However, some custom XMPP applications use <iq> stanzas - as a carrier stanza for an application-specific protocol instead. - - Example <iq> Stanzas: - <iq to="user@example.com" type="get" id="314"> - <query xmlns="http://jabber.org/protocol/disco#items" /> - </iq> - - <iq to="user@localhost" type="result" id="17"> - <query xmlns='jabber:iq:roster'> - <item jid='otheruser@example.net' - name='John Doe' - subscription='both'> - <group>Friends</group> - </item> - </query> - </iq> - - Stanza Interface: - query -- The namespace of the <query> element if one exists. - - Attributes: - types -- May be one of: get, set, result, or error. - - Methods: - __init__ -- Overrides StanzaBase.__init__. - unhandled -- Send error if there are no handlers. - set_payload -- Overrides StanzaBase.set_payload. - set_query -- Add or modify a <query> element. - get_query -- Return the namespace of the <query> element. - del_query -- Remove the <query> element. - reply -- Overrides StanzaBase.reply - send -- Overrides StanzaBase.send - """ - - namespace = 'jabber:client' - name = 'iq' - interfaces = set(('type', 'to', 'from', 'id', 'query')) - types = set(('get', 'result', 'set', 'error')) - plugin_attrib = name - - def __init__(self, *args, **kwargs): - """ - Initialize a new <iq> stanza with an 'id' value. - - Overrides StanzaBase.__init__. - """ - StanzaBase.__init__(self, *args, **kwargs) - if self['id'] == '': - if self.stream is not None: - self['id'] = self.stream.new_id() - else: - self['id'] = '0' - - def unhandled(self): - """ - Send a feature-not-implemented error if the stanza is not handled. - - Overrides StanzaBase.unhandled. - """ - if self['type'] in ('get', 'set'): - self.reply() - self['error']['condition'] = 'feature-not-implemented' - self['error']['text'] = 'No handlers registered for this request.' - self.send() - - def set_payload(self, value): - """ - Set the XML contents of the <iq> stanza. - - Arguments: - value -- An XML object to use as the <iq> stanza's contents - """ - self.clear() - StanzaBase.set_payload(self, value) - return self - - def set_query(self, value): - """ - Add or modify a <query> element. - - Query elements are differentiated by their namespace. - - Arguments: - value -- The namespace of the <query> element. - """ - query = self.xml.find("{%s}query" % value) - if query is None and value: - plugin = self.plugin_tag_map.get('{%s}query' % value, None) - if plugin: - self.enable(plugin.plugin_attrib) - else: - self.clear() - query = ET.Element("{%s}query" % value) - self.xml.append(query) - return self - - def get_query(self): - """Return the namespace of the <query> element.""" - for child in self.xml: - if child.tag.endswith('query'): - ns = child.tag.split('}')[0] - if '{' in ns: - ns = ns[1:] - return ns - return '' - - def del_query(self): - """Remove the <query> element.""" - for child in self.xml: - if child.tag.endswith('query'): - self.xml.remove(child) - return self - - def reply(self, clear=True): - """ - Send a reply <iq> stanza. - - Overrides StanzaBase.reply - - Sets the 'type' to 'result' in addition to the default - StanzaBase.reply behavior. - - Arguments: - clear -- Indicates if existing content should be - removed before replying. Defaults to True. - """ - self['type'] = 'result' - StanzaBase.reply(self, clear) - return self - - def send(self, block=True, timeout=None, callback=None, now=False, timeout_callback=None): - """ - Send an <iq> stanza over the XML stream. - - The send call can optionally block until a response is received or - a timeout occurs. Be aware that using blocking in non-threaded event - handlers can drastically impact performance. Otherwise, a callback - handler can be provided that will be executed when the Iq stanza's - result reply is received. Be aware though that that the callback - handler will not be executed in its own thread. - - Using both block and callback is not recommended, and only the - callback argument will be used in that case. - - Overrides StanzaBase.send - - Arguments: - block -- Specify if the send call will block until a response - is received, or a timeout occurs. Defaults to True. - timeout -- The length of time (in seconds) to wait for a response - before exiting the send call if blocking is used. - Defaults to sleekxmpp.xmlstream.RESPONSE_TIMEOUT - callback -- Optional reference to a stream handler function. Will - be executed when a reply stanza is received. - now -- Indicates if the send queue should be skipped and send - the stanza immediately. Used during stream - initialization. Defaults to False. - timeout_callback -- Optional reference to a stream handler function. - Will be executed when the timeout expires before a - response has been received with the originally-sent IQ - stanza. Only called if there is a callback parameter - (and therefore are in async mode). - """ - if timeout is None: - timeout = self.stream.response_timeout - - if self.stream.session_bind_event.is_set(): - matcher = MatchIDSender({ - 'id': self['id'], - 'self': self.stream.boundjid, - 'peer': self['to'] - }) - else: - matcher = MatcherId(self['id']) - - if callback is not None and self['type'] in ('get', 'set'): - handler_name = 'IqCallback_%s' % self['id'] - if timeout_callback: - self.callback = callback - self.timeout_callback = timeout_callback - self.stream.schedule('IqTimeout_%s' % self['id'], - timeout, - self._fire_timeout, - repeat=False) - handler = Callback(handler_name, - matcher, - self._handle_result, - once=True) - else: - handler = Callback(handler_name, - matcher, - callback, - once=True) - self.stream.register_handler(handler) - StanzaBase.send(self, now=now) - return handler_name - elif block and self['type'] in ('get', 'set'): - waitfor = Waiter('IqWait_%s' % self['id'], matcher) - self.stream.register_handler(waitfor) - StanzaBase.send(self, now=now) - result = waitfor.wait(timeout) - if not result: - raise IqTimeout(self) - if result['type'] == 'error': - raise IqError(result) - return result - else: - return StanzaBase.send(self, now=now) - - def _handle_result(self, iq): - # we got the IQ, so don't fire the timeout - self.stream.scheduler.remove('IqTimeout_%s' % self['id']) - self.callback(iq) - - def _fire_timeout(self): - # don't fire the handler for the IQ, if it finally does come in - self.stream.remove_handler('IqCallback_%s' % self['id']) - self.timeout_callback(self) - - def _set_stanza_values(self, values): - """ - Set multiple stanza interface values using a dictionary. - - Stanza plugin values may be set usind nested dictionaries. - - If the interface 'query' is given, then it will be set - last to avoid duplication of the <query /> element. - - Overrides ElementBase._set_stanza_values. - - Arguments: - values -- A dictionary mapping stanza interface with values. - Plugin interfaces may accept a nested dictionary that - will be used recursively. - """ - query = values.get('query', '') - if query: - del values['query'] - StanzaBase._set_stanza_values(self, values) - self['query'] = query - else: - StanzaBase._set_stanza_values(self, values) - return self - - -# To comply with PEP8, method names now use underscores. -# Deprecated method names are re-mapped for backwards compatibility. -Iq.setPayload = Iq.set_payload -Iq.getQuery = Iq.get_query -Iq.setQuery = Iq.set_query -Iq.delQuery = Iq.del_query |