diff --git a/plugins/MoobotFactoids.py b/plugins/MoobotFactoids.py index 34c47b852..ad3a5e4c2 100644 --- a/plugins/MoobotFactoids.py +++ b/plugins/MoobotFactoids.py @@ -70,9 +70,6 @@ except ImportError: raise callbacks.Error, 'You need to have PySQLite installed to use this ' \ 'plugin. Download it at ' -dbfilename = os.path.join(conf.supybot.directories.data(), 'MoobotFactoids') - - allchars = string.maketrans('', '') class OptionList(object): validChars = allchars.translate(allchars, '|()') @@ -128,14 +125,17 @@ conf.registerChannelValue(conf.supybot.plugins.MoobotFactoids, 'showFactoidIfOnlyOneMatch', registry.Boolean(True, """Determines whether or not the factoid value will be shown when a listkeys search returns only one factoid key.""")) +conf.registerChannelValue(conf.supybot.plugins.MoobotFactoids, + 'mostCount', registry.Integer(10, """Determines how many items are shown + when the 'most' command is called.""")) -class MoobotDBHandler(plugins.DBHandler): - def makeDb(self, filename): - """create MoobotFactoids database and tables""" +class SqliteMoobotDB(object): + def _getDb(self, channel): + filename = plugins.makeChannelFilename(channel, 'MoobotFactoids.db') if os.path.exists(filename): db = sqlite.connect(filename) else: - db = sqlite.connect(filename, converters={'bool': bool}) + db = sqlite.connect(filename) cursor = db.cursor() cursor.execute("""CREATE TABLE factoids ( key TEXT PRIMARY KEY, @@ -153,18 +153,169 @@ class MoobotDBHandler(plugins.DBHandler): db.commit() return db + def getFactoid(self, channel, key): + db = self._getDb(channel) + cursor = db.cursor() + cursor.execute("""SELECT fact FROM factoids + WHERE key LIKE %s""", key) + if cursor.rowcount == 0: + return None + else: + return cursor.fetchall()[0] + + def getFactinfo(self, channel, key): + db = self._getDb(channel) + cursor = db.cursor() + cursor.execute("""SELECT created_by, created_at, + modified_by, modified_at, + last_requested_by, last_requested_at, + requested_count, locked_by, locked_at + FROM factoids + WHERE key LIKE %s""", key) + if cursor.rowcount == 0: + return None + else: + return cursor.fetchone() + + def randomFactoid(self, channel): + db = self._getDb(channel) + cursor = db.cursor() + cursor.execute("""SELECT fact, key FROM factoids + ORDER BY random() LIMIT 1""") + if cursor.rowcount == 0: + return None + else: + return cursor.fetchone() + + def addFactoid(self, channel, key, value, creator_id): + db = self._getDb(channel) + cursor = db.cursor() + cursor.execute("""INSERT INTO factoids VALUES + (%s, %s, %s, NULL, NULL, NULL, NULL, + NULL, NULL, %s, 0)""", + key, creator_id, int(time.time()), value) + db.commit() + + def updateFactoid(self, channel, key, newvalue, modifier_id): + db = self._getDb(channel) + cursor = db.cursor() + cursor.execute("""UPDATE factoids + SET fact=%s, modified_by=%s, + modified_at=%s WHERE key LIKE %s""", + newvalue, modifier_id, int(time.time()), key) + db.commit() + + def updateRequest(self, channel, key, hostmask): + db = self._getDb(channel) + cursor = db.cursor() + cursor.execute("""UPDATE factoids SET + last_requested_by = %s, + last_requested_at = %s, + requested_count = requested_count + 1 + WHERE key = %s""", + hostmask, int(time.time()), key) + db.commit() + + def removeFactoid(self, channel, key): + db = self._getDb(channel) + cursor = db.cursor() + cursor.execute("""DELETE FROM factoids WHERE key LIKE %s""", + key) + db.commit() + + def locked(self, channel, key): + db = self._getDb(channel) + cursor = db.cursor() + cursor.execute ("""SELECT locked_by FROM factoids + WHERE key LIKE %s""", key) + if cursor.fetchone()[0] is None: + return False + else: + return True + + def lock(self, channel, key, locker_id): + db = self._getDb(channel) + cursor = db.cursor() + cursor.execute("""UPDATE factoids + SET locked_by=%s, locked_at=%s + WHERE key LIKE %s""", + locker_id, int(time.time()), key) + db.commit() + + def unlock(self, channel, key): + db = self._getDb(channel) + cursor = db.cursor() + cursor.execute("""UPDATE factoids + SET locked_by=%s, locked_at=%s + WHERE key LIKE %s""", None, None, key) + db.commit() + + def mostAuthored(self, channel, limit): + db = self._getDb(channel) + cursor = db.cursor() + cursor.execute("""SELECT created_by, count(key) FROM factoids + GROUP BY created_by + ORDER BY count(key) DESC LIMIT %s""", limit) + return cursor.fetchall() + + def mostRecent(self, channel, limit): + db = self._getDb(channel) + cursor = db.cursor() + cursor.execute("""SELECT key FROM factoids + ORDER BY created_at DESC LIMIT %s""", limit) + return cursor.fetchall() + + def mostPopular(self, channel, limit): + db = self._getDb(channel) + cursor = db.cursor() + cursor.execute("""SELECT key, requested_count FROM factoids + WHERE requested_count > 0 + ORDER BY requested_count DESC LIMIT %s""", limit) + if cursor.rowcount == 0: + return None + else: + return cursor.fetchall() + + def getKeysByAuthor(self, channel, author_id): + db = self._getDb(channel) + cursor = db.cursor() + cursor.execute("""SELECT key FROM factoids WHERE created_by=%s + ORDER BY key""", author_id) + if cursor.rowcount == 0: + return None + else: + return cursor.fetchall() + + def getKeysByGlob(self, channel, glob): + db = self._getDb(channel) + cursor = db.cursor() + cursor.execute("""SELECT key FROM factoids WHERE key LIKE %s + ORDER BY key""", glob) + if cursor.rowcount == 0: + return None + else: + return cursor.fetchall() + + def getKeysByValueGlob(self, channel, glob): + db = self._getDb(channel) + cursor = db.cursor() + cursor.execute("""SELECT key FROM factoids WHERE fact LIKE %s + ORDER BY key""", glob) + if cursor.rowcount == 0: + return None + else: + return cursor.fetchall() + +def MoobotDB(): + return SqliteMoobotDB() class MoobotFactoids(callbacks.PrivmsgCommandAndRegexp): priority = 98 addressedRegexps = ['changeFactoid', 'augmentFactoid', 'replaceFactoid', 'addFactoid'] def __init__(self): + self.db = MoobotDB() callbacks.PrivmsgCommandAndRegexp.__init__(self) - self.dbHandler = MoobotDBHandler(dbfilename) - - def die(self): - # Handle DB stuff - self.dbHandler.die() def _parseFactoid(self, irc, msg, fact): type = "define" # Default is to just spit the factoid back as a @@ -180,50 +331,36 @@ class MoobotFactoids(callbacks.PrivmsgCommandAndRegexp): newfact = plugins.standardSubstitute(irc, msg, newfact) return (type, newfact) - def updateFactoidRequest(self, key, hostmask): - """Updates the last_requested_* fields of a factoid row""" - db = self.dbHandler.getDb() - cursor = db.cursor() - cursor.execute("""UPDATE factoids SET - last_requested_by = %s, - last_requested_at = %s, - requested_count = requested_count +1 - WHERE key = %s""", - hostmask, int(time.time()), key) - db.commit() - def randomfactoid(self, irc, msg, args): """takes no arguments Displays a random factoid (along with its key) from the database. """ - db = self.dbHandler.getDb() - cursor = db.cursor() - cursor.execute("""SELECT fact, key FROM factoids - ORDER BY random() LIMIT 1""") - if cursor.rowcount == 0: + channel = privmsgs.getChannel(msg, args) + tup = self.db.randomFactoid(channel) + if tup is None: irc.error('No factoids in the database.') - return - (fact, key) = cursor.fetchone() - irc.reply('"%s" is "%s"' % (key, fact)) - + else: + irc.reply('"%s" is "%s"' % tup) def invalidCommand(self, irc, msg, tokens): key = ' '.join(tokens) key = key.rstrip('?!') + channel = privmsgs.getChannel(msg, list(msg.args)) + # ignore ACTIONs if key.startswith('\x01'): return # Check the factoid db for an appropriate reply - db = self.dbHandler.getDb() - cursor = db.cursor() - cursor.execute("""SELECT fact FROM factoids WHERE key LIKE %s""", key) - if cursor.rowcount == 0: + fact = self.db.getFactoid(channel, key) + if not fact: return False else: - fact = cursor.fetchone()[0] + # getFactoid returns "all results", so we need to extract the + # first one + fact = fact[0] # Update the requested count/requested by for this key hostmask = msg.prefix - self.updateFactoidRequest(key, hostmask) + self.db.updateRequest(channel, key, hostmask) # Now actually get the factoid and respond accordingly (type, text) = self._parseFactoid(irc, msg, fact) if type == "action": @@ -238,18 +375,12 @@ class MoobotFactoids(callbacks.PrivmsgCommandAndRegexp): def addFactoid(self, irc, msg, match): r"^(?!\x01)(.+?)\s+(?:is|_is_)\s+(.+)" - # Check and see if there is a command that matches this that didn't - # get caught due to nesting -# cb = callbacks.findCallbackForCommand(irc, msg) -# if cb: -# irc.reply(irc.getHelp(cb[0].config)) -# return # First, check and see if the entire message matches a factoid key - db = self.dbHandler.getDb() - cursor = db.cursor() + channel = privmsgs.getChannel(msg, list(msg.args)) key = match.group().rstrip('?! ') - cursor.execute("""SELECT * FROM factoids WHERE key LIKE %s""", key) - if cursor.rowcount != 0: + fact = self.db.getFactoid(channel, key) + # If it exists, call invalidCommand to display it + if fact: self.invalidCommand(irc, msg, callbacks.tokenize(match.group())) return # Okay, we are REALLY adding stuff @@ -259,24 +390,20 @@ class MoobotFactoids(callbacks.PrivmsgCommandAndRegexp): except KeyError: irc.errorNotRegistered() return - key, fact = match.groups() + key, newfact = match.groups() # These are okay, unless there's an _is_ in there, in which case # we split on the leftmost one. if '_is_' in match.group(): - key, fact = imap(str.strip, match.group().split('_is_', 1)) + key, newfact = imap(str.strip, match.group().split('_is_', 1)) # Strip the key of punctuation and spaces key = key.rstrip('?! ') # Check and make sure it's not in the DB already - cursor.execute("""SELECT * FROM factoids WHERE key LIKE %s""", key) - if cursor.rowcount != 0: + fact = self.db.getFactoid(channel, key) + if fact: irc.error('Factoid "%s" already exists.' % key) return # Otherwise, - cursor.execute("""INSERT INTO factoids VALUES - (%s, %s, %s, NULL, NULL, NULL, NULL, NULL, NULL, - %s, 0)""", - key, id, int(time.time()), fact) - db.commit() + self.db.addFactoid(channel, key, newfact, id) irc.replySuccess() def changeFactoid(self, irc, msg, match): @@ -288,17 +415,15 @@ class MoobotFactoids(callbacks.PrivmsgCommandAndRegexp): irc.errorNotRegistered() return key, regexp = match.groups() - db = self.dbHandler.getDb() - cursor = db.cursor() + channel = privmsgs.getChannel(msg, list(msg.args)) # Check and make sure it's in the DB - cursor.execute("""SELECT locked_at, fact FROM factoids - WHERE key LIKE %s""", key) - if cursor.rowcount == 0: + fact = self.db.getFactoid(channel, key) + if not fact: irc.error('Factoid "%s" not found.' % key) return # No dice if it's locked, no matter who it is - (locked_at, fact) = cursor.fetchone() - if locked_at is not None: + locked = self.db.locked(channel, key) + if locked: irc.error('Factoid "%s" is locked.' % key) return # It's fair game if we get to here @@ -307,12 +432,9 @@ class MoobotFactoids(callbacks.PrivmsgCommandAndRegexp): except ValueError, e: irc.error('Invalid regexp: "%s"' % regexp) return + fact = fact[0] new_fact = r(fact) - cursor.execute("""UPDATE factoids - SET fact = %s, modified_by = %s, - modified_at = %s WHERE key = %s""", - new_fact, id, int(time.time()), key) - db.commit() + self.db.updateFactoid(channel, key, new_fact, id) irc.replySuccess() def augmentFactoid(self, irc, msg, match): @@ -324,26 +446,21 @@ class MoobotFactoids(callbacks.PrivmsgCommandAndRegexp): irc.errorNotRegistered() return key, new_text = match.groups() - db = self.dbHandler.getDb() - cursor = db.cursor() + channel = privmsgs.getChannel(msg, list(msg.args)) + fact = self.db.getFactoid(channel, key) # Check and make sure it's in the DB - cursor.execute("""SELECT locked_at, fact FROM factoids - WHERE key LIKE %s""", key) - if cursor.rowcount == 0: + if not fact: irc.error('Factoid "%s" not found.' % key) return # No dice if it's locked, no matter who it is - (locked_at, fact) = cursor.fetchone() - if locked_at is not None: + locked = self.db.locked(channel, key) + if locked: irc.error('Factoid "%s" is locked.' % key) return # It's fair game if we get to here + fact = fact[0] new_fact = "%s, or %s" % (fact, new_text) - cursor.execute("""UPDATE factoids - SET fact = %s, modified_by = %s, - modified_at = %s WHERE key = %s""", - new_fact, id, int(time.time()), key) - db.commit() + self.db.updateFactoid(channel, key, new_fact, id) irc.replySuccess() def replaceFactoid(self, irc, msg, match): @@ -360,29 +477,20 @@ class MoobotFactoids(callbacks.PrivmsgCommandAndRegexp): if '_is_' in match.group(): key, new_fact = imap(str.strip, match.group().split('_is_', 1)) key = key.split(' ', 1)[1] # Take out everything to first space - db = self.dbHandler.getDb() - cursor = db.cursor() # Check and make sure it's in the DB - cursor.execute("""SELECT locked_at, fact FROM factoids - WHERE key LIKE %s""", key) - if cursor.rowcount == 0: + channel = privmsgs.getChannel(msg, list(msg.args)) + fact = self.db.getFactoid(channel, key) + if not fact: irc.error('Factoid "%s" not found.' % key) return # No dice if it's locked, no matter who it is - (locked_at, _) = cursor.fetchone() - if locked_at is not None: + locked = self.db.locked(channel, key) + if locked: irc.error('Factoid "%s" is locked.' % key) return # It's fair game if we get to here - cursor.execute("""UPDATE factoids - SET fact = %s, created_by = %s, - created_at = %s, modified_by = NULL, - modified_at = NULL, requested_count = 0, - last_requested_by = NULL, last_requested_at = NULL, - locked_at = NULL - WHERE key = %s""", - new_fact, id, int(time.time()), key) - db.commit() + self.db.removeFactoid(channel, key) + self.db.addFactoid(channel, key, new_fact, id) irc.replySuccess() def literal(self, irc, msg, args): @@ -391,15 +499,13 @@ class MoobotFactoids(callbacks.PrivmsgCommandAndRegexp): Returns the literal factoid for the given factoid key. No parsing of the factoid value is done as it is with normal retrieval. """ + channel = privmsgs.getChannel(msg, args) key = privmsgs.getArgs(args, required=1) - db = self.dbHandler.getDb() - cursor = db.cursor() - cursor.execute("""SELECT fact FROM factoids WHERE key LIKE %s""", key) - if cursor.rowcount == 0: + fact = self.db.getFactoid(channel, key) + if not fact: irc.error('No such factoid: "%s"' % key) - return else: - fact = cursor.fetchone()[0] + fact = fact[0] irc.reply(fact) def factinfo(self, irc, msg, args): @@ -407,22 +513,17 @@ class MoobotFactoids(callbacks.PrivmsgCommandAndRegexp): Returns the various bits of info on the factoid for the given key. """ + channel = privmsgs.getChannel(msg, args) key = privmsgs.getArgs(args, required=1) # Start building the response string s = key + ": " # Next, get all the info and build the response piece by piece - db = self.dbHandler.getDb() - cursor = db.cursor() - cursor.execute("""SELECT created_by, created_at, modified_by, - modified_at, last_requested_by, last_requested_at, - requested_count, locked_by, locked_at FROM - factoids WHERE key LIKE %s""", key) - if cursor.rowcount == 0: + info = self.db.getFactinfo(channel, key) + if not info: irc.error('No such factoid: "%s"' % key) return (created_by, created_at, modified_by, modified_at, last_requested_by, - last_requested_at, requested_count, locked_by, - locked_at) = cursor.fetchone() + last_requested_at, requested_count, locked_by, locked_at) = info # First, creation info. # Map the integer created_by to the username creat_by = ircdb.users.getUser(created_by).name @@ -460,15 +561,13 @@ class MoobotFactoids(callbacks.PrivmsgCommandAndRegexp): irc.errorNotRegistered() return self.log.debug('id: %s' % id) + channel = privmsgs.getChannel(msg, args) key = privmsgs.getArgs(args, required=1) - db = self.dbHandler.getDb() - cursor = db.cursor() - cursor.execute("""SELECT created_by, locked_by FROM factoids - WHERE key LIKE %s""", key) - if cursor.rowcount == 0: + info = self.db.getFactinfo(channel, key) + if not info: irc.error('No such factoid: "%s"' % key) return - (created_by, locked_by) = cursor.fetchone() + (created_by, _, _, _, _, _, _, locked_by, _) = info # Don't perform redundant operations if locking and locked_by is not None: irc.error('Factoid "%s" is already locked.' % key) @@ -489,13 +588,9 @@ class MoobotFactoids(callbacks.PrivmsgCommandAndRegexp): return # Okay, we're done, ready to lock/unlock if locking: - locked_at = int(time.time()) + self.db.lock(channel, key, id) else: - locked_at = None - id = None - cursor.execute("""UPDATE factoids SET locked_at = %s, locked_by = %s - WHERE key = %s""", locked_at, id, key) - db.commit() + self.db.unlock(channel, key) irc.replySuccess() def lock(self, irc, msg, args): @@ -514,8 +609,7 @@ class MoobotFactoids(callbacks.PrivmsgCommandAndRegexp): """ self._lock(irc, msg, args, False) - _mostCount = 10 - class MostException(Exception): + class MostException: pass def most(self, irc, msg, args): """ @@ -524,46 +618,35 @@ class MoobotFactoids(callbacks.PrivmsgCommandAndRegexp): most frequently requested factoids. lists the author with the most factoids. lists the most recently created factoids. """ + channel = privmsgs.getChannel(msg, args) arg = privmsgs.getArgs(args) arg = arg.capitalize() method = getattr(self, '_most%s' % arg, None) if method is None: raise callbacks.ArgumentError - db = self.dbHandler.getDb() - cursor = db.cursor() - cursor.execute("""SELECT COUNT(*) FROM factoids""") - if int(cursor.fetchone()[0]) == 0: - irc.error('I don\'t have any factoids in my database!') - else: - try: - irc.reply(method(cursor, self._mostCount)) - except self.MostException, e: - irc.error(str(e)) + limit = self.registryValue('mostCount', channel) + irc.reply(method(channel, limit)) - def _mostAuthored(self, cursor, limit): - cursor.execute("""SELECT created_by, count(key) FROM factoids - GROUP BY created_by - ORDER BY count(key) DESC LIMIT %s""", limit) + + def _mostAuthored(self, channel, limit): + results = self.db.mostAuthored(channel, limit) L = ['%s (%s)' % (ircdb.users.getUser(t[0]).name, int(t[1])) - for t in cursor.fetchall()] + for t in results] return 'Most prolific %s: %s' % \ (utils.pluralize('author', len(L)), utils.commaAndify(L)) - def _mostRecent(self, cursor, limit): - cursor.execute("""SELECT key FROM factoids - ORDER by created_at DESC LIMIT %s""", limit) - L = ['"%s"' % t[0] for t in cursor.fetchall()] + def _mostRecent(self, channel, limit): + results = self.db.mostRecent(channel, limit) + L = ['"%s"' % t[0] for t in results] return '%s: %s' % \ (utils.nItems('factoid', len(L), between='latest'), utils.commaAndify(L)) - def _mostPopular(self, cursor, limit): - cursor.execute("""SELECT key, requested_count FROM factoids - WHERE requested_count > 0 - ORDER BY requested_count DESC LIMIT %s""", limit) - if cursor.rowcount == 0: + def _mostPopular(self, channel, limit): + results = self.db.mostPopular(channel, limit) + if not results: raise self.MostException, 'No factoids have been requested.' - L = ['"%s" (%s)' % (t[0], t[1]) for t in cursor.fetchall()] + L = ['"%s" (%s)' % (t[0], t[1]) for t in results] return 'Top %s: %s' % \ (utils.nItems('factoid', len(L), between='requested'), utils.commaAndify(L)) @@ -575,21 +658,18 @@ class MoobotFactoids(callbacks.PrivmsgCommandAndRegexp): author has an integer name, you'll have to use that author's id to use this function (so don't use integer usernames!). """ + channel = privmsgs.getChannel(msg, args) author = privmsgs.getArgs(args, required=1) try: id = ircdb.users.getUserId(author) except KeyError: irc.error("No such user: %r" % author) return - db = self.dbHandler.getDb() - cursor = db.cursor() - cursor.execute("""SELECT key FROM factoids - WHERE created_by = %s - ORDER BY key""", id) - if cursor.rowcount == 0: + results = self.db.getKeysByAuthor(channel, id) + if not results: irc.reply('No factoids by "%s" found.' % author) return - keys = ['"%s"' % tup[0] for tup in cursor.fetchall()] + keys = ['"%s"' % tup[0] for tup in results] s = 'Author search for "%s" (%s found): %s' % \ (author, len(keys), utils.commaAndify(keys)) irc.reply(s) @@ -599,24 +679,20 @@ class MoobotFactoids(callbacks.PrivmsgCommandAndRegexp): Lists the keys of the factoids whose key contains the provided text. """ + channel = privmsgs.getChannel(msg, args) search = privmsgs.getArgs(args, required=1) # Don't error if we aren't in a channel, private messages are okay channel = privmsgs.getChannel(msg, args, raiseError=False) glob = '%' + search + '%' - db = self.dbHandler.getDb() - cursor = db.cursor() - cursor.execute("""SELECT key FROM factoids - WHERE key LIKE %s - ORDER BY key""", - glob) - if cursor.rowcount == 0: + results = self.db.getKeysByGlob(channel, glob) + if not results: irc.reply('No keys matching "%s" found.' % search) - elif cursor.rowcount == 1 and \ + elif len(results) == 1 and \ self.registryValue('showFactoidIfOnlyOneMatch', channel): - key = cursor.fetchone()[0] + key = results[0][0] self.invalidCommand(irc, msg, [key]) else: - keys = ['"%s"' % tup[0] for tup in cursor.fetchall()] + keys = ['"%s"' % tup[0] for tup in results] s = 'Key search for "%s" (%s found): %s' % \ (search, len(keys), utils.commaAndify(keys)) irc.reply(s) @@ -626,18 +702,14 @@ class MoobotFactoids(callbacks.PrivmsgCommandAndRegexp): Lists the keys of the factoids whose value contains the provided text. """ + channel = privmsgs.getChannel(msg, args) search = privmsgs.getArgs(args, required=1) glob = '%' + search + '%' - db = self.dbHandler.getDb() - cursor = db.cursor() - cursor.execute("""SELECT key FROM factoids - WHERE fact LIKE %s - ORDER BY key""", - glob) - if cursor.rowcount == 0: + results = self.db.getKeysByValueGlob(channel, glob) + if not results: irc.reply('No values matching "%s" found.' % search) return - keys = ['"%s"' % tup[0] for tup in cursor.fetchall()] + keys = ['"%s"' % tup[0] for tup in results] s = 'Value search for "%s" (%s found): %s' % \ (search, len(keys), utils.commaAndify(keys)) irc.reply(s) @@ -653,20 +725,17 @@ class MoobotFactoids(callbacks.PrivmsgCommandAndRegexp): except KeyError: irc.errorNotRegistered() return + channel = privmsgs.getChannel(msg, args) key = privmsgs.getArgs(args, required=1) - db = self.dbHandler.getDb() - cursor = db.cursor() - cursor.execute("""SELECT key, locked_at FROM factoids - WHERE key LIKE %s""", key) - if cursor.rowcount == 0: + fact = self.db.getFactoid(channel, key) + if not fact: irc.error('No such factoid: "%s"' % key) return - (_, locked_at) = cursor.fetchone() - if locked_at is not None: + locked = self.db.locked(channel, key) + if locked: irc.error("Factoid is locked, cannot remove.") return - cursor.execute("""DELETE FROM factoids WHERE key = %s""", key) - db.commit() + self.db.removeFactoid(channel, key) irc.replySuccess() def randomfactoid(self, irc, msg, args): @@ -674,14 +743,12 @@ class MoobotFactoids(callbacks.PrivmsgCommandAndRegexp): Displays a random factoid (along with its key) from the database. """ - db = self.dbHandler.getDb() - cursor = db.cursor() - cursor.execute("""SELECT fact, key FROM factoids - ORDER BY random() LIMIT 1""") - if cursor.rowcount == 0: + channel = privmsgs.getChannel(msg, args) + results = self.db.randomFactoid(channel) + if not results: irc.error('No factoids in the database.') return - (fact, key) = cursor.fetchone() + (fact, key) = results irc.reply('Random factoid: "%s" is "%s"' % (key, fact)) Class = MoobotFactoids