diff --git a/modules/Dispatch.py b/modules/Dispatch.py new file mode 100644 index 0000000..7cc9711 --- /dev/null +++ b/modules/Dispatch.py @@ -0,0 +1,124 @@ +""" +Dispatch - accept messages and route them to notification channels +Copyright (C) 2012 Brian S. Stephan + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . + +""" + +import MySQLdb as mdb + +from Module import Module + +class Dispatch(Module): + + """Accept messages via XML-RPC, send them to the configured IRC + channel. + + """ + + def db_init(self): + """Set up the database tables, if they don't exist.""" + + version = self.db_module_registered(self.__class__.__name__) + if (version == None): + db = self.get_db() + try: + version = 1 + cur = db.cursor(mdb.cursors.DictCursor) + cur.execute(''' + CREATE TABLE dispatch_item ( + key_ VARCHAR(255) NOT NULL, + dest VARCHAR(255) NOT NULL, + PRIMARY KEY (key_) + ) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci + ''') + + db.commit() + self.db_register_module_version(self.__class__.__name__, + version) + except mdb.Error as e: + db.rollback() + self.log.error("database error trying to create tables") + self.log.exception(e) + raise + finally: cur.close() + + def xmlrpc_init(self): + """Expose dispatching interface.""" + + self.irc.xmlrpc_register_function(self.dispatch_message, "dispatch") + + def register_handlers(self): + """Hook handler functions into the IRC library.""" + + pass + + def unregister_handlers(self): + """Unhook handler functions from the IRC library.""" + + pass + + def dispatch_message(self, key, message): + """Send a message, of the given type, to the configured channel. + + Args: + key the type of message. this will be converted uppercase + message the message to send to the channel + + Returns: + tuple of strings: the destination channel, the string sent to it + + """ + + key, dest = self._get_key_and_destination(key) + + if key is not None and dest is not None: + msg = "[{0:s}] {1:s}".format(key, message) + self.new_sendmsg(dest, msg) + + return dest, msg + + def _get_key_and_destination(self, key): + """Retrieve the configured channel for the given key. + + Args: + key the type of message. this will be converted uppercase + + Returns: + tuple of strings: the key (from the db), the destination channel + + """ + + channel = None + db = self.get_db() + try: + cur = db.cursor(mdb.cursors.DictCursor) + query = ''' + SELECT key_, dest FROM dispatch_item + WHERE key_ = %s + ''' + cur.execute(query, (key.upper(),)) + result = cur.fetchone() + if result: + return result['key_'], result['dest'] + else: + return None, None + except mdb.Error as e: + self.log.error("database error while getting destination") + self.log.exception(e) + raise + finally: cur.close() + +# vi:tabstop=4:expandtab:autoindent