import threading """ Base handler class, which subclasses `threading.Thread' to by default enable threaded handlers. Handlers can be run in parallel this way. """ class Handler(threading.Thread): commands = [] # - Set this to a list/tuple of commands to handle. command = '' # - This is a convenience variable, for single commands. threaded = True # - True/False/None if the thread should be run in parallel. """ Handler-specific initialization: client => The Client object executing this handler. message => The Message object which the handler should handle. """ def __init__(self, client, message, *args, **kwargs): # Initialize super threading.Thread.__init__(self, *args, **kwargs) self.client = client # - Client object self.message = message # - Message object """ Does this handler respond to a certain command? """ def respondsTo(self, command): # Grab a list of commands this handler responds to. commands = [command for command in (list(self.__class__.commands) + self.__class__.command) if command] # Return True/False based on the responsiveness of this handler to a # specific command. if command in commands: return True return False """ A handler group is a simple subclass of a list which provides methods which operate on the entire group of handlers. """ class HandlerGroup(list): """ Invoke handlers in this group associated with the specified command. If no command is specified, then invoke every handler. client => The Client object that is executing the handlers. message => The Message object which the executed handlers will handle. command => String/None: Which handlers to execute. (None means all) Return: HandlerGroup containing handlers that were invoked. """ def invoke(self, client, message, command = None): # Determine which handlers to invoke. if command: handlers = HandlerGroup([handler for handler in self if handler.respondsTo(command)]) else: handlers = self # Start invoking handlers that respond to the given command (or invoke # all of them...) for handler in handlers: thread = handler(client, message) thread.start() if not thread.threaded: thread.join() # Return a HandlerGroup containing handlers that were invoked. return handlers """ Get a normal list, rather than a HandlerGroup instance of handler classes. """ def getList(self): return list(self) """ Default PING message handler. The handler, when invoked will send a PONG message to the server in response to the received PING message. """ class PingHandler(Handler): command = 'ping' # - Indicate that this handler responds to PING. """ Respond to a PING message by sending back a PONG. """ def run(self): ping = self.message ping.pong()