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
This commit is contained in:
Brian S. Stephan 2013-01-04 10:17:07 -06:00
parent 30a395bc05
commit 947e82b78f
1 changed files with 124 additions and 0 deletions

124
modules/Dispatch.py Normal file
View File

@ -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 <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."""
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