summaryrefslogtreecommitdiff
path: root/sleekxmpp/plugins/xep_0050/adhoc.py
diff options
context:
space:
mode:
authorLance Stout <lancestout@gmail.com>2011-08-13 00:00:34 -0700
committerLance Stout <lancestout@gmail.com>2011-08-13 00:10:06 -0700
commitc26b716164d123b177fd069b9e04cb07eab79b56 (patch)
tree64bb5393ecb99f061a65812bac1f423ed733b1fd /sleekxmpp/plugins/xep_0050/adhoc.py
parentdcaddb804221790e778742f3f5ef22464608cc87 (diff)
downloadslixmpp-c26b716164d123b177fd069b9e04cb07eab79b56.tar.gz
slixmpp-c26b716164d123b177fd069b9e04cb07eab79b56.tar.bz2
slixmpp-c26b716164d123b177fd069b9e04cb07eab79b56.tar.xz
slixmpp-c26b716164d123b177fd069b9e04cb07eab79b56.zip
Update XEP-0050 to use new IQ exceptions.
IqError is now caught and forwarded to the command error handler referenced in the session. Errors are now caught and processed by the session's error handler whether or not the results Iq stanza includes the <command> substanza. Added the option for blocking command calls. The blocking option is set during start_command with block=True. Subsequent command flow methods use session['block'] to determine their blocking behaviour. If you use blocking commands, then you will need to wrap your command calls in a try/except block for IqTimeout exceptions.
Diffstat (limited to 'sleekxmpp/plugins/xep_0050/adhoc.py')
-rw-r--r--sleekxmpp/plugins/xep_0050/adhoc.py60
1 files changed, 41 insertions, 19 deletions
diff --git a/sleekxmpp/plugins/xep_0050/adhoc.py b/sleekxmpp/plugins/xep_0050/adhoc.py
index dd1c88d6..54be1f86 100644
--- a/sleekxmpp/plugins/xep_0050/adhoc.py
+++ b/sleekxmpp/plugins/xep_0050/adhoc.py
@@ -10,6 +10,7 @@ import logging
import time
from sleekxmpp import Iq
+from sleekxmpp.exceptions import IqError
from sleekxmpp.xmlstream.handler import Callback
from sleekxmpp.xmlstream.matcher import StanzaPath
from sleekxmpp.xmlstream import register_stanza_plugin, JID
@@ -91,16 +92,6 @@ class xep_0050(base_plugin):
StanzaPath('iq@type=set/command'),
self._handle_command))
- self.xmpp.register_handler(
- Callback("Ad-Hoc Result",
- StanzaPath('iq@type=result/command'),
- self._handle_command_result))
-
- self.xmpp.register_handler(
- Callback("Ad-Hoc Error",
- StanzaPath('iq@type=error/command'),
- self._handle_command_result))
-
register_stanza_plugin(Iq, stanza.Command)
self.xmpp.add_event_handler('command_execute',
@@ -408,7 +399,7 @@ class xep_0050(base_plugin):
**kwargs)
def send_command(self, jid, node, ifrom=None, action='execute',
- payload=None, sessionid=None, **kwargs):
+ payload=None, sessionid=None, flow=False, **kwargs):
"""
Create and send a command stanza, without using the provided
workflow management APIs.
@@ -422,6 +413,10 @@ class xep_0050(base_plugin):
payload -- Either a list of payload items, or a single
payload item such as a data form.
sessionid -- The current session's ID value.
+ flow -- If True, process the Iq result using the
+ command workflow methods contained in the
+ session instead of returning the response
+ stanza itself. Defaults to False.
block -- Specify if the send call will block until a
response is received, or a timeout occurs.
Defaults to True.
@@ -431,7 +426,7 @@ class xep_0050(base_plugin):
sleekxmpp.xmlstream.RESPONSE_TIMEOUT
callback -- Optional reference to a stream handler
function. Will be executed when a reply
- stanza is received.
+ stanza is received if flow=False.
"""
iq = self.xmpp.Iq()
iq['type'] = 'set'
@@ -447,13 +442,24 @@ class xep_0050(base_plugin):
payload = [payload]
for item in payload:
iq['command'].append(item)
- return iq.send(**kwargs)
+ if not flow:
+ return iq.send(**kwargs)
+ else:
+ if kwargs.get('block', True):
+ try:
+ result = iq.send(**kwargs)
+ except IqError as err:
+ result = err.iq
+ self._handle_command_result(result)
+ else:
+ iq.send(block=False, callback=self._handle_command_result)
- def start_command(self, jid, node, session, ifrom=None):
+ def start_command(self, jid, node, session, ifrom=None, block=False):
"""
Initiate executing a command provided by a remote agent.
- The workflow provided is always non-blocking.
+ The default workflow provided is non-blocking, but a blocking
+ version may be used with block=True.
The provided session dictionary should contain:
next -- A handler for processing the command result.
@@ -465,11 +471,14 @@ class xep_0050(base_plugin):
node -- The node for the desired command.
session -- A dictionary of relevant session data.
ifrom -- Optionally specify the sender's JID.
+ block -- If True, block execution until a result
+ is received. Defaults to False.
"""
session['jid'] = jid
session['node'] = node
session['timestamp'] = time.time()
session['payload'] = None
+ session['block'] = block
iq = self.xmpp.Iq()
iq['type'] = 'set'
iq['to'] = jid
@@ -481,7 +490,14 @@ class xep_0050(base_plugin):
sessionid = 'client:pending_' + iq['id']
session['id'] = sessionid
self.sessions[sessionid] = session
- iq.send(block=False)
+ if session['block']:
+ try:
+ result = iq.send(block=True)
+ except IqError as err:
+ result = err.iq
+ self._handle_command_result(result)
+ else:
+ iq.send(block=False, callback=self._handle_command_result)
def continue_command(self, session):
"""
@@ -499,7 +515,9 @@ class xep_0050(base_plugin):
ifrom=session.get('from', None),
action='next',
payload=session.get('payload', None),
- sessionid=session['id'])
+ sessionid=session['id'],
+ flow=True,
+ block=session['block'])
def cancel_command(self, session):
"""
@@ -517,7 +535,9 @@ class xep_0050(base_plugin):
ifrom=session.get('from', None),
action='cancel',
payload=session.get('payload', None),
- sessionid=session['id'])
+ sessionid=session['id'],
+ flow=True,
+ block=session['block'])
def complete_command(self, session):
"""
@@ -535,7 +555,9 @@ class xep_0050(base_plugin):
ifrom=session.get('from', None),
action='complete',
payload=session.get('payload', None),
- sessionid=session['id'])
+ sessionid=session['id'],
+ flow=True,
+ block=session['block'])
def terminate_command(self, session):
"""