From 9307a6915f9e7e9d34dc561021e7dd10fb3cf5cd Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Sat, 23 Jun 2012 22:30:24 -0700 Subject: Add notes to echo_client.py example on working with Facebook and MSN. --- examples/echo_client.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) 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 -- cgit v1.2.3 From a26a8bd79cc24d29ca3cff0640d8b831f8c84bd3 Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Sat, 30 Jun 2012 17:40:11 -0700 Subject: Bump version to 1.1.8 --- README.rst | 2 +- sleekxmpp/version.py | 4 ++-- 2 files changed, 3 insertions(+), 3 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 `_ + - `1.1.8 `_ **Develop Releases** - `Latest Develop Version `_ 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) -- cgit v1.2.3 From 88b5e60807d5e07e4da1a07042d3b66fe9e98701 Mon Sep 17 00:00:00 2001 From: Jay Farrimond Date: Thu, 5 Jul 2012 13:30:33 -0700 Subject: only log cert errors if not handled by user --- sleekxmpp/xmlstream/xmlstream.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sleekxmpp/xmlstream/xmlstream.py b/sleekxmpp/xmlstream/xmlstream.py index 321e2694..3baa5b80 100644 --- a/sleekxmpp/xmlstream/xmlstream.py +++ b/sleekxmpp/xmlstream/xmlstream.py @@ -537,8 +537,8 @@ class XMLStream(object): try: cert.verify(self._expected_server_name, self._der_cert) except cert.CertificateError as err: - log.error(err.message) if not self.event_handled('ssl_invalid_cert'): + log.error(err.message) self.disconnect(send_close=False) else: self.event('ssl_invalid_cert', @@ -828,8 +828,8 @@ class XMLStream(object): try: cert.verify(self._expected_server_name, self._der_cert) except cert.CertificateError as err: - log.error(err.message) if not self.event_handled('ssl_invalid_cert'): + log.error(err.message) self.disconnect(self.auto_reconnect, send_close=False) else: self.event('ssl_invalid_cert', pem_cert, direct=True) -- cgit v1.2.3 From 6819b57353cd7d2f7f7b2b31fb849f1c0a566f00 Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Fri, 6 Jul 2012 11:05:47 -0700 Subject: Handle converting None to byte data (b''). --- sleekxmpp/thirdparty/suelta/util.py | 3 +++ 1 file changed, 3 insertions(+) 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) -- cgit v1.2.3 From 4a4a03858e87df15b0722e1c8951d5b8592a346a Mon Sep 17 00:00:00 2001 From: Jay Farrimond Date: Fri, 6 Jul 2012 13:50:15 -0700 Subject: dereference iq stanza only once for roster processing --- sleekxmpp/clientxmpp.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sleekxmpp/clientxmpp.py b/sleekxmpp/clientxmpp.py index 7f606de7..03070b06 100644 --- a/sleekxmpp/clientxmpp.py +++ b/sleekxmpp/clientxmpp.py @@ -270,8 +270,9 @@ class ClientXMPP(BaseXMPP): roster = self.client_roster if iq['roster']['ver']: roster.version = iq['roster']['ver'] - for jid in iq['roster']['items']: - item = iq['roster']['items'][jid] + items = iq['roster']['items'] + for jid in items: + item = items[jid] roster[jid]['name'] = item['name'] roster[jid]['groups'] = item['groups'] roster[jid]['from'] = item['subscription'] in ['from', 'both'] -- cgit v1.2.3 From 5af2f62c049825a5f606b7041fa7e6f918d8486c Mon Sep 17 00:00:00 2001 From: Erik Larsson Date: Sun, 8 Jul 2012 22:06:08 +0200 Subject: Make sure that the last RSM stanza is returned from the iterator --- sleekxmpp/plugins/xep_0059/rsm.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sleekxmpp/plugins/xep_0059/rsm.py b/sleekxmpp/plugins/xep_0059/rsm.py index 9335ed22..d4218202 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'] -- cgit v1.2.3 From 7d20f0e9a6cbb9d45b167aca8563d45baf2a112a Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Mon, 9 Jul 2012 22:21:40 -0700 Subject: Fix missing import in xep_0256 plugin. --- sleekxmpp/plugins/xep_0256.py | 1 + 1 file changed, 1 insertion(+) diff --git a/sleekxmpp/plugins/xep_0256.py b/sleekxmpp/plugins/xep_0256.py index 265a5da8..e2ec936c 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 -- cgit v1.2.3 From 1baae1b81ef0765c0f069e67911d7c5224bb4800 Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Mon, 9 Jul 2012 22:22:05 -0700 Subject: Fix issues of disco info leaking between entities with the same bare JIDs. To ensure that disco info, or any settings which depend on the bound JID, are correct, only set such information on or after the session_bound event has fired. --- sleekxmpp/api.py | 4 ++-- sleekxmpp/plugins/xep_0030/disco.py | 16 ++++------------ sleekxmpp/plugins/xep_0030/static.py | 5 +---- sleekxmpp/plugins/xep_0115/caps.py | 5 +++-- 4 files changed, 10 insertions(+), 20 deletions(-) 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/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_0115/caps.py b/sleekxmpp/plugins/xep_0115/caps.py index b0cba42d..9c93486b 100644 --- a/sleekxmpp/plugins/xep_0115/caps.py +++ b/sleekxmpp/plugins/xep_0115/caps.py @@ -78,11 +78,12 @@ class XEP_0115(BasePlugin): 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 -- cgit v1.2.3 From 99701c947e4cf969c5c7a226cdfd56eaf4f0e0d4 Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Mon, 9 Jul 2012 22:59:26 -0700 Subject: Prevent None from being added to the schedule from a timing issue. --- sleekxmpp/xmlstream/scheduler.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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, -- cgit v1.2.3 From 46f49c7a12c3e00bb6e6b38e5e3aba5394aea931 Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Tue, 10 Jul 2012 01:35:25 -0700 Subject: Add method to unregister stream features. --- sleekxmpp/clientxmpp.py | 6 ++++++ 1 file changed, 6 insertions(+) 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. -- cgit v1.2.3 From a347cf625ade5b3cdea0a37ababebe754f580276 Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Tue, 10 Jul 2012 01:35:57 -0700 Subject: Add session_bind_event threading event. --- sleekxmpp/basexmpp.py | 5 +++++ sleekxmpp/componentxmpp.py | 2 ++ sleekxmpp/features/feature_bind/bind.py | 3 ++- 3 files changed, 9 insertions(+), 1 deletion(-) 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/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') -- cgit v1.2.3 From 8dcb441f440ea4c65b4f5d02ed682081f28af11c Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Tue, 10 Jul 2012 01:36:21 -0700 Subject: Add default plugin session_bind handler. All plugins may now simply define a session_bind method where disco features and other actions which require the bound JID may be done. --- sleekxmpp/plugins/base.py | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) 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. -- cgit v1.2.3 From 5df3839b7a8b1a3ca47f057865a52fe7a3f30229 Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Tue, 10 Jul 2012 01:37:23 -0700 Subject: Add method to remove a filter. --- sleekxmpp/xmlstream/xmlstream.py | 4 ++++ 1 file changed, 4 insertions(+) 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. -- cgit v1.2.3 From e8a3e92ceb17d57ae95efd2a3fe7ed82c6ce2a2f Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Tue, 10 Jul 2012 01:37:44 -0700 Subject: Update plugins to use session_bind handler for disco, and use plugin_end --- sleekxmpp/plugins/xep_0004/dataforms.py | 7 ++++++- sleekxmpp/plugins/xep_0012/last_activity.py | 11 ++++++++--- sleekxmpp/plugins/xep_0027/gpg.py | 7 +++++++ sleekxmpp/plugins/xep_0033/addresses.py | 9 +++++++-- sleekxmpp/plugins/xep_0047/ibb.py | 7 +++++++ sleekxmpp/plugins/xep_0050/adhoc.py | 14 ++++++++++++++ sleekxmpp/plugins/xep_0054/vcard_temp.py | 8 +++++++- sleekxmpp/plugins/xep_0059/rsm.py | 7 ++++++- sleekxmpp/plugins/xep_0060/pubsub.py | 7 +++++++ sleekxmpp/plugins/xep_0066/oob.py | 6 ++++++ sleekxmpp/plugins/xep_0077/register.py | 8 +++++--- sleekxmpp/plugins/xep_0078/legacyauth.py | 3 +++ sleekxmpp/plugins/xep_0080/geoloc.py | 7 +++++-- sleekxmpp/plugins/xep_0084/avatar.py | 9 +++++++-- sleekxmpp/plugins/xep_0085/chat_states.py | 4 ++++ sleekxmpp/plugins/xep_0092/version.py | 5 +++++ sleekxmpp/plugins/xep_0107/user_mood.py | 6 ++++++ sleekxmpp/plugins/xep_0108/user_activity.py | 6 +++++- sleekxmpp/plugins/xep_0115/caps.py | 15 +++++++++++++-- sleekxmpp/plugins/xep_0118/user_tune.py | 6 +++++- sleekxmpp/plugins/xep_0128/extended_disco.py | 2 -- sleekxmpp/plugins/xep_0153/vcard_avatar.py | 9 +++++++++ sleekxmpp/plugins/xep_0163.py | 2 +- sleekxmpp/plugins/xep_0172/user_nick.py | 6 ++++++ sleekxmpp/plugins/xep_0184/receipt.py | 7 +++++++ sleekxmpp/plugins/xep_0198/stream_management.py | 21 +++++++++++++++++++++ sleekxmpp/plugins/xep_0199/ping.py | 10 ++++++++++ sleekxmpp/plugins/xep_0202/time.py | 5 +++++ sleekxmpp/plugins/xep_0224/attention.py | 5 +++++ sleekxmpp/plugins/xep_0231/bob.py | 11 +++++++++-- sleekxmpp/plugins/xep_0249/invite.py | 5 +++++ sleekxmpp/plugins/xep_0256.py | 4 ++++ sleekxmpp/plugins/xep_0258/security_labels.py | 8 ++++++-- 33 files changed, 221 insertions(+), 26 deletions(-) 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_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 d4218202..59cfc10b 100644 --- a/sleekxmpp/plugins/xep_0059/rsm.py +++ b/sleekxmpp/plugins/xep_0059/rsm.py @@ -114,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 9c93486b..8ce10edb 100644 --- a/sleekxmpp/plugins/xep_0115/caps.py +++ b/sleekxmpp/plugins/xep_0115/caps.py @@ -73,8 +73,6 @@ 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) @@ -91,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_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 e2ec936c..dd407fff 100644 --- a/sleekxmpp/plugins/xep_0256.py +++ b/sleekxmpp/plugins/xep_0256.py @@ -36,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() -- cgit v1.2.3 From 51fee28bf4941dfcb2471aea0b1ed8b69a4128d6 Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Mon, 16 Jul 2012 19:38:50 -0700 Subject: Add a warning log if dnspython is not found for SRV lookup. Closes issue #183 --- sleekxmpp/xmlstream/resolver.py | 1 + 1 file changed, 1 insertion(+) 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) -- cgit v1.2.3 From f6edaa56a6e91f7104cd63e5d48b39d4ca7e09f2 Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Mon, 16 Jul 2012 20:10:14 -0700 Subject: Add plugin for XEP-0191: Simple Communications Blocking --- setup.py | 1 + sleekxmpp/plugins/__init__.py | 1 + sleekxmpp/plugins/xep_0191/__init__.py | 15 ++++++ sleekxmpp/plugins/xep_0191/blocking.py | 83 ++++++++++++++++++++++++++++++++++ sleekxmpp/plugins/xep_0191/stanza.py | 50 ++++++++++++++++++++ 5 files changed, 150 insertions(+) create mode 100644 sleekxmpp/plugins/xep_0191/__init__.py create mode 100644 sleekxmpp/plugins/xep_0191/blocking.py create mode 100644 sleekxmpp/plugins/xep_0191/stanza.py diff --git a/setup.py b/setup.py index 71973ceb..6d0891a6 100755 --- a/setup.py +++ b/setup.py @@ -85,6 +85,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/plugins/__init__.py b/sleekxmpp/plugins/__init__.py index 1466a274..abaeb307 100644 --- a/sleekxmpp/plugins/__init__.py +++ b/sleekxmpp/plugins/__init__.py @@ -46,6 +46,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/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' -- cgit v1.2.3