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.
Changes:
May now use underscored method names
form.field is replaced by form['fields']
form.get_fields no longer accepts use_dict parameter, it always
returns an OrderedDict now
form.set_fields will accept either an OrderedDict, or a list
of (var, dict) tuples as before.
Setting the form type to 'submit' will remove extra meta data
from the form fields, leaving just the 'var' and 'value'
Setting the form type to 'cancel' will remove all fields.
Honestly, this is mainly just a demo/proof of concept that we
can handle dependencies and ordering issues with stream features.
DON'T use XEP-0078 if you are able to use the normal SASL method,
which should be the case unless you are dealing with a very old
XMPP server implementation.
Thus, using the XEP-0082 and XEP-0202 introduces a dependency
on the dateutil package (installable using pip install python-dateutil).
Maybe we'll be able to rework how these plugins work to avoid
needing dateutil, but for now this will have to do.
Accepting download requests can be done using:
self['xep_0066'].register_url_handler(handler=self.oob_download)
# Add jid=... to specify a handler for a particular JID for a
# componenent.
def oob_download(self, iq):
if iq['from'] not in self.custom_oob_whitelist:
raise XMPPError('not-authorized')
try:
data = urllib2.urlopen(iq['oob_transfer']['url'])
file = open('oob_download', 'w+')
file.write(data.read())
file.close()
data.close()
except:
raise XMPPError('item-not-found')
For now, session_end is the same as disconnected, but once support is
added later for stream management, the two events will become distinct.
Plugins should add handlers for session_end for cleaning any session
state.
Backward incompatibility alert!
Please see examples/adhoc_provider.py for how to use the new
plugin implementation, or the test examples in the files
tests/test_stream_xep_0050.py and tests/test_stanza_xep_0050.py.
Major changes:
- May now have zero-step commands. Useful if a command is
intended to be a dynamic status report that doesn't
require any user input.
- May use payloads other than data forms, such as a
completely custom stanza type.
- May include multiple payload items, such as multiple
data forms, or a form and a custom stanza type.
- Includes a command user API for calling adhoc commands
on remote agents and managing the workflow.
- Added support for note elements.
Todo:
- Add prev action support.
You may use register_plugin('old_0050') to continue using the
previous XEP-0050 implementation.
We need to check if type="get". otherwise we will send our version
when we will receive the version of the remote entity, and thus
going in an infinite loop.
Can now be used as so:
>>> msg['chat_state']
''
>>> msg
<message />
>>> msg['chat_state'] = 'paused'
>>> msg
<message>
<paused xmlns="http://jabber.org/protocol/chatstates" />
</message>
>>> msg['chat_state']
'paused'
>>> del msg['chat_state']
>>> msg
<message />
Use stanza.values instead of _get/set_stanza_values where used.
ElementBase stanzas can now use .tag
May use class method tag_name() for stanza classes.
ElementBase now has .clear() method.
Methods now accept either an ifrom or mfrom parameter
to specify a 'from' value. Client connections should not
need to use these, but component connections must use them.
Now with dynamic node handling goodness.
Some things are not quite working yet, in particular:
set_items
set_info
set_identities
set_features
And still need more unit tests to round things out.
* check_stanza does not require stanza_class parameter. Introspection!
* check_message, check_iq, and check_presence removed -- use check
instead.
* stream_send_stanza, stream_send_message, stream_send_iq, and
stream_send_presence removed -- use send instead.
* Use recv instead of recv_message, recv_presence, etc.
* check_jid instead of check_JID
* stream_start may accept multi=True to return a new SleekTest instance
for testing multiple streams at once.
xep_0030 still referenced event_handlers. Added the method event_handled
which will return the number of registered handlers for an event to
resolve the issue.
It is now possible to ask for "any number of history stanzas" when
joining a muc (with history=None).
Also we use "maxchars" when asking NO history ("0") since it's a MUST in
the XEP.
And you can specify a message when leaving a MUC.
Forms have default type of 'form'
setFields now uses a list of tuples instead of a dictionary because ordering is important.
getFields defaults to returning a list of tuples, but the use_dict parameter can change that
Chat states may be set using:
msg['chat_state'].active()
msg['chat_state'].composing()
msg['chat_state'].gone()
msg['chat_state'].inactive()
msg['chat_state'].paused()
Checking a chat state can be done with either:
msg['chat_state'].getState()
msg['chat_state'].name
When a message with a chat state is receieved, the following events
may occur:
chatstate_active
chatstate_composing
chatstate_gone
chatstate_inactive
chatstate_paused
where the event data is the message stanza. Note that currently these
events are also triggered for messages sent by SleekXMPP, not just those
received.
Four new events have been added:
disco_info - A disco#info result has been received
disco_info_request - A disco#info request has been received
disco_items - A disco#items result has been received
disco_items_request - A disco#items request has been received
For disco_info_request and disco_items_request two default handlers are registered. These handlers will only run if they are the only handler for these two events so that multiple responses are not returned and cause errors.
In your own handlers for these two events, you can call the default handlers to preserve the static node behaviour as so:
self.plugin['xep_0030'].handle_disco_info(iq, True)
The forwarded=True will disable the check for other registered handlers.
Agents can now dynamically respond to disco requests by using these events.
(cherry picked from commit 0fc3381492a8bd75e6a9858539a972334881d8ff)
* added stanza.keys()
* stanza.getValues() now return substanzas and plugins
* stanza.setValues() now can read substanzas and plugins
* stanzas can now be iterable if stanza.subitem is set to a class
* added stanza unhandled (unhandled iqs now reply with feature-not-implemented)
* added stanza exceptions (stanzas may now reply with exceptions when their handler raises an exception)
* sleekxmpp no longer spawns threads for callback handlers -- there are now two threads: one for handlers and one for reading. callback handlers can get results from the read queue directly with the "wait" handler which is used in .send() for the reply catching argument.