dr.botzo, the IRC bot with Django integration.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

145 lines
4.6 KiB

"""
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
import os
from extlib import irclib
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:
list of all notified targets
"""
notified = []
for key, dest in self._get_key_and_destination(key):
if irclib.is_channel(dest):
msg = "[{0:s}] {1:s}".format(key, message.encode('utf-8', 'ignore'))
self.sendmsg(dest, msg)
notified.append(dest)
elif dest.find('FILE:') == 0:
filename = dest.replace('FILE:', '')
filename = os.path.abspath(filename)
self.log.info("filename: {0:s}".format(filename))
msg = "[{0:s}] {1:s}\n".format(key, message.encode('utf-8', 'ignore'))
with open(filename, 'w') as f:
f.write(msg)
return notified
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:
list of tuple of strings: (the key, the destination channel)
"""
targets = []
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(),))
results = cur.fetchall()
for result in results:
targets.append((result['key_'], result['dest']))
return targets
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