aboutsummaryrefslogtreecommitdiffstats
path: root/sleekxmpp/xmlstream/handler
diff options
context:
space:
mode:
authorThibaut Horel <thibaut.horel@gmail.com>2010-11-08 00:59:14 +0100
committerThibaut Horel <thibaut.horel@gmail.com>2010-11-08 00:59:14 +0100
commitb0a2a305028bf284fc5dcf7e1a696d85787f128f (patch)
treee6463e36e381b4342b7c864200a3482cca182618 /sleekxmpp/xmlstream/handler
parentb8499306ce329ca3881b1d1dfc3362a3a5c115d0 (diff)
downloadalias-b0a2a305028bf284fc5dcf7e1a696d85787f128f.tar.gz
Add the sleekxmpp library (will be added as a submodule later)
Diffstat (limited to 'sleekxmpp/xmlstream/handler')
-rw-r--r--sleekxmpp/xmlstream/handler/__init__.py14
-rw-r--r--sleekxmpp/xmlstream/handler/base.py89
-rw-r--r--sleekxmpp/xmlstream/handler/callback.py84
-rw-r--r--sleekxmpp/xmlstream/handler/waiter.py98
-rw-r--r--sleekxmpp/xmlstream/handler/xmlcallback.py36
-rw-r--r--sleekxmpp/xmlstream/handler/xmlwaiter.py33
6 files changed, 354 insertions, 0 deletions
diff --git a/sleekxmpp/xmlstream/handler/__init__.py b/sleekxmpp/xmlstream/handler/__init__.py
new file mode 100644
index 0000000..7bcf0b7
--- /dev/null
+++ b/sleekxmpp/xmlstream/handler/__init__.py
@@ -0,0 +1,14 @@
+"""
+ SleekXMPP: The Sleek XMPP Library
+ Copyright (C) 2010 Nathanael C. Fritz
+ This file is part of SleekXMPP.
+
+ See the file LICENSE for copying permission.
+"""
+
+from sleekxmpp.xmlstream.handler.callback import Callback
+from sleekxmpp.xmlstream.handler.waiter import Waiter
+from sleekxmpp.xmlstream.handler.xmlcallback import XMLCallback
+from sleekxmpp.xmlstream.handler.xmlwaiter import XMLWaiter
+
+__all__ = ['Callback', 'Waiter', 'XMLCallback', 'XMLWaiter']
diff --git a/sleekxmpp/xmlstream/handler/base.py b/sleekxmpp/xmlstream/handler/base.py
new file mode 100644
index 0000000..9c704ec
--- /dev/null
+++ b/sleekxmpp/xmlstream/handler/base.py
@@ -0,0 +1,89 @@
+"""
+ SleekXMPP: The Sleek XMPP Library
+ Copyright (C) 2010 Nathanael C. Fritz
+ This file is part of SleekXMPP.
+
+ See the file LICENSE for copying permission.
+"""
+
+
+class BaseHandler(object):
+
+ """
+ Base class for stream handlers. Stream handlers are matched with
+ incoming stanzas so that the stanza may be processed in some way.
+ Stanzas may be matched with multiple handlers.
+
+ Handler execution may take place in two phases. The first is during
+ the stream processing itself. The second is after stream processing
+ and during SleekXMPP's main event loop. The prerun method is used
+ for execution during stream processing, and the run method is used
+ during the main event loop.
+
+ Attributes:
+ name -- The name of the handler.
+ stream -- The stream this handler is assigned to.
+
+ Methods:
+ match -- Compare a stanza with the handler's matcher.
+ prerun -- Handler execution during stream processing.
+ run -- Handler execution during the main event loop.
+ check_delete -- Indicate if the handler may be removed from use.
+ """
+
+ def __init__(self, name, matcher, stream=None):
+ """
+ Create a new stream handler.
+
+ Arguments:
+ name -- The name of the handler.
+ matcher -- A matcher object from xmlstream.matcher that will be
+ used to determine if a stanza should be accepted by
+ this handler.
+ stream -- The XMLStream instance the handler should monitor.
+ """
+ self.checkDelete = self.check_delete
+
+ self.name = name
+ self.stream = stream
+ self._destroy = False
+ self._payload = None
+ self._matcher = matcher
+ if stream is not None:
+ stream.registerHandler(self)
+
+ def match(self, xml):
+ """
+ Compare a stanza or XML object with the handler's matcher.
+
+ Arguments
+ xml -- An XML or stanza object.
+ """
+ return self._matcher.match(xml)
+
+ def prerun(self, payload):
+ """
+ Prepare the handler for execution while the XML stream is being
+ processed.
+
+ Arguments:
+ payload -- A stanza object.
+ """
+ self._payload = payload
+
+ def run(self, payload):
+ """
+ Execute the handler after XML stream processing and during the
+ main event loop.
+
+ Arguments:
+ payload -- A stanza object.
+ """
+ self._payload = payload
+
+ def check_delete(self):
+ """
+ Check if the handler should be removed from the list of stream
+ handlers.
+ """
+ return self._destroy
diff --git a/sleekxmpp/xmlstream/handler/callback.py b/sleekxmpp/xmlstream/handler/callback.py
new file mode 100644
index 0000000..f0a7285
--- /dev/null
+++ b/sleekxmpp/xmlstream/handler/callback.py
@@ -0,0 +1,84 @@
+"""
+ SleekXMPP: The Sleek XMPP Library
+ Copyright (C) 2010 Nathanael C. Fritz
+ This file is part of SleekXMPP.
+
+ See the file LICENSE for copying permission.
+"""
+
+from sleekxmpp.xmlstream.handler.base import BaseHandler
+
+
+class Callback(BaseHandler):
+
+ """
+ The Callback handler will execute a callback function with
+ matched stanzas.
+
+ The handler may execute the callback either during stream
+ processing or during the main event loop.
+
+ Callback functions are all executed in the same thread, so be
+ aware if you are executing functions that will block for extended
+ periods of time. Typically, you should signal your own events using the
+ SleekXMPP object's event() method to pass the stanza off to a threaded
+ event handler for further processing.
+
+ Methods:
+ prerun -- Overrides BaseHandler.prerun
+ run -- Overrides BaseHandler.run
+ """
+
+ def __init__(self, name, matcher, pointer, thread=False,
+ once=False, instream=False, stream=None):
+ """
+ Create a new callback handler.
+
+ Arguments:
+ name -- The name of the handler.
+ matcher -- A matcher object for matching stanza objects.
+ pointer -- The function to execute during callback.
+ thread -- DEPRECATED. Remains only for backwards compatibility.
+ once -- Indicates if the handler should be used only
+ once. Defaults to False.
+ instream -- Indicates if the callback should be executed
+ during stream processing instead of in the
+ main event loop.
+ stream -- The XMLStream instance this handler should monitor.
+ """
+ BaseHandler.__init__(self, name, matcher, stream)
+ self._pointer = pointer
+ self._once = once
+ self._instream = instream
+
+ def prerun(self, payload):
+ """
+ Execute the callback during stream processing, if
+ the callback was created with instream=True.
+
+ Overrides BaseHandler.prerun
+
+ Arguments:
+ payload -- The matched stanza object.
+ """
+ BaseHandler.prerun(self, payload)
+ if self._instream:
+ self.run(payload, True)
+
+ def run(self, payload, instream=False):
+ """
+ Execute the callback function with the matched stanza payload.
+
+ Overrides BaseHandler.run
+
+ Arguments:
+ payload -- The matched stanza object.
+ instream -- Force the handler to execute during
+ stream processing. Used only by prerun.
+ Defaults to False.
+ """
+ if not self._instream or instream:
+ BaseHandler.run(self, payload)
+ self._pointer(payload)
+ if self._once:
+ self._destroy = True
diff --git a/sleekxmpp/xmlstream/handler/waiter.py b/sleekxmpp/xmlstream/handler/waiter.py
new file mode 100644
index 0000000..8072022
--- /dev/null
+++ b/sleekxmpp/xmlstream/handler/waiter.py
@@ -0,0 +1,98 @@
+"""
+ SleekXMPP: The Sleek XMPP Library
+ Copyright (C) 2010 Nathanael C. Fritz
+ This file is part of SleekXMPP.
+
+ See the file LICENSE for copying permission.
+"""
+
+import logging
+try:
+ import queue
+except ImportError:
+ import Queue as queue
+
+from sleekxmpp.xmlstream import StanzaBase, RESPONSE_TIMEOUT
+from sleekxmpp.xmlstream.handler.base import BaseHandler
+
+
+class Waiter(BaseHandler):
+
+ """
+ The Waiter handler allows an event handler to block
+ until a particular stanza has been received. The handler
+ will either be given the matched stanza, or False if the
+ waiter has timed out.
+
+ Methods:
+ check_delete -- Overrides BaseHandler.check_delete
+ prerun -- Overrides BaseHandler.prerun
+ run -- Overrides BaseHandler.run
+ wait -- Wait for a stanza to arrive and return it to
+ an event handler.
+ """
+
+ def __init__(self, name, matcher, stream=None):
+ """
+ Create a new Waiter.
+
+ Arguments:
+ name -- The name of the waiter.
+ matcher -- A matcher object to detect the desired stanza.
+ stream -- Optional XMLStream instance to monitor.
+ """
+ BaseHandler.__init__(self, name, matcher, stream=stream)
+ self._payload = queue.Queue()
+
+ def prerun(self, payload):
+ """
+ Store the matched stanza.
+
+ Overrides BaseHandler.prerun
+
+ Arguments:
+ payload -- The matched stanza object.
+ """
+ self._payload.put(payload)
+
+ def run(self, payload):
+ """
+ Do not process this handler during the main event loop.
+
+ Overrides BaseHandler.run
+
+ Arguments:
+ payload -- The matched stanza object.
+ """
+ pass
+
+ def wait(self, timeout=RESPONSE_TIMEOUT):
+ """
+ Block an event handler while waiting for a stanza to arrive.
+
+ Be aware that this will impact performance if called from a
+ non-threaded event handler.
+
+ Will return either the received stanza, or False if the waiter
+ timed out.
+
+ Arguments:
+ timeout -- The number of seconds to wait for the stanza to
+ arrive. Defaults to the global default timeout
+ value sleekxmpp.xmlstream.RESPONSE_TIMEOUT.
+ """
+ try:
+ stanza = self._payload.get(True, timeout)
+ except queue.Empty:
+ stanza = False
+ logging.warning("Timed out waiting for %s" % self.name)
+ self.stream.removeHandler(self.name)
+ return stanza
+
+ def check_delete(self):
+ """
+ Always remove waiters after use.
+
+ Overrides BaseHandler.check_delete
+ """
+ return True
diff --git a/sleekxmpp/xmlstream/handler/xmlcallback.py b/sleekxmpp/xmlstream/handler/xmlcallback.py
new file mode 100644
index 0000000..11607ff
--- /dev/null
+++ b/sleekxmpp/xmlstream/handler/xmlcallback.py
@@ -0,0 +1,36 @@
+"""
+ SleekXMPP: The Sleek XMPP Library
+ Copyright (C) 2010 Nathanael C. Fritz
+ This file is part of SleekXMPP.
+
+ See the file LICENSE for copying permission.
+"""
+
+from sleekxmpp.xmlstream.handler import Callback
+
+
+class XMLCallback(Callback):
+
+ """
+ The XMLCallback class is identical to the normal Callback class,
+ except that XML contents of matched stanzas will be processed instead
+ of the stanza objects themselves.
+
+ Methods:
+ run -- Overrides Callback.run
+ """
+
+ def run(self, payload, instream=False):
+ """
+ Execute the callback function with the matched stanza's
+ XML contents, instead of the stanza itself.
+
+ Overrides BaseHandler.run
+
+ Arguments:
+ payload -- The matched stanza object.
+ instream -- Force the handler to execute during
+ stream processing. Used only by prerun.
+ Defaults to False.
+ """
+ Callback.run(self, payload.xml, instream)
diff --git a/sleekxmpp/xmlstream/handler/xmlwaiter.py b/sleekxmpp/xmlstream/handler/xmlwaiter.py
new file mode 100644
index 0000000..5201caf
--- /dev/null
+++ b/sleekxmpp/xmlstream/handler/xmlwaiter.py
@@ -0,0 +1,33 @@
+"""
+ SleekXMPP: The Sleek XMPP Library
+ Copyright (C) 2010 Nathanael C. Fritz
+ This file is part of SleekXMPP.
+
+ See the file LICENSE for copying permission.
+"""
+
+from sleekxmpp.xmlstream.handler import Waiter
+
+
+class XMLWaiter(Waiter):
+
+ """
+ The XMLWaiter class is identical to the normal Waiter class
+ except that it returns the XML contents of the stanza instead
+ of the full stanza object itself.
+
+ Methods:
+ prerun -- Overrides Waiter.prerun
+ """
+
+ def prerun(self, payload):
+ """
+ Store the XML contents of the stanza to return to the
+ waiting event handler.
+
+ Overrides Waiter.prerun
+
+ Arguments:
+ payload -- The matched stanza object.
+ """
+ Waiter.prerun(self, payload.xml)