Moved event functions to XMLStream.

This is just a transplant, modifying event to use the main
event queue has not been implemented yet.
This commit is contained in:
Lance Stout 2010-10-01 12:03:58 -04:00
parent fcdd57ce54
commit bb219595a7
2 changed files with 70 additions and 39 deletions

View file

@ -39,8 +39,6 @@ if sys.version_info < (3,0):
class basexmpp(object): class basexmpp(object):
def __init__(self): def __init__(self):
self.id = 0
self.id_lock = threading.Lock()
self.sentpresence = False self.sentpresence = False
self.fulljid = '' self.fulljid = ''
self.resource = '' self.resource = ''
@ -50,7 +48,6 @@ class basexmpp(object):
self.plugin = {} self.plugin = {}
self.auto_authorize = True self.auto_authorize = True
self.auto_subscribe = True self.auto_subscribe = True
self.event_handlers = {}
self.roster = {} self.roster = {}
self.registerHandler(Callback('IM', MatchXMLMask("<message xmlns='%s'><body /></message>" % self.default_ns), self._handleMessage)) self.registerHandler(Callback('IM', MatchXMLMask("<message xmlns='%s'><body /></message>" % self.default_ns), self._handleMessage))
self.registerHandler(Callback('Presence', MatchXMLMask("<presence xmlns='%s' />" % self.default_ns), self._handlePresence)) self.registerHandler(Callback('Presence', MatchXMLMask("<presence xmlns='%s' />" % self.default_ns), self._handlePresence))
@ -148,37 +145,6 @@ class basexmpp(object):
iq.append(query) iq.append(query)
return 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): 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 = self.Message(sto=mto, stype=mtype, sfrom=mfrom)
message['body'] = mbody message['body'] = mbody

View file

@ -182,6 +182,8 @@ class XMLStream(object):
self.__thread = {} self.__thread = {}
self.__root_stanza = [] self.__root_stanza = []
self.__handlers = [] self.__handlers = []
self.__event_handlers = {}
self.__event_handlers_lock = threading.Lock()
self._id = 0 self._id = 0
self._id_lock = threading.Lock() self._id_lock = threading.Lock()
@ -192,8 +194,8 @@ class XMLStream(object):
""" """
Generate and return a new stream ID in hexadecimal form. Generate and return a new stream ID in hexadecimal form.
Many stanzas, handlers, or matchers may require unique Many stanzas, handlers, or matchers may require unique
ID values. Using this method ensures that all new ID values ID values. Using this method ensures that all new ID values
are unique in this stream. are unique in this stream.
""" """
with self._id_lock: with self._id_lock:
@ -377,7 +379,7 @@ class XMLStream(object):
""" """
del self.__root_stanza[stanza_class] 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): threaded=False, filter=False, instream=False):
""" """
A shortcut method for registering a handler using XML masks. A shortcut method for registering a handler using XML masks.
@ -398,7 +400,7 @@ class XMLStream(object):
""" """
if name is None: if name is None:
name = 'add_handler_%s' % self.getNewId() name = 'add_handler_%s' % self.getNewId()
self.registerHandler(XMLCallback(name, MatchXMLMask(mask), pointer, self.registerHandler(XMLCallback(name, MatchXMLMask(mask), pointer,
once=disposable, instream=instream)) once=disposable, instream=instream))
def register_handler(self, handler, before=None, after=None): def register_handler(self, handler, before=None, after=None):
@ -428,6 +430,69 @@ class XMLStream(object):
idx += 1 idx += 1
return False 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, def schedule(self, name, seconds, callback, args=None,
kwargs=None, repeat=False): kwargs=None, repeat=False):
""" """
@ -477,7 +542,7 @@ class XMLStream(object):
data = str(data) data = str(data)
if mask is not None: if mask is not None:
logging.warning("Use of send mask waiters is deprecated.") 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)) MatchXMLMask(mask))
self.register_handler(wait_for) self.register_handler(wait_for)
self.send_raw(data) self.send_raw(data)