dr.botzo/modules/Dispatch.py

135 lines
4.2 KiB
Python

"""
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 <http://www.gnu.org/licenses/>.
"""
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."""
try:
db = self.get_db()
version = self.db_module_registered(self.__class__.__name__)
if version is None:
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)
if version == 1:
version = 2
cur = db.cursor(mdb.cursors.DictCursor)
cur.execute('''
ALTER TABLE dispatch_item DROP PRIMARY KEY, ADD PRIMARY KEY (key_, dest)
''')
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.encode('utf-8', 'ignore'))
self.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