diff --git a/sleekxmpp/basexmpp.py b/sleekxmpp/basexmpp.py
index 51607d7..927e1fc 100644
--- a/sleekxmpp/basexmpp.py
+++ b/sleekxmpp/basexmpp.py
@@ -39,8 +39,6 @@ if sys.version_info < (3,0):
class basexmpp(object):
def __init__(self):
- self.id = 0
- self.id_lock = threading.Lock()
self.sentpresence = False
self.fulljid = ''
self.resource = ''
@@ -50,7 +48,6 @@ class basexmpp(object):
self.plugin = {}
self.auto_authorize = True
self.auto_subscribe = True
- self.event_handlers = {}
self.roster = {}
self.registerHandler(Callback('IM', MatchXMLMask("" % self.default_ns), self._handleMessage))
self.registerHandler(Callback('Presence', MatchXMLMask("" % self.default_ns), self._handlePresence))
@@ -148,37 +145,6 @@ class basexmpp(object):
iq.append(query)
return query
- def add_event_handler(self, name, pointer, threaded=False, disposable=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 handler for an event."""
- 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, eventdata = {}): # called on an event
- for handler in self.event_handlers.get(name, []):
- handlerdata = copy.copy(eventdata)
- if handler[1]: #if threaded
- #thread.start_new(handler[0], (eventdata,))
- x = threading.Thread(name="Event_%s" % str(handler[0]), target=handler[0], args=(handlerdata,))
- x.start()
- else:
- handler[0](handlerdata)
- if handler[2]: #disposable
- with self.lock:
- self.event_handlers[name].pop(self.event_handlers[name].index(handler))
-
def makeMessage(self, mto, mbody=None, msubject=None, mtype=None, mhtml=None, mfrom=None, mnick=None):
message = self.Message(sto=mto, stype=mtype, sfrom=mfrom)
message['body'] = mbody
diff --git a/sleekxmpp/xmlstream/xmlstream.py b/sleekxmpp/xmlstream/xmlstream.py
index fc6a374..401865c 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)