From 78a50d02374185e3f06dcee9fc2d2bca1ed1abbe Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Sat, 10 Mar 2012 00:07:56 -0800 Subject: Add support for pubsub notification events. Publishes, retractions, purges, and deletions now raise the events: - pubsub_publish - pubsub_retract - pubsub_purge - pubsub_delete In addition, custom events may be raised based on the node that generated the notification. For example: xmpp['xep_0060'].map_node_event('http://jabber.org/protocol/tune', 'user_tune') will allow for using the events: - user_tune_publish - user_tune_retract - user_tune_purge - user_tune_delete --- sleekxmpp/plugins/xep_0060/pubsub.py | 87 ++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) (limited to 'sleekxmpp/plugins/xep_0060') diff --git a/sleekxmpp/plugins/xep_0060/pubsub.py b/sleekxmpp/plugins/xep_0060/pubsub.py index 9e394ef2..f47bcbfb 100644 --- a/sleekxmpp/plugins/xep_0060/pubsub.py +++ b/sleekxmpp/plugins/xep_0060/pubsub.py @@ -9,6 +9,8 @@ import logging from sleekxmpp.xmlstream import JID +from sleekxmpp.xmlstream.handler import Callback +from sleekxmpp.xmlstream.matcher import StanzaPath from sleekxmpp.plugins.base import base_plugin from sleekxmpp.plugins.xep_0060 import stanza @@ -27,6 +29,91 @@ class xep_0060(base_plugin): self.description = 'Publish-Subscribe' self.stanza = stanza + self.node_event_map = {} + + self.xmpp.register_handler( + Callback('Pubsub Event: Items', + StanzaPath('message/pubsub_event/items'), + self._handle_event_items)) + self.xmpp.register_handler( + Callback('Pubsub Event: Purge', + StanzaPath('message/pubsub_event/purge'), + self._handle_event_purge)) + self.xmpp.register_handler( + Callback('Pubsub Event: Delete', + StanzaPath('message/pubsub_event/delete'), + self._handle_event_delete)) + + def _handle_event_items(self, msg): + """Raise events for publish and retraction notifications.""" + node = msg['pubsub_event']['items']['node'] + + multi = len(msg['pubsub_event']['items']) > 1 + values = {} + if multi: + values = msg.values + del values['pubsub_event'] + + for item in msg['pubsub_event']['items']: + event_name = self.node_event_map.get(node, None) + event_type = 'publish' + if item.name == 'retract': + event_type = 'retract' + + if multi: + condensed = self.xmpp.Message() + condensed.values = values + condensed['pubsub_event']['items']['node'] = node + condensed['pubsub_event']['items'].append(item) + self.xmpp.event('pubsub_%s' % event_type, msg) + if event_name: + self.xmpp.event('%s_%s' % (event_name, event_type), condensed) + else: + self.xmpp.event('pubsub_%s' % event_type, msg) + if event_name: + self.xmpp.event('%s_%s' % (event_name, event_type), msg) + + def _handle_event_purge(self, msg): + """Raise events for node purge notifications.""" + node = msg['pubsub_event']['purge']['node'] + event_name = self.node_event_map.get(node, None) + + self.xmpp.event('pubsub_purge', msg) + if event_name: + self.xmpp.event('%s_purge' % event_name, msg) + + def _handle_event_delete(self, msg): + """Raise events for node deletion notifications.""" + node = msg['pubsub_event']['delete']['node'] + event_name = self.node_event_map.get(node, None) + + self.xmpp.event('pubsub_delete', msg) + if event_name: + self.xmpp.event('%s_delete' % event_name, msg) + + def map_node_event(self, node, event_name): + """ + Map node names to events. + + When a pubsub event is received for the given node, + raise the provided event. + + For example:: + + map_node_event('http://jabber.org/protocol/tune', + 'user_tune') + + will produce the events 'user_tune_publish' and 'user_tune_retract' + when the respective notifications are received from the node + 'http://jabber.org/protocol/tune', among other events. + + Arguments: + node -- The node name to map to an event. + event_name -- The name of the event to raise when a + notification from the given node is received. + """ + self.node_event_map[node] = event_name + def create_node(self, jid, node, config=None, ntype=None, ifrom=None, block=True, callback=None, timeout=None): """ -- cgit v1.2.3