summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.rst2
-rwxr-xr-xexamples/echo_client.py13
-rwxr-xr-xsetup.py1
-rw-r--r--sleekxmpp/api.py4
-rw-r--r--sleekxmpp/basexmpp.py5
-rw-r--r--sleekxmpp/clientxmpp.py6
-rw-r--r--sleekxmpp/componentxmpp.py2
-rw-r--r--sleekxmpp/features/feature_bind/bind.py3
-rw-r--r--sleekxmpp/plugins/__init__.py1
-rw-r--r--sleekxmpp/plugins/base.py31
-rw-r--r--sleekxmpp/plugins/xep_0004/dataforms.py7
-rw-r--r--sleekxmpp/plugins/xep_0012/last_activity.py11
-rw-r--r--sleekxmpp/plugins/xep_0027/gpg.py7
-rw-r--r--sleekxmpp/plugins/xep_0030/disco.py16
-rw-r--r--sleekxmpp/plugins/xep_0030/static.py5
-rw-r--r--sleekxmpp/plugins/xep_0033/addresses.py9
-rw-r--r--sleekxmpp/plugins/xep_0047/ibb.py7
-rw-r--r--sleekxmpp/plugins/xep_0050/adhoc.py14
-rw-r--r--sleekxmpp/plugins/xep_0054/vcard_temp.py8
-rw-r--r--sleekxmpp/plugins/xep_0059/rsm.py12
-rw-r--r--sleekxmpp/plugins/xep_0060/pubsub.py7
-rw-r--r--sleekxmpp/plugins/xep_0066/oob.py6
-rw-r--r--sleekxmpp/plugins/xep_0077/register.py8
-rw-r--r--sleekxmpp/plugins/xep_0078/legacyauth.py3
-rw-r--r--sleekxmpp/plugins/xep_0080/geoloc.py7
-rw-r--r--sleekxmpp/plugins/xep_0084/avatar.py9
-rw-r--r--sleekxmpp/plugins/xep_0085/chat_states.py4
-rw-r--r--sleekxmpp/plugins/xep_0092/version.py5
-rw-r--r--sleekxmpp/plugins/xep_0107/user_mood.py6
-rw-r--r--sleekxmpp/plugins/xep_0108/user_activity.py6
-rw-r--r--sleekxmpp/plugins/xep_0115/caps.py20
-rw-r--r--sleekxmpp/plugins/xep_0118/user_tune.py6
-rw-r--r--sleekxmpp/plugins/xep_0128/extended_disco.py2
-rw-r--r--sleekxmpp/plugins/xep_0153/vcard_avatar.py9
-rw-r--r--sleekxmpp/plugins/xep_0163.py2
-rw-r--r--sleekxmpp/plugins/xep_0172/user_nick.py6
-rw-r--r--sleekxmpp/plugins/xep_0184/receipt.py7
-rw-r--r--sleekxmpp/plugins/xep_0191/__init__.py15
-rw-r--r--sleekxmpp/plugins/xep_0191/blocking.py83
-rw-r--r--sleekxmpp/plugins/xep_0191/stanza.py50
-rw-r--r--sleekxmpp/plugins/xep_0198/stream_management.py21
-rw-r--r--sleekxmpp/plugins/xep_0199/ping.py10
-rw-r--r--sleekxmpp/plugins/xep_0202/time.py5
-rw-r--r--sleekxmpp/plugins/xep_0224/attention.py5
-rw-r--r--sleekxmpp/plugins/xep_0231/bob.py11
-rw-r--r--sleekxmpp/plugins/xep_0249/invite.py5
-rw-r--r--sleekxmpp/plugins/xep_0256.py5
-rw-r--r--sleekxmpp/plugins/xep_0258/security_labels.py8
-rw-r--r--sleekxmpp/thirdparty/suelta/util.py3
-rw-r--r--sleekxmpp/version.py4
-rw-r--r--sleekxmpp/xmlstream/resolver.py1
-rw-r--r--sleekxmpp/xmlstream/scheduler.py3
-rw-r--r--sleekxmpp/xmlstream/xmlstream.py4
53 files changed, 455 insertions, 55 deletions
diff --git a/README.rst b/README.rst
index 9e99a9bc..c7c4a35e 100644
--- a/README.rst
+++ b/README.rst
@@ -45,7 +45,7 @@ The latest source code for SleekXMPP may be found on `Github
``develop`` branch.
**Latest Release**
- - `1.1.7 <http://github.com/fritzy/SleekXMPP/zipball/1.1.7>`_
+ - `1.1.8 <http://github.com/fritzy/SleekXMPP/zipball/1.1.8>`_
**Develop Releases**
- `Latest Develop Version <http://github.com/fritzy/SleekXMPP/zipball/develop>`_
diff --git a/examples/echo_client.py b/examples/echo_client.py
index 7e553c4a..73990089 100755
--- a/examples/echo_client.py
+++ b/examples/echo_client.py
@@ -122,6 +122,19 @@ if __name__ == '__main__':
xmpp.register_plugin('xep_0060') # PubSub
xmpp.register_plugin('xep_0199') # XMPP Ping
+ # If you are connecting to Facebook and wish to use the
+ # X-FACEBOOK-PLATFORM authentication mechanism, you will need
+ # your API key and an access token. Then you'll set:
+ # xmpp.credentials['api_key'] = 'THE_API_KEY'
+ # xmpp.credentials['access_token'] = 'THE_ACCESS_TOKEN'
+
+ # If you are connecting to MSN, then you will need an
+ # access token, and it does not matter what JID you
+ # specify other than that the domain is 'messenger.live.com',
+ # so '_@messenger.live.com' will work. You can specify
+ # the access token as so:
+ # xmpp.credentials['access_token'] = 'THE_ACCESS_TOKEN'
+
# If you are working with an OpenFire server, you may need
# to adjust the SSL version used:
# xmpp.ssl_version = ssl.PROTOCOL_SSLv3
diff --git a/setup.py b/setup.py
index 7486e106..61d243cc 100755
--- a/setup.py
+++ b/setup.py
@@ -86,6 +86,7 @@ packages = [ 'sleekxmpp',
'sleekxmpp/plugins/xep_0172',
'sleekxmpp/plugins/xep_0184',
'sleekxmpp/plugins/xep_0186',
+ 'sleekxmpp/plugins/xep_0191',
'sleekxmpp/plugins/xep_0198',
'sleekxmpp/plugins/xep_0199',
'sleekxmpp/plugins/xep_0202',
diff --git a/sleekxmpp/api.py b/sleekxmpp/api.py
index 103de2ff..4004f5b7 100644
--- a/sleekxmpp/api.py
+++ b/sleekxmpp/api.py
@@ -99,7 +99,7 @@ class APIRegistry(object):
"""
self._setup(ctype, op)
- if jid in (None, ''):
+ if not jid:
jid = self.xmpp.boundjid
if jid and not isinstance(jid, JID):
jid = JID(jid)
@@ -113,7 +113,7 @@ class APIRegistry(object):
else:
jid = jid.full
else:
- if self.settings[ctype].get('client_bare', True):
+ if self.settings[ctype].get('client_bare', False):
jid = jid.bare
else:
jid = jid.full
diff --git a/sleekxmpp/basexmpp.py b/sleekxmpp/basexmpp.py
index 275275d1..da5b3e41 100644
--- a/sleekxmpp/basexmpp.py
+++ b/sleekxmpp/basexmpp.py
@@ -16,6 +16,7 @@ from __future__ import with_statement, unicode_literals
import sys
import logging
+import threading
import sleekxmpp
from sleekxmpp import plugins, features, roster
@@ -69,8 +70,11 @@ class BaseXMPP(XMLStream):
#: The JabberID (JID) used by this connection.
self.boundjid = JID(jid)
+
self._expected_server_name = self.boundjid.host
+ self.session_bind_event = threading.Event()
+
#: A dictionary mapping plugin names to plugins.
self.plugin = PluginManager(self)
@@ -655,6 +659,7 @@ class BaseXMPP(XMLStream):
def _handle_disconnected(self, event):
"""When disconnected, reset the roster"""
self.roster.reset()
+ self.session_bind_event.clear()
def _handle_stream_error(self, error):
self.event('stream_error', error)
diff --git a/sleekxmpp/clientxmpp.py b/sleekxmpp/clientxmpp.py
index 03070b06..48637dad 100644
--- a/sleekxmpp/clientxmpp.py
+++ b/sleekxmpp/clientxmpp.py
@@ -173,6 +173,12 @@ class ClientXMPP(BaseXMPP):
self._stream_feature_order.append((order, name))
self._stream_feature_order.sort()
+ def unregister_feature(self, name, order):
+ if name in self._stream_feature_handlers:
+ del self._stream_feature_handlers[name]
+ self._stream_feature_order.remove((order, name))
+ self._stream_feature_order.sort()
+
def update_roster(self, jid, name=None, subscription=None, groups=[],
block=True, timeout=None, callback=None):
"""Add or change a roster item.
diff --git a/sleekxmpp/componentxmpp.py b/sleekxmpp/componentxmpp.py
index d69d8266..20748b69 100644
--- a/sleekxmpp/componentxmpp.py
+++ b/sleekxmpp/componentxmpp.py
@@ -156,7 +156,9 @@ class ComponentXMPP(BaseXMPP):
:param xml: The reply handshake stanza.
"""
+ self.session_bind_event.set()
self.session_started_event.set()
+ self.event("session_bind", self.xmpp.boundjid.full, direct=True)
self.event("session_start")
def _handle_probe(self, presence):
diff --git a/sleekxmpp/features/feature_bind/bind.py b/sleekxmpp/features/feature_bind/bind.py
index b828e26f..2253d5ae 100644
--- a/sleekxmpp/features/feature_bind/bind.py
+++ b/sleekxmpp/features/feature_bind/bind.py
@@ -50,7 +50,8 @@ class FeatureBind(BasePlugin):
self.xmpp.set_jid(response['bind']['jid'])
self.xmpp.bound = True
- self.xmpp.event('session_bind', self.xmpp.boundjid, direct=True)
+ self.xmpp.event('session_bind', self.xmpp.boundjid.full, direct=True)
+ self.xmpp.session_bind_event.set()
self.xmpp.features.add('bind')
diff --git a/sleekxmpp/plugins/__init__.py b/sleekxmpp/plugins/__init__.py
index fef7072c..1613ac4d 100644
--- a/sleekxmpp/plugins/__init__.py
+++ b/sleekxmpp/plugins/__init__.py
@@ -47,6 +47,7 @@ __all__ = [
'xep_0172', # User Nickname
'xep_0184', # Message Receipts
'xep_0186', # Invisible Command
+ 'xep_0191', # Simple Communications Blocking
'xep_0198', # Stream Management
'xep_0199', # Ping
'xep_0202', # Entity Time
diff --git a/sleekxmpp/plugins/base.py b/sleekxmpp/plugins/base.py
index 337db2db..26f0c827 100644
--- a/sleekxmpp/plugins/base.py
+++ b/sleekxmpp/plugins/base.py
@@ -167,8 +167,7 @@ class PluginManager(object):
self._plugins[name] = plugin
for dep in plugin.dependencies:
self.enable(dep, enabled=enabled)
- plugin.plugin_init()
- log.debug("Loaded Plugin: %s", plugin.description)
+ plugin._init()
if top_level:
for name in enabled:
@@ -229,7 +228,7 @@ class PluginManager(object):
raise PluginNotFound(name)
for dep in PLUGIN_DEPENDENTS[name]:
self.disable(dep, _disabled)
- plugin.plugin_end()
+ plugin._end()
if name in self._enabled:
self._enabled.remove(name)
del self._plugins[name]
@@ -282,6 +281,28 @@ class BasePlugin(object):
#: configuration settings will be provided as a dictionary.
self.config = config if config is not None else {}
+ def _init(self):
+ """Initialize plugin state, such as registering event handlers.
+
+ Also sets up required event handlers.
+ """
+ if self.xmpp is not None:
+ self.xmpp.add_event_handler('session_bind', self.session_bind)
+ if self.xmpp.session_bind_event.is_set():
+ self.session_bind(self.xmpp.boundjid.full)
+ self.plugin_init()
+ log.debug('Loaded Plugin: %s', self.description)
+
+ def _end(self):
+ """Cleanup plugin state, and prepare for plugin removal.
+
+ Also removes required event handlers.
+ """
+ if self.xmpp is not None:
+ self.xmpp.del_event_handler('session_bind', self.session_bind)
+ self.plugin_end()
+ log.debug('Disabled Plugin: %s' % self.description)
+
def plugin_init(self):
"""Initialize plugin state, such as registering event handlers."""
pass
@@ -290,6 +311,10 @@ class BasePlugin(object):
"""Cleanup plugin state, and prepare for plugin removal."""
pass
+ def session_bind(self, jid):
+ """Initialize plugin state based on the bound JID."""
+ pass
+
def post_init(self):
"""Initialize any cross-plugin state.
diff --git a/sleekxmpp/plugins/xep_0004/dataforms.py b/sleekxmpp/plugins/xep_0004/dataforms.py
index 1097bd29..dde6e6a8 100644
--- a/sleekxmpp/plugins/xep_0004/dataforms.py
+++ b/sleekxmpp/plugins/xep_0004/dataforms.py
@@ -27,7 +27,7 @@ class XEP_0004(BasePlugin):
stanza = stanza
def plugin_init(self):
- self.xmpp.registerHandler(
+ self.xmpp.register_handler(
Callback('Data Form',
StanzaPath('message/form'),
self.handle_form))
@@ -36,6 +36,11 @@ class XEP_0004(BasePlugin):
register_stanza_plugin(Form, FormField, iterable=True)
register_stanza_plugin(Message, Form)
+ def plugin_end(self):
+ self.xmpp.remove_handler('Data Form')
+ self.xmpp['xep_0030'].del_feature(feature='jabber:x:data')
+
+ def session_bind(self, jid):
self.xmpp['xep_0030'].add_feature('jabber:x:data')
def make_form(self, ftype='form', title='', instructions=''):
diff --git a/sleekxmpp/plugins/xep_0012/last_activity.py b/sleekxmpp/plugins/xep_0012/last_activity.py
index b71b6907..8790b47c 100644
--- a/sleekxmpp/plugins/xep_0012/last_activity.py
+++ b/sleekxmpp/plugins/xep_0012/last_activity.py
@@ -37,13 +37,11 @@ class XEP_0012(BasePlugin):
self._last_activities = {}
- self.xmpp.registerHandler(
+ self.xmpp.register_handler(
Callback('Last Activity',
StanzaPath('iq@type=get/last_activity'),
self._handle_get_last_activity))
- self.xmpp.plugin['xep_0030'].add_feature('jabber:iq:last')
-
self.api.register(self._default_get_last_activity,
'get_last_activity',
default=True)
@@ -54,6 +52,13 @@ class XEP_0012(BasePlugin):
'del_last_activity',
default=True)
+ def plugin_end(self):
+ self.xmpp.remove_handler('Last Activity')
+ self.xmpp['xep_0030'].del_feature(feature='jabber:iq:last')
+
+ def session_bind(self, jid):
+ self.xmpp['xep_0030'].add_feature('jabber:iq:last')
+
def begin_idle(self, jid=None, status=None):
self.set_last_activity(jid, 0, status)
diff --git a/sleekxmpp/plugins/xep_0027/gpg.py b/sleekxmpp/plugins/xep_0027/gpg.py
index 7cc128bd..9c6ca078 100644
--- a/sleekxmpp/plugins/xep_0027/gpg.py
+++ b/sleekxmpp/plugins/xep_0027/gpg.py
@@ -79,6 +79,13 @@ class XEP_0027(BasePlugin):
StanzaPath('message/encrypted'),
self._handle_encrypted_message))
+ def plugin_end(self):
+ self.xmpp.remove_handler('Encrypted Message')
+ self.xmpp.remove_handler('Signed Presence')
+ self.xmpp.del_filter('out', self._sign_presence)
+ self.xmpp.del_event_handler('unverified_signed_presence',
+ self._handle_unverified_signed_presence)
+
def _sign_presence(self, stanza):
if isinstance(stanza, Presence):
if stanza['type'] == 'available' or \
diff --git a/sleekxmpp/plugins/xep_0030/disco.py b/sleekxmpp/plugins/xep_0030/disco.py
index 18c1dba2..eeb977b1 100644
--- a/sleekxmpp/plugins/xep_0030/disco.py
+++ b/sleekxmpp/plugins/xep_0030/disco.py
@@ -622,11 +622,7 @@ class XEP_0030(BasePlugin):
if iq['type'] == 'get':
log.debug("Received disco info query from " + \
"<%s> to <%s>.", iq['from'], iq['to'])
- if self.xmpp.is_component:
- jid = iq['to'].full
- else:
- jid = iq['to'].bare
- info = self.api['get_info'](jid,
+ info = self.api['get_info'](iq['to'],
iq['disco_info']['node'],
iq['from'],
iq)
@@ -649,7 +645,7 @@ class XEP_0030(BasePlugin):
ito = iq['to'].full
else:
ito = None
- self.api['cache_info'](iq['from'].full,
+ self.api['cache_info'](iq['from'],
iq['disco_info']['node'],
ito,
iq)
@@ -667,13 +663,9 @@ class XEP_0030(BasePlugin):
if iq['type'] == 'get':
log.debug("Received disco items query from " + \
"<%s> to <%s>.", iq['from'], iq['to'])
- if self.xmpp.is_component:
- jid = iq['to'].full
- else:
- jid = iq['to'].bare
- items = self.api['get_items'](jid,
+ items = self.api['get_items'](iq['to'],
iq['disco_items']['node'],
- iq['from'].full,
+ iq['from'],
iq)
if isinstance(items, Iq):
items.send()
diff --git a/sleekxmpp/plugins/xep_0030/static.py b/sleekxmpp/plugins/xep_0030/static.py
index 8dd412d4..dd5317d1 100644
--- a/sleekxmpp/plugins/xep_0030/static.py
+++ b/sleekxmpp/plugins/xep_0030/static.py
@@ -237,7 +237,7 @@ class StaticDisco(object):
with self.lock:
if not self.node_exists(jid, node):
if not node:
- return DiscoInfo()
+ return DiscoItems()
else:
raise XMPPError(condition='item-not-found')
else:
@@ -424,9 +424,6 @@ class StaticDisco(object):
The data parameter is not used.
"""
with self.lock:
- if isinstance(jid, JID):
- jid = jid.full
-
if not self.node_exists(jid, node, ifrom):
return None
else:
diff --git a/sleekxmpp/plugins/xep_0033/addresses.py b/sleekxmpp/plugins/xep_0033/addresses.py
index 78b9fbb5..13cb7267 100644
--- a/sleekxmpp/plugins/xep_0033/addresses.py
+++ b/sleekxmpp/plugins/xep_0033/addresses.py
@@ -26,7 +26,12 @@ class XEP_0033(BasePlugin):
stanza = stanza
def plugin_init(self):
- self.xmpp['xep_0030'].add_feature(Addresses.namespace)
-
register_stanza_plugin(Message, Addresses)
register_stanza_plugin(Presence, Addresses)
+
+ def plugin_end(self):
+ self.xmpp['xep_0030'].del_feature(feature=Addresses.namespace)
+
+ def session_bind(self, jid):
+ self.xmpp['xep_0030'].add_feature(Addresses.namespace)
+
diff --git a/sleekxmpp/plugins/xep_0047/ibb.py b/sleekxmpp/plugins/xep_0047/ibb.py
index c8a4b5e7..2b8c57d4 100644
--- a/sleekxmpp/plugins/xep_0047/ibb.py
+++ b/sleekxmpp/plugins/xep_0047/ibb.py
@@ -51,6 +51,13 @@ class XEP_0047(BasePlugin):
StanzaPath('iq@type=set/ibb_data'),
self._handle_data))
+ def plugin_end(self):
+ self.xmpp.remove_handler('IBB Open')
+ self.xmpp.remove_handler('IBB Close')
+ self.xmpp.remove_handler('IBB Data')
+ self.xmpp['xep_0030'].del_feature(feature='http://jabber.org/protocol/ibb')
+
+ def session_bind(self, jid):
self.xmpp['xep_0030'].add_feature('http://jabber.org/protocol/ibb')
def _accept_stream(self, iq):
diff --git a/sleekxmpp/plugins/xep_0050/adhoc.py b/sleekxmpp/plugins/xep_0050/adhoc.py
index fb3af7cf..a833221a 100644
--- a/sleekxmpp/plugins/xep_0050/adhoc.py
+++ b/sleekxmpp/plugins/xep_0050/adhoc.py
@@ -110,6 +110,20 @@ class XEP_0050(BasePlugin):
self._handle_command_complete,
threaded=self.threaded)
+ def plugin_end(self):
+ self.xmpp.del_event_handler('command_execute',
+ self._handle_command_start)
+ self.xmpp.del_event_handler('command_next',
+ self._handle_command_next)
+ self.xmpp.del_event_handler('command_cancel',
+ self._handle_command_cancel)
+ self.xmpp.del_event_handler('command_complete',
+ self._handle_command_complete)
+ self.xmpp.remove_handler('Ad-Hoc Execute')
+ self.xmpp['xep_0030'].del_feature(feature=Command.namespace)
+ self.xmpp['xep_0030'].set_items(node=Command.namespace, items=tuple())
+
+ def session_bind(self, jid):
self.xmpp['xep_0030'].add_feature(Command.namespace)
self.xmpp['xep_0030'].set_items(node=Command.namespace, items=tuple())
diff --git a/sleekxmpp/plugins/xep_0054/vcard_temp.py b/sleekxmpp/plugins/xep_0054/vcard_temp.py
index 672f948a..83cbccf8 100644
--- a/sleekxmpp/plugins/xep_0054/vcard_temp.py
+++ b/sleekxmpp/plugins/xep_0054/vcard_temp.py
@@ -37,7 +37,6 @@ class XEP_0054(BasePlugin):
"""
register_stanza_plugin(Iq, VCardTemp)
- self.xmpp['xep_0030'].add_feature('vcard-temp')
self.api.register(self._set_vcard, 'set_vcard', default=True)
self.api.register(self._get_vcard, 'get_vcard', default=True)
@@ -50,6 +49,13 @@ class XEP_0054(BasePlugin):
StanzaPath('iq/vcard_temp'),
self._handle_get_vcard))
+ def plugin_end(self):
+ self.xmpp.remove_handler('VCardTemp')
+ self.xmpp['xep_0030'].del_feature(feature='vcard-temp')
+
+ def session_bind(self, jid):
+ self.xmpp['xep_0030'].add_feature('vcard-temp')
+
def make_vcard(self):
return VCardTemp()
diff --git a/sleekxmpp/plugins/xep_0059/rsm.py b/sleekxmpp/plugins/xep_0059/rsm.py
index 9335ed22..59cfc10b 100644
--- a/sleekxmpp/plugins/xep_0059/rsm.py
+++ b/sleekxmpp/plugins/xep_0059/rsm.py
@@ -47,6 +47,7 @@ class ResultIterator():
self.start = start
self.interface = interface
self.reverse = reverse
+ self._stop = False
def __iter__(self):
return self
@@ -62,6 +63,8 @@ class ResultIterator():
results will be the items before the current page
of items.
"""
+ if self._stop:
+ raise StopIteration
self.query[self.interface]['rsm']['before'] = self.reverse
self.query['id'] = self.query.stream.new_id()
self.query[self.interface]['rsm']['max'] = str(self.amount)
@@ -84,7 +87,7 @@ class ResultIterator():
first = int(r[self.interface]['rsm']['first_index'])
num_items = len(r[self.interface]['substanzas'])
if first + num_items == count:
- raise StopIteration
+ self._stop = True
if self.reverse:
self.start = r[self.interface]['rsm']['first']
@@ -111,10 +114,15 @@ class XEP_0059(BasePlugin):
"""
Start the XEP-0059 plugin.
"""
- self.xmpp['xep_0030'].add_feature(Set.namespace)
register_stanza_plugin(self.xmpp['xep_0030'].stanza.DiscoItems,
self.stanza.Set)
+ def plugin_end(self):
+ self.xmpp['xep_0030'].del_feature(feature=Set.namespace)
+
+ def session_bind(self, jid):
+ self.xmpp['xep_0030'].add_feature(Set.namespace)
+
def iterate(self, stanza, interface):
"""
Create a new result set iterator for a given stanza query.
diff --git a/sleekxmpp/plugins/xep_0060/pubsub.py b/sleekxmpp/plugins/xep_0060/pubsub.py
index 31e59be9..387c5a0f 100644
--- a/sleekxmpp/plugins/xep_0060/pubsub.py
+++ b/sleekxmpp/plugins/xep_0060/pubsub.py
@@ -53,6 +53,13 @@ class XEP_0060(BasePlugin):
StanzaPath('message/pubsub_event/subscription'),
self._handle_event_subscription))
+ def plugin_end(self):
+ self.xmpp.remove_handler('Pubsub Event: Items')
+ self.xmpp.remove_handler('Pubsub Event: Purge')
+ self.xmpp.remove_handler('Pubsub Event: Delete')
+ self.xmpp.remove_handler('Pubsub Event: Configuration')
+ self.xmpp.remove_handler('Pubsub Event: Subscription')
+
def _handle_event_items(self, msg):
"""Raise events for publish and retraction notifications."""
node = msg['pubsub_event']['items']['node']
diff --git a/sleekxmpp/plugins/xep_0066/oob.py b/sleekxmpp/plugins/xep_0066/oob.py
index dc215e83..959c15a2 100644
--- a/sleekxmpp/plugins/xep_0066/oob.py
+++ b/sleekxmpp/plugins/xep_0066/oob.py
@@ -62,6 +62,12 @@ class XEP_0066(BasePlugin):
StanzaPath('iq@type=set/oob_transfer'),
self._handle_transfer))
+ def plugin_end(self):
+ self.xmpp.remove_handler('OOB Transfer')
+ self.xmpp['xep_0030'].del_feature(feature=stanza.OOBTransfer.namespace)
+ self.xmpp['xep_0030'].del_feature(feature=stanza.OOB.namespace)
+
+ def session_bind(self, jid):
self.xmpp['xep_0030'].add_feature(stanza.OOBTransfer.namespace)
self.xmpp['xep_0030'].add_feature(stanza.OOB.namespace)
diff --git a/sleekxmpp/plugins/xep_0077/register.py b/sleekxmpp/plugins/xep_0077/register.py
index 1d04ab25..7f00354b 100644
--- a/sleekxmpp/plugins/xep_0077/register.py
+++ b/sleekxmpp/plugins/xep_0077/register.py
@@ -34,9 +34,7 @@ class XEP_0077(BasePlugin):
register_stanza_plugin(StreamFeatures, RegisterFeature)
register_stanza_plugin(Iq, Register)
- if self.xmpp.is_component:
- pass
- else:
+ if not self.xmpp.is_component:
self.xmpp.register_feature('register',
self._handle_register_feature,
restart=False,
@@ -45,6 +43,10 @@ class XEP_0077(BasePlugin):
register_stanza_plugin(Register, self.xmpp['xep_0004'].stanza.Form)
register_stanza_plugin(Register, self.xmpp['xep_0066'].stanza.OOB)
+ def plugin_end(self):
+ if not self.xmpp.is_component:
+ self.xmpp.unregister_feature('register', self.config.get('order', 50))
+
def _handle_register_feature(self, features):
if 'mechanisms' in self.xmpp.features:
# We have already logged in with an account
diff --git a/sleekxmpp/plugins/xep_0078/legacyauth.py b/sleekxmpp/plugins/xep_0078/legacyauth.py
index 95587843..8ea78fba 100644
--- a/sleekxmpp/plugins/xep_0078/legacyauth.py
+++ b/sleekxmpp/plugins/xep_0078/legacyauth.py
@@ -44,6 +44,9 @@ class XEP_0078(BasePlugin):
register_stanza_plugin(Iq, stanza.IqAuth)
register_stanza_plugin(StreamFeatures, stanza.AuthFeature)
+ def plugin_end(self):
+ self.xmpp.unregister_feature('auth', self.config.get('order', 15))
+
def _handle_auth(self, features):
# If we can or have already authenticated with SASL, do nothing.
if 'mechanisms' in features['features']:
diff --git a/sleekxmpp/plugins/xep_0080/geoloc.py b/sleekxmpp/plugins/xep_0080/geoloc.py
index 28c69a2d..ba594cce 100644
--- a/sleekxmpp/plugins/xep_0080/geoloc.py
+++ b/sleekxmpp/plugins/xep_0080/geoloc.py
@@ -28,8 +28,11 @@ class XEP_0080(BasePlugin):
dependencies = set(['xep_0163'])
stanza = stanza
- def plugin_init(self):
- """Start the XEP-0080 plugin."""
+ def plugin_end(self):
+ self.xmpp['xep_0163'].remove_interest(Geoloc.namespace)
+ self.xmpp['xep_0030'].del_feature(feature=Geoloc.namespace)
+
+ def session_bind(self, jid):
self.xmpp['xep_0163'].register_pep('user_location', Geoloc)
def publish_location(self, **kwargs):
diff --git a/sleekxmpp/plugins/xep_0084/avatar.py b/sleekxmpp/plugins/xep_0084/avatar.py
index 14ab7d97..bbac330a 100644
--- a/sleekxmpp/plugins/xep_0084/avatar.py
+++ b/sleekxmpp/plugins/xep_0084/avatar.py
@@ -28,14 +28,19 @@ class XEP_0084(BasePlugin):
stanza = stanza
def plugin_init(self):
- self.xmpp['xep_0163'].register_pep('avatar_metadata', MetaData)
-
pubsub_stanza = self.xmpp['xep_0060'].stanza
register_stanza_plugin(pubsub_stanza.Item, Data)
register_stanza_plugin(pubsub_stanza.EventItem, Data)
self.xmpp['xep_0060'].map_node_event(Data.namespace, 'avatar_data')
+ def plugin_end(self):
+ self.xmpp['xep_0030'].del_feature(feature=MetaData.namespace)
+ self.xmpp['xep_0163'].remove_interest(MetaData.namespace)
+
+ def session_bind(self, jid):
+ self.xmpp['xep_0163'].register_pep('avatar_metadata', MetaData)
+
def retrieve_avatar(self, jid, id, url=None, ifrom=None, block=True,
callback=None, timeout=None):
return self.xmpp['xep_0060'].get_item(jid, Data.namespace, id,
diff --git a/sleekxmpp/plugins/xep_0085/chat_states.py b/sleekxmpp/plugins/xep_0085/chat_states.py
index d10b317b..17e19d35 100644
--- a/sleekxmpp/plugins/xep_0085/chat_states.py
+++ b/sleekxmpp/plugins/xep_0085/chat_states.py
@@ -43,6 +43,10 @@ class XEP_0085(BasePlugin):
register_stanza_plugin(Message, stanza.Inactive)
register_stanza_plugin(Message, stanza.Paused)
+ def plugin_end(self):
+ self.xmpp.remove_handler('Chat State')
+
+ def session_bind(self, jid):
self.xmpp.plugin['xep_0030'].add_feature(ChatState.namespace)
def _handle_chat_state(self, msg):
diff --git a/sleekxmpp/plugins/xep_0092/version.py b/sleekxmpp/plugins/xep_0092/version.py
index 5e84b2ff..463da158 100644
--- a/sleekxmpp/plugins/xep_0092/version.py
+++ b/sleekxmpp/plugins/xep_0092/version.py
@@ -48,6 +48,11 @@ class XEP_0092(BasePlugin):
register_stanza_plugin(Iq, Version)
+ def plugin_end(self):
+ self.xmpp.remove_handler('Software Version')
+ self.xmpp['xep_0030'].del_feature(feature='jabber:iq:version')
+
+ def session_bind(self, jid):
self.xmpp.plugin['xep_0030'].add_feature('jabber:iq:version')
def _handle_version(self, iq):
diff --git a/sleekxmpp/plugins/xep_0107/user_mood.py b/sleekxmpp/plugins/xep_0107/user_mood.py
index 95e17d45..2d2f3551 100644
--- a/sleekxmpp/plugins/xep_0107/user_mood.py
+++ b/sleekxmpp/plugins/xep_0107/user_mood.py
@@ -32,6 +32,12 @@ class XEP_0107(BasePlugin):
def plugin_init(self):
register_stanza_plugin(Message, UserMood)
+
+ def plugin_end(self):
+ self.xmpp['xep_0030'].del_feature(feature=UserMood.namespace)
+ self.xmpp['xep_0163'].remove_interest(UserMood.namespace)
+
+ def session_bind(self, jid):
self.xmpp['xep_0163'].register_pep('user_mood', UserMood)
def publish_mood(self, value=None, text=None, options=None,
diff --git a/sleekxmpp/plugins/xep_0108/user_activity.py b/sleekxmpp/plugins/xep_0108/user_activity.py
index cd4f48d1..3a2f49b8 100644
--- a/sleekxmpp/plugins/xep_0108/user_activity.py
+++ b/sleekxmpp/plugins/xep_0108/user_activity.py
@@ -26,7 +26,11 @@ class XEP_0108(BasePlugin):
dependencies = set(['xep_0163'])
stanza = stanza
- def plugin_init(self):
+ def plugin_end(self):
+ self.xmpp['xep_0030'].del_feature(feature=UserActivity.namespace)
+ self.xmpp['xep_0163'].remove_interest(UserActivity.namespace)
+
+ def session_bind(self, jid):
self.xmpp['xep_0163'].register_pep('user_activity', UserActivity)
def publish_activity(self, general, specific=None, text=None, options=None,
diff --git a/sleekxmpp/plugins/xep_0115/caps.py b/sleekxmpp/plugins/xep_0115/caps.py
index b0cba42d..8ce10edb 100644
--- a/sleekxmpp/plugins/xep_0115/caps.py
+++ b/sleekxmpp/plugins/xep_0115/caps.py
@@ -73,16 +73,15 @@ class XEP_0115(BasePlugin):
restart=False,
order=10010)
- self.xmpp['xep_0030'].add_feature(stanza.Capabilities.namespace)
-
disco = self.xmpp['xep_0030']
self.static = StaticCaps(self.xmpp, disco.static)
- self.api.settings['client_bare'] = False
- self.api.settings['component_bare'] = False
for op in self._disco_ops:
self.api.register(getattr(self.static, op), op, default=True)
+ for op in ('supports', 'has_identity'):
+ self.xmpp['xep_0030'].api.register(getattr(self.static, op), op)
+
self._run_node_handler = disco._run_node_handler
disco.cache_caps = self.cache_caps
@@ -90,6 +89,19 @@ class XEP_0115(BasePlugin):
disco.assign_verstring = self.assign_verstring
disco.get_verstring = self.get_verstring
+ def plugin_end(self):
+ self.xmpp['xep_0030'].del_feature(feature=stanza.Capabilities.namespace)
+ self.xmpp.del_filter('out', self._filter_add_caps)
+ self.xmpp.del_event_handler('entity_caps', self._process_caps)
+ self.xmpp.remove_handler('Entity Capabilities')
+ if not self.xmpp.is_component:
+ self.xmpp.unregister_feature('caps', 10010)
+ for op in ('supports', 'has_identity'):
+ self.xmpp['xep_0030'].restore_defaults(op)
+
+ def session_bind(self, jid):
+ self.xmpp['xep_0030'].add_feature(stanza.Capabilities.namespace)
+
def _filter_add_caps(self, stanza):
if isinstance(stanza, Presence) and self.broadcast:
ver = self.get_verstring(stanza['from'])
diff --git a/sleekxmpp/plugins/xep_0118/user_tune.py b/sleekxmpp/plugins/xep_0118/user_tune.py
index 53a4f51a..1bb00122 100644
--- a/sleekxmpp/plugins/xep_0118/user_tune.py
+++ b/sleekxmpp/plugins/xep_0118/user_tune.py
@@ -26,7 +26,11 @@ class XEP_0118(BasePlugin):
dependencies = set(['xep_0163'])
stanza = stanza
- def plugin_init(self):
+ def plugin_end(self):
+ self.xmpp['xep_0030'].del_feature(feature=UserTune.namespace)
+ self.xmpp['xep_0163'].remove_interest(UserTune.namespace)
+
+ def session_bind(self, jid):
self.xmpp['xep_0163'].register_pep('user_tune', UserTune)
def publish_tune(self, artist=None, length=None, rating=None, source=None,
diff --git a/sleekxmpp/plugins/xep_0128/extended_disco.py b/sleekxmpp/plugins/xep_0128/extended_disco.py
index 5adc2368..d785affe 100644
--- a/sleekxmpp/plugins/xep_0128/extended_disco.py
+++ b/sleekxmpp/plugins/xep_0128/extended_disco.py
@@ -51,8 +51,6 @@ class XEP_0128(BasePlugin):
register_stanza_plugin(DiscoInfo, Form, iterable=True)
- def post_init(self):
- """Handle cross-plugin dependencies."""
self.disco = self.xmpp['xep_0030']
self.static = StaticExtendedDisco(self.disco.static)
diff --git a/sleekxmpp/plugins/xep_0153/vcard_avatar.py b/sleekxmpp/plugins/xep_0153/vcard_avatar.py
index 3f36d135..1e32595a 100644
--- a/sleekxmpp/plugins/xep_0153/vcard_avatar.py
+++ b/sleekxmpp/plugins/xep_0153/vcard_avatar.py
@@ -45,6 +45,15 @@ class XEP_0153(BasePlugin):
self.api.register(self._set_hash, 'set_hash', default=True)
self.api.register(self._get_hash, 'get_hash', default=True)
+ def plugin_end(self):
+ self.xmpp.del_filter('out', self._update_presence)
+ self.xmpp.del_event_handler('session_start', self._start)
+ self.xmpp.del_event_handler('presence_available', self._recv_presence)
+ self.xmpp.del_event_handler('presence_dnd', self._recv_presence)
+ self.xmpp.del_event_handler('presence_xa', self._recv_presence)
+ self.xmpp.del_event_handler('presence_chat', self._recv_presence)
+ self.xmpp.del_event_handler('presence_away', self._recv_presence)
+
def set_avatar(self, jid=None, avatar=None, mtype=None, block=True,
timeout=None, callback=None):
vcard = self.xmpp['xep_0054'].get_vcard(jid, cached=True)
diff --git a/sleekxmpp/plugins/xep_0163.py b/sleekxmpp/plugins/xep_0163.py
index 43d3ad3a..5aa3aef9 100644
--- a/sleekxmpp/plugins/xep_0163.py
+++ b/sleekxmpp/plugins/xep_0163.py
@@ -74,7 +74,7 @@ class XEP_0163(BasePlugin):
be a list of such namespaces.
jid -- Optionally specify the JID.
"""
- if not isinstance(namespace, set) and not isinstance(namespace, list):
+ if not isinstance(namespace, (set, list)):
namespace = [namespace]
for ns in namespace:
diff --git a/sleekxmpp/plugins/xep_0172/user_nick.py b/sleekxmpp/plugins/xep_0172/user_nick.py
index 324407c3..cab13c15 100644
--- a/sleekxmpp/plugins/xep_0172/user_nick.py
+++ b/sleekxmpp/plugins/xep_0172/user_nick.py
@@ -34,6 +34,12 @@ class XEP_0172(BasePlugin):
def plugin_init(self):
register_stanza_plugin(Message, UserNick)
register_stanza_plugin(Presence, UserNick)
+
+ def plugin_end(self):
+ self.xmpp['xep_0030'].del_feature(feature=UserNick.namespace)
+ self.xmpp['xep_0163'].remove_interest(UserNick.namespace)
+
+ def session_bind(self, jid):
self.xmpp['xep_0163'].register_pep('user_nick', UserNick)
def publish_nick(self, nick=None, options=None, ifrom=None, block=True,
diff --git a/sleekxmpp/plugins/xep_0184/receipt.py b/sleekxmpp/plugins/xep_0184/receipt.py
index 83d89269..044fa83f 100644
--- a/sleekxmpp/plugins/xep_0184/receipt.py
+++ b/sleekxmpp/plugins/xep_0184/receipt.py
@@ -48,6 +48,13 @@ class XEP_0184(BasePlugin):
StanzaPath('message/request_receipt'),
self._handle_receipt_request))
+ def plugin_end(self):
+ self.xmpp['xep_0030'].del_feature('urn:xmpp:receipts')
+ self.xmpp.del_filter('out', self._filter_add_receipt_request)
+ self.xmpp.remove_handler('Message Receipt')
+ self.xmpp.remove_handler('Message Receipt Request')
+
+ def session_bind(self, jid):
self.xmpp['xep_0030'].add_feature('urn:xmpp:receipts')
def ack(self, msg):
diff --git a/sleekxmpp/plugins/xep_0191/__init__.py b/sleekxmpp/plugins/xep_0191/__init__.py
new file mode 100644
index 00000000..934ac631
--- /dev/null
+++ b/sleekxmpp/plugins/xep_0191/__init__.py
@@ -0,0 +1,15 @@
+"""
+ SleekXMPP: The Sleek XMPP Library
+ Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
+ This file is part of SleekXMPP.
+
+ See the file LICENSE for copying permission.
+"""
+
+from sleekxmpp.plugins.base import register_plugin
+
+from sleekxmpp.plugins.xep_0191.stanza import Block, Unblock, BlockList
+from sleekxmpp.plugins.xep_0191.blocking import XEP_0191
+
+
+register_plugin(XEP_0191)
diff --git a/sleekxmpp/plugins/xep_0191/blocking.py b/sleekxmpp/plugins/xep_0191/blocking.py
new file mode 100644
index 00000000..0d903acc
--- /dev/null
+++ b/sleekxmpp/plugins/xep_0191/blocking.py
@@ -0,0 +1,83 @@
+"""
+ SleekXMPP: The Sleek XMPP Library
+ Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
+ This file is part of SleekXMPP.
+
+ See the file LICENSE for copying permission.
+"""
+
+import logging
+
+from sleekxmpp import Iq
+from sleekxmpp.plugins import BasePlugin
+from sleekxmpp.xmlstream.handler import Callback
+from sleekxmpp.xmlstream.matcher import StanzaPath
+from sleekxmpp.xmlstream import register_stanza_plugin, JID
+from sleekxmpp.plugins.xep_0191 import stanza, Block, Unblock, BlockList
+
+
+log = logging.getLogger(__name__)
+
+
+class XEP_0191(BasePlugin):
+
+ name = 'xep_0191'
+ description = 'XEP-0191: Simple Communications Blocking'
+ dependencies = set(['xep_0030'])
+ stanza = stanza
+
+ def plugin_init(self):
+ register_stanza_plugin(Iq, BlockList)
+ register_stanza_plugin(Iq, Block)
+ register_stanza_plugin(Iq, Unblock)
+
+ self.xmpp.register_handler(
+ Callback('Blocked Contact',
+ StanzaPath('iq@type=set/block'),
+ self._handle_blocked))
+
+ self.xmpp.register_handler(
+ Callback('Unblocked Contact',
+ StanzaPath('iq@type=set/unblock'),
+ self._handle_unblocked))
+
+ def plugin_end(self):
+ self.xmpp.remove_handler('Blocked Contact')
+ self.xmpp.remove_handler('Unblocked Contact')
+
+ def get_blocked(self, ifrom=None, block=True, timeout=None, callback=None):
+ iq = self.xmpp.Iq()
+ iq['type'] = 'get'
+ iq['from'] = 'ifrom'
+ iq.enable('blocklist')
+ return iq.send(block=block, timeout=timeout, callback=callback)
+
+ def block(self, jids, ifrom=None, block=True, timeout=None, callback=None):
+ iq = self.xmpp.Iq()
+ iq['type'] = 'set'
+ iq['from'] = ifrom
+
+ if not isinstance(jids, (set, list)):
+ jids = [jids]
+
+ iq['block']['items'] = jids
+ return iq.send(block=block, timeout=timeout, callback=callback)
+
+ def unblock(self, jids=None, ifrom=None, block=True, timeout=None, callback=None):
+ iq = self.xmpp.Iq()
+ iq['type'] = 'set'
+ iq['from'] = ifrom
+
+ if jids is None:
+ jids = []
+ if not isinstance(jids, (set, list)):
+ jids = [jids]
+
+ iq['unblock']['items'] = jids
+ return iq.send(block=block, timeout=timeout, callback=callback)
+
+ def _handle_blocked(self, iq):
+ self.xmpp.event('blocked', iq)
+
+ def _handle_unblocked(self, iq):
+ self.xmpp.event('unblocked', iq)
diff --git a/sleekxmpp/plugins/xep_0191/stanza.py b/sleekxmpp/plugins/xep_0191/stanza.py
new file mode 100644
index 00000000..c5a284bd
--- /dev/null
+++ b/sleekxmpp/plugins/xep_0191/stanza.py
@@ -0,0 +1,50 @@
+"""
+ SleekXMPP: The Sleek XMPP Library
+ Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
+ This file is part of SleekXMPP.
+
+ See the file LICENSE for copying permission.
+"""
+
+from sleekxmpp.xmlstream import ET, ElementBase, JID
+
+
+class BlockList(ElementBase):
+ name = 'blocklist'
+ namespace = 'urn:xmpp:blocking'
+ plugin_attrib = 'blocklist'
+ interfaces = set(['items'])
+
+ def get_items(self):
+ result = set()
+ items = self.xml.findall('{%s}item' % self.namespace)
+ if items is not None:
+ for item in items:
+ jid = JID(item.attrib.get('jid', ''))
+ if jid:
+ result.add(jid)
+ return result
+
+ def set_items(self, values):
+ self.del_items()
+ for jid in values:
+ if jid:
+ item = ET.Element('{%s}item' % self.namespace)
+ item.attrib['jid'] = JID(jid).full
+ self.xml.append(item)
+
+ def del_items(self):
+ items = self.xml.findall('{%s}item' % self.namespace)
+ if items is not None:
+ for item in items:
+ self.xml.remove(item)
+
+
+class Block(BlockList):
+ name = 'block'
+ plugin_attrib = 'block'
+
+
+class Unblock(BlockList):
+ name = 'unblock'
+ plugin_attrib = 'unblock'
diff --git a/sleekxmpp/plugins/xep_0198/stream_management.py b/sleekxmpp/plugins/xep_0198/stream_management.py
index 05d5856f..a150ad39 100644
--- a/sleekxmpp/plugins/xep_0198/stream_management.py
+++ b/sleekxmpp/plugins/xep_0198/stream_management.py
@@ -133,6 +133,27 @@ class XEP_0198(BasePlugin):
self.xmpp.add_event_handler('session_end', self.session_end)
+ def plugin_end(self):
+ if self.xmpp.is_component:
+ return
+
+ self.xmpp.unregister_feature('sm', self.config.get('order', 10100))
+ self.xmpp.unregister_feature('sm', self.config.get('resume_order', 9000))
+ self.xmpp.del_event_handler('session_end', self.session_end)
+ self.xmpp.del_filter('in', self._handle_incoming)
+ self.xmpp.del_filter('out_sync', self._handle_outgoing)
+ self.xmpp.remove_handler('Stream Management Enabled')
+ self.xmpp.remove_handler('Stream Management Resumed')
+ self.xmpp.remove_handler('Stream Management Failed')
+ self.xmpp.remove_handler('Stream Management Ack')
+ self.xmpp.remove_handler('Stream Management Request Ack')
+ self.xmpp.remove_stanza(stanza.Enable)
+ self.xmpp.remove_stanza(stanza.Enabled)
+ self.xmpp.remove_stanza(stanza.Resume)
+ self.xmpp.remove_stanza(stanza.Resumed)
+ self.xmpp.remove_stanza(stanza.Ack)
+ self.xmpp.remove_stanza(stanza.RequestAck)
+
def session_end(self, event):
"""Reset stream management state."""
self.enabled.clear()
diff --git a/sleekxmpp/plugins/xep_0199/ping.py b/sleekxmpp/plugins/xep_0199/ping.py
index 851e5ae5..b9d145aa 100644
--- a/sleekxmpp/plugins/xep_0199/ping.py
+++ b/sleekxmpp/plugins/xep_0199/ping.py
@@ -74,6 +74,16 @@ class XEP_0199(BasePlugin):
self.xmpp.add_event_handler('session_end',
self._handle_session_end)
+ def plugin_end(self):
+ self.xmpp['xep_0030'].del_feature(feature=Ping.namespace)
+ self.xmpp.remove_handler('Ping')
+ if self.keepalive:
+ self.xmpp.del_event_handler('session_start',
+ self._handle_keepalive)
+ self.xmpp.del_event_handler('session_end',
+ self._handle_session_end)
+
+ def session_bind(self, jid):
self.xmpp['xep_0030'].add_feature(Ping.namespace)
def _handle_keepalive(self, event):
diff --git a/sleekxmpp/plugins/xep_0202/time.py b/sleekxmpp/plugins/xep_0202/time.py
index 319a9bc5..50af4730 100644
--- a/sleekxmpp/plugins/xep_0202/time.py
+++ b/sleekxmpp/plugins/xep_0202/time.py
@@ -53,6 +53,11 @@ class XEP_0202(BasePlugin):
self._handle_time_request))
register_stanza_plugin(Iq, stanza.EntityTime)
+ def plugin_end(self):
+ self.xmpp['xep_0030'].del_feature(feature='urn:xmpp:time')
+ self.xmpp.remove_handler('Entity Time')
+
+ def session_bind(self, jid):
self.xmpp['xep_0030'].add_feature('urn:xmpp:time')
def _handle_time_request(self, iq):
diff --git a/sleekxmpp/plugins/xep_0224/attention.py b/sleekxmpp/plugins/xep_0224/attention.py
index 6eea5d9d..4e560604 100644
--- a/sleekxmpp/plugins/xep_0224/attention.py
+++ b/sleekxmpp/plugins/xep_0224/attention.py
@@ -39,6 +39,11 @@ class XEP_0224(BasePlugin):
StanzaPath('message/attention'),
self._handle_attention))
+ def plugin_end(self):
+ self.xmpp['xep_0030'].del_feature(feature=stanza.Attention.namespace)
+ self.xmpp.remove_handler('Attention')
+
+ def session_bind(self, jid):
self.xmpp['xep_0030'].add_feature(stanza.Attention.namespace)
def request_attention(self, to, mfrom=None, mbody=''):
diff --git a/sleekxmpp/plugins/xep_0231/bob.py b/sleekxmpp/plugins/xep_0231/bob.py
index f411a8f7..d86a5ddf 100644
--- a/sleekxmpp/plugins/xep_0231/bob.py
+++ b/sleekxmpp/plugins/xep_0231/bob.py
@@ -35,8 +35,6 @@ class XEP_0231(BasePlugin):
def plugin_init(self):
self._cids = {}
- self.xmpp['xep_0030'].add_feature('urn:xmpp:bob')
-
register_stanza_plugin(Iq, BitsOfBinary)
self.xmpp.register_handler(
@@ -58,6 +56,15 @@ class XEP_0231(BasePlugin):
self.api.register(self._set_bob, 'set_bob', default=True)
self.api.register(self._del_bob, 'del_bob', default=True)
+ def plugin_end(self):
+ self.xmpp['xep_0030'].del_feature(feature='urn:xmpp:bob')
+ self.xmpp.remove_handler('Bits of Binary - Iq')
+ self.xmpp.remove_handler('Bits of Binary - Message')
+ self.xmpp.remove_handler('Bits of Binary - Presence')
+
+ def session_bind(self, jid):
+ self.xmpp['xep_0030'].add_feature('urn:xmpp:bob')
+
def set_bob(self, data, mtype, cid=None, max_age=None):
if cid is None:
cid = 'sha1+%s@bob.xmpp.org' % hashlib.sha1(data).hexdigest()
diff --git a/sleekxmpp/plugins/xep_0249/invite.py b/sleekxmpp/plugins/xep_0249/invite.py
index 737684f5..4b7abd4a 100644
--- a/sleekxmpp/plugins/xep_0249/invite.py
+++ b/sleekxmpp/plugins/xep_0249/invite.py
@@ -39,6 +39,11 @@ class XEP_0249(BasePlugin):
register_stanza_plugin(Message, Invite)
+ def plugin_end(self):
+ self.xmpp['xep_0030'].del_feature(feature=Invite.namespace)
+ self.xmpp.remove_handler('Direct MUC Invitations')
+
+ def session_bind(self, jid):
self.xmpp['xep_0030'].add_feature(Invite.namespace)
def _handle_invite(self, msg):
diff --git a/sleekxmpp/plugins/xep_0256.py b/sleekxmpp/plugins/xep_0256.py
index 265a5da8..dd407fff 100644
--- a/sleekxmpp/plugins/xep_0256.py
+++ b/sleekxmpp/plugins/xep_0256.py
@@ -9,6 +9,7 @@
import logging
from sleekxmpp import Presence
+from sleekxmpp.exceptions import XMPPError
from sleekxmpp.plugins import BasePlugin, register_plugin
from sleekxmpp.xmlstream import register_stanza_plugin
@@ -35,6 +36,10 @@ class XEP_0256(BasePlugin):
self._initial_presence = set()
+ def plugin_end(self):
+ self.xmpp.del_filter('out', self._initial_presence_activity)
+ self.xmpp.del_event_handler('connected', self._reset_presence_activity)
+
def _reset_presence_activity(self, e):
self._initial_presence = set()
diff --git a/sleekxmpp/plugins/xep_0258/security_labels.py b/sleekxmpp/plugins/xep_0258/security_labels.py
index e0426f32..439143c1 100644
--- a/sleekxmpp/plugins/xep_0258/security_labels.py
+++ b/sleekxmpp/plugins/xep_0258/security_labels.py
@@ -25,11 +25,15 @@ class XEP_0258(BasePlugin):
stanza = stanza
def plugin_init(self):
- self.xmpp['xep_0030'].add_feature(SecurityLabel.namespace)
-
register_stanza_plugin(Message, SecurityLabel)
register_stanza_plugin(Iq, Catalog)
+ def plugin_end(self):
+ self.xmpp['xep_0030'].del_feature(feature=SecurityLabel.namespace)
+
+ def session_bind(self, jid):
+ self.xmpp['xep_0030'].add_feature(SecurityLabel.namespace)
+
def get_catalog(self, jid, ifrom=None, block=True,
callback=None, timeout=None):
iq = self.xmpp.Iq()
diff --git a/sleekxmpp/thirdparty/suelta/util.py b/sleekxmpp/thirdparty/suelta/util.py
index 7d822a81..cd2439d5 100644
--- a/sleekxmpp/thirdparty/suelta/util.py
+++ b/sleekxmpp/thirdparty/suelta/util.py
@@ -15,6 +15,9 @@ def bytes(text):
:param text: Unicode text to convert to bytes
:rtype: bytes (Python3), str (Python2.6+)
"""
+ if text is None:
+ return b''
+
if sys.version_info < (3, 0):
import __builtin__
return __builtin__.bytes(text)
diff --git a/sleekxmpp/version.py b/sleekxmpp/version.py
index 782a8560..eb39fd68 100644
--- a/sleekxmpp/version.py
+++ b/sleekxmpp/version.py
@@ -9,5 +9,5 @@
# We don't want to have to import the entire library
# just to get the version info for setup.py
-__version__ = '1.1.7'
-__version_info__ = (1, 1, 7, '', 0)
+__version__ = '1.1.8'
+__version_info__ = (1, 1, 8, '', 0)
diff --git a/sleekxmpp/xmlstream/resolver.py b/sleekxmpp/xmlstream/resolver.py
index 455ab8d0..0d7a8c0d 100644
--- a/sleekxmpp/xmlstream/resolver.py
+++ b/sleekxmpp/xmlstream/resolver.py
@@ -254,6 +254,7 @@ def get_SRV(host, port, service, proto='tcp', resolver=None):
by SRV priorities and weights.
"""
if resolver is None:
+ log.warning("DNS: dnspython not found. Can not use SRV lookup.")
return [(host, port)]
log.debug("DNS: Querying SRV records for %s" % host)
diff --git a/sleekxmpp/xmlstream/scheduler.py b/sleekxmpp/xmlstream/scheduler.py
index 70e36f24..f68af081 100644
--- a/sleekxmpp/xmlstream/scheduler.py
+++ b/sleekxmpp/xmlstream/scheduler.py
@@ -172,7 +172,8 @@ class Scheduler(object):
else:
updated = True
self.schedule_lock.acquire()
- self.schedule.append(newtask)
+ if newtask is not None:
+ self.schedule.append(newtask)
finally:
if updated:
self.schedule = sorted(self.schedule,
diff --git a/sleekxmpp/xmlstream/xmlstream.py b/sleekxmpp/xmlstream/xmlstream.py
index 3baa5b80..49f33933 100644
--- a/sleekxmpp/xmlstream/xmlstream.py
+++ b/sleekxmpp/xmlstream/xmlstream.py
@@ -954,6 +954,10 @@ class XMLStream(object):
else:
self.__filters[mode].append(handler)
+ def del_filter(self, mode, handler):
+ """Remove an incoming or outgoing filter."""
+ self.__filters[mode].remove(handler)
+
def add_handler(self, mask, pointer, name=None, disposable=False,
threaded=False, filter=False, instream=False):
"""A shortcut method for registering a handler using XML masks.