Can now use len(self.client_roster) to get the number of JIDs in
the roster, and self.client_roster.groups() to get a dict of
groups and the JIDs in those groups.
Form fields now remember their current type if the type is deleted. This
allows for fields to properly format their values if set after the form
has been changed to the 'submit' type.
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.
Sleek loads a few plugins by default, which made it difficult to
configure or even disable them.
Now, if a plugin is registered without any configuration, then
sleek will try finding a configuration in self.plugin_config.
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')
If wait=True, then the disconnect call will block until
the send queue has emptied.
WARNING: Using wait=True when more stanzas are being added to the
queue than can be processed such that the queue is never empty
will cause the disconnect call to block indefinitely without actually
disconnecting.