From 947e82b78fe6dce7e8759b6f620e747bfbc9ca51 Mon Sep 17 00:00:00 2001 From: "Brian S. Stephan" Date: Fri, 4 Jan 2013 10:17:07 -0600 Subject: [PATCH] Dispatch: send messages to channels via XML-RPC keep a collection of key-channel pairs that, when receiving an XML-RPC dispatch message with a key and message, sends the message to the associated channel. this allows for various notification bus style stuff this is the barebones version, there's no IRC admin interaction yet, so all key-channel pairs need to be managed by direct database access. it is possible i won't bother changing this. there are also some not-so-clever assumptions, like that the bot is already in the channel it is trying to speak in --- modules/Dispatch.py | 124 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 modules/Dispatch.py 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