""" Facts - display facts, from within a category, from the database Copyright (C) 2010 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 random import re import MySQLdb as mdb from Module import Module class Facts(Module): """Select a fact from the database. Facts are categorized by a name, which may allow for random selection and so on. """ def __init__(self, irc, config): """Set up XML-RPC methods.""" Module.__init__(self, irc, config) irc.xmlrpc_register_function(self._get_fact, "facts_get") def db_init(self): """Initialize database tables.""" # init the database if module isn't registered 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 facts_facts ( id SERIAL, category VARCHAR(64) NOT NULL, fact LONGTEXT NOT NULL, who VARCHAR(64) NOT NULL, userhost VARCHAR(256) NOT NULL, time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin ''') 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 do(self, connection, event, nick, userhost, what, admin_unlocked): """Add or retrieve a fact from the database.""" db = self.get_db() try: cur = db.cursor(mdb.cursors.DictCursor) match = re.search('^!facts\s+add\s+(\S+)\s+(.*)$', what) if match: category = match.group(1) fact = match.group(2) cur.execute('''INSERT INTO facts_facts (category, fact, who, userhost) VALUES (%s, %s, %s, %s)''', (category, fact, nick, userhost)) db.commit() return self.irc.reply(event, category + ' added.') match = re.search('^!facts\s+(\S+)\s+(.*)$', what) if match: category = match.group(1) regex = match.group(2) return self.irc.reply(event, self._get_fact(category, regex)) match = re.search('^!facts\s+(\S+)$', what) if match: category = match.group(1) return self.irc.reply(event, self._get_fact(category)) except mdb.Error as e: db.rollback() self.log.error("database error during add/retrieve") self.log.exception(e) return self.irc.reply(event, "database error during add/retrieve fact") finally: cur.close() def _get_fact(self, category, search=""): """ Get a fact in the given category from the database. Keyword arguments: category - the fact category to query search - the optional regex to match against within that category """ db = self.get_db() try: cur = db.cursor(mdb.cursors.DictCursor) if search == "": cur.execute("SELECT * FROM facts_facts WHERE category = %s", (category,)) facts = cur.fetchall() else: cur.execute("SELECT * FROM facts_facts WHERE category = %s AND fact REGEXP %s", (category, search)) facts = cur.fetchall() if len(facts) > 0: fact = facts[random.randint(1,len(facts))-1] return fact['fact'].rstrip() except mdb.Error as e: self.log.error("database error in _get_fact") self.log.exception(e) raise finally: cur.close() # vi:tabstop=4:expandtab:autoindent # kate: indent-mode python;indent-width 4;replace-tabs on;