summaryrefslogtreecommitdiff
path: root/sleekxmpp/xmlstream/xmlstream.py
diff options
context:
space:
mode:
Diffstat (limited to 'sleekxmpp/xmlstream/xmlstream.py')
-rw-r--r--sleekxmpp/xmlstream/xmlstream.py75
1 files changed, 70 insertions, 5 deletions
diff --git a/sleekxmpp/xmlstream/xmlstream.py b/sleekxmpp/xmlstream/xmlstream.py
index fc6a374c..401865c6 100644
--- a/sleekxmpp/xmlstream/xmlstream.py
+++ b/sleekxmpp/xmlstream/xmlstream.py
@@ -182,6 +182,8 @@ class XMLStream(object):
self.__thread = {}
self.__root_stanza = []
self.__handlers = []
+ self.__event_handlers = {}
+ self.__event_handlers_lock = threading.Lock()
self._id = 0
self._id_lock = threading.Lock()
@@ -192,8 +194,8 @@ class XMLStream(object):
"""
Generate and return a new stream ID in hexadecimal form.
- Many stanzas, handlers, or matchers may require unique
- ID values. Using this method ensures that all new ID values
+ Many stanzas, handlers, or matchers may require unique
+ ID values. Using this method ensures that all new ID values
are unique in this stream.
"""
with self._id_lock:
@@ -377,7 +379,7 @@ class XMLStream(object):
"""
del self.__root_stanza[stanza_class]
- def add_handler(self, mask, pointer, name=None, disposable=False,
+ 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.
@@ -398,7 +400,7 @@ class XMLStream(object):
"""
if name is None:
name = 'add_handler_%s' % self.getNewId()
- self.registerHandler(XMLCallback(name, MatchXMLMask(mask), pointer,
+ self.registerHandler(XMLCallback(name, MatchXMLMask(mask), pointer,
once=disposable, instream=instream))
def register_handler(self, handler, before=None, after=None):
@@ -428,6 +430,69 @@ class XMLStream(object):
idx += 1
return False
+ def add_event_handler(self, name, pointer,
+ threaded=False, disposable=False):
+ """
+ Add a custom event handler that will be executed whenever
+ its event is manually triggered.
+
+ Arguments:
+ name -- The name of the event that will trigger
+ this handler.
+ pointer -- The function to execute.
+ threaded -- If set to True, the handler will execute
+ in its own thread. Defaults to False.
+ disposable -- If set to True, the handler will be
+ discarded after one use. Defaults to False.
+ """
+ if not name in self.__event_handlers:
+ self.__event_handlers[name] = []
+ self.__event_handlers[name].append((pointer, threaded, disposable))
+
+ def del_event_handler(self, name, pointer):
+ """
+ Remove a function as a handler for an event.
+
+ Arguments:
+ name -- The name of the event.
+ pointer -- The function to remove as a handler.
+ """
+ if not name in self.__event_handlers:
+ return
+
+ # Need to keep handlers that do not use
+ # the given function pointer
+ def filter_pointers(handler):
+ return handler[0] != pointer
+
+ self.__event_handlers[name] = filter(filter_pointers,
+ self.__event_handlers[name])
+
+ def event(self, name, data={}):
+ """
+ Manually trigger a custom event.
+
+ Arguments:
+ name -- The name of the event to trigger.
+ data -- Data that will be passed to each event handler.
+ Defaults to an empty dictionary.
+ """
+ for handler in self.__event_handlers.get(name, []):
+ func, threaded, disposable = handler
+
+ handler_data = copy.copy(data)
+ if threaded:
+ x = threading.Thread(name="Event_%s" % str(func),
+ target=func,
+ args=(handler_data,))
+ x.start()
+ else:
+ func(handler_data)
+ if disposable:
+ with self.__event_handlers_lock:
+ handler_index = self.event_handlers[name].index(handler)
+ self.__event_handlers[name].pop(handler_index)
+
def schedule(self, name, seconds, callback, args=None,
kwargs=None, repeat=False):
"""
@@ -477,7 +542,7 @@ class XMLStream(object):
data = str(data)
if mask is not None:
logging.warning("Use of send mask waiters is deprecated.")
- wait_for = Waiter("SendWait_%s" % self.new_id(),
+ wait_for = Waiter("SendWait_%s" % self.new_id(),
MatchXMLMask(mask))
self.register_handler(wait_for)
self.send_raw(data)