From faea5a59095ef72e5848f9ed2c03355ebc03afea Mon Sep 17 00:00:00 2001 From: Daniel DiPaolo Date: Tue, 28 Oct 2003 01:46:58 +0000 Subject: [PATCH] Split out dunnos from MoobotFactoids (into Dunno.py) in anticipation of the invalidCommand infrastructure addition. --- plugins/Dunno.py | 182 ++++++++++++++++++++++++++++++++++++++ plugins/MoobotFactoids.py | 91 ++----------------- 2 files changed, 190 insertions(+), 83 deletions(-) create mode 100644 plugins/Dunno.py diff --git a/plugins/Dunno.py b/plugins/Dunno.py new file mode 100644 index 000000000..511af8dcb --- /dev/null +++ b/plugins/Dunno.py @@ -0,0 +1,182 @@ +#!/usr/bin/python + +### +# Copyright (c) 2003, Daniel DiPaolo +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions, and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions, and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the author of this software nor the name of +# contributors to this software may be used to endorse or promote products +# derived from this software without specific prior written consent. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +### + +""" +Add the module docstring here. This will be used by the setup.py script. +""" + +import ircdb +import sqlite +import plugins + +import utils +import privmsgs +import callbacks + +dbfilename = os.path.join(conf.dataDir, 'Dunno.db') + +def configure(onStart, afterConnect, advanced): + # This will be called by setup.py to configure this module. onStart and + # afterConnect are both lists. Append to onStart the commands you would + # like to be run when the bot is started; append to afterConnect the + # commands you would like to be run when the bot has finished connecting. + from questions import expect, anything, something, yn + onStart.append('load Dunno') + +example = utils.wrapLines(""" +Add an example IRC session using this module here. +""") + +class Dunno(callbacks.Privmsg): + priority = 1000 + def __init__(self): + callbacks.Privmsg.__init__(self) + self.makeDb(dbfilename) + + def makeDb(self, filename): + """create Dunno database and tables""" + if os.path.exists(filename): + self.db = sqlite.connect(filename) + return + self.db = sqlite.connect(filename, converters={'bool': bool}) + cursor = self.db.cursor() + cursor.execute("""CREATE TABLE dunnos ( + id INTEGER PRIMARY KEY, + added_by INTEGER, + added_at TIMESTAMP, + dunno TEXT + )""") + self.db.commit() + + def invalidCommand(self, irc, msg, tokens): + cursor = self.db.cursor() + cursor.execute("""SELECT dunno + FROM dunnos + ORDER BY random() + LIMIT 1""") + if cursor.rowcount == 0: + return "No dunno's available, add some with dunnoadd." + dunno = cursor.fetchone()[0] + dunno = dunno.replace('$who', msg.nick) + irc.reply(msg, text, prefixName=false) + return True + + def add(self, irc, msg, args): + """ + + Adds as a "dunno" to be used as a random response when no + command or factoid key matches. Can optionally contain '$who', which + will be replaced by the user's name when the dunno is displayed. + """ + # Must be registered to use this + try: + id = ircdb.users.getUserId(msg.prefix) + except KeyError: + irc.error(msg, conf.replyNotRegistered) + return + text = privmsgs.getArgs(args, needed=1) + cursor = self.db.cursor() + cursor.execute("""INSERT INTO dunnos + VALUES(NULL, %s, %s, %s)""", + id, int(time.time()), text) + self.db.commit() + irc.reply(msg, conf.replySuccess) + + def remove(self, irc, msg, args): + """ + + Removes dunno with the given . + """ + # Must be registered to use this + try: + user_id = ircdb.users.getUserId(msg.prefix) + except KeyError: + irc.error(msg, conf.replyNotRegistered) + return + dunno_id = privmsgs.getArgs(args, needed=1) + cursor = self.db.cursor() + cursor.execute("""SELECT added_by, dunno + FROM dunnos + WHERE id = %s""" % dunno_id) + if cursor.rowcount == 0: + irc.error(msg, 'No dunno with id: %d' % dunno_id) + return + (added_by, dunno) = cursor.fetchone() + if not (ircdb.checkCapability(user_id, 'admin') or \ + added_by == user_id): + irc.error(msg, 'Only admins and the dunno creator may delete a ' + 'dunno.') + return + cursor.execute("""DELETE FROM dunnos WHERE id = %s""" % dunno_id) + self.db.commit() + irc.reply(msg, conf.replySuccess) + + def search(self, irc, msg, args): + """ + + Search for dunno containing the given text. Returns the ids of the + dunnos with the text in them. + """ + text = privmsgs.getArgs(args, needed=1) + glob = "%" + text + "%" + cursor = self.db.cursor() + cursor.execute("""SELECT id FROM dunnos + WHERE dunno LIKE %s""", glob) + if cursor.rowcount == 0: + irc.error(msg, 'No dunnos with %r found.' % text) + return + ids = cursor.fetchall() + s = "Dunno search for %r (%d found): %s" % \ + (text, len(ids), utils.commaAndify(ids)) + irc.reply(msg, s) + + def dunno(self, irc, msg, args): + """ + + Display the text of the dunno with the given id. + """ + id = privmsgs.getArgs(args, needed=1) + try: + id = int(id) + except ValueError: + irc.error(msg, '%r is not a valid dunno id' % id) + return + cursor = self.db.cursor() + cursor.execute("""SELECT dunno FROM dunnos WHERE id = %s""", id) + if cursor.rowcount == 0: + irc.error(msg, 'No dunno found with id #%d' % id) + return + dunno = cursor.fetchone()[0] + irc.reply(msg, "Dunno #%d: %r" % (id, dunno)) + +Class = Dunno + +# vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78: diff --git a/plugins/MoobotFactoids.py b/plugins/MoobotFactoids.py index c19602f8b..d26289ed9 100644 --- a/plugins/MoobotFactoids.py +++ b/plugins/MoobotFactoids.py @@ -124,19 +124,12 @@ def pick(L, recursed=False): return L class MoobotFactoids(callbacks.PrivmsgCommandAndRegexp): - priority = 1000 + priority = 999 addressedRegexps = ['changeFactoid', 'augmentFactoid', 'replaceFactoid', 'addFactoid'] def __init__(self): callbacks.PrivmsgCommandAndRegexp.__init__(self) self.makeDb(dbfilename) - # Set up the "reply when not command" behavior - Misc = Owner.loadPluginModule('Misc') - # Gotta make sure we restore this when we unload - self.originalReplyWhenNotCommand = Misc.replyWhenNotCommand - self.originalConfReplyWhenNotCommand = conf.replyWhenNotCommand - conf.replyWhenNotCommand = True - Misc.replyWhenNotCommand = self._checkFactoids def makeDb(self, filename): """create MoobotFactoids database and tables""" @@ -158,12 +151,6 @@ class MoobotFactoids(callbacks.PrivmsgCommandAndRegexp): fact TEXT, requested_count INTEGER )""") - cursor.execute("""CREATE TABLE dunnos ( - id INTEGER PRIMARY KEY, - added_by INTEGER, - added_at TIMESTAMP, - dunno TEXT - )""") self.db.commit() def die(self): @@ -182,9 +169,11 @@ class MoobotFactoids(callbacks.PrivmsgCommandAndRegexp): newfact = ''.join(pick(tokenize(fact))) if newfact.startswith(""): newfact = newfact.replace("", "", 1) + newfact = newfact.strip() type = "reply" elif newfact.startswith(""): newfact = newfact.replace("", "", 1) + newfact = newfact.strip() type = "action" return (type, newfact) @@ -199,17 +188,15 @@ class MoobotFactoids(callbacks.PrivmsgCommandAndRegexp): hostmask, int(time.time()), key) self.db.commit() - def _checkFactoids(self, irc, msg, _): - # Strip the bot name - key = callbacks.addressed(irc.nick, msg) + def invalidCommand(self, irc, msg, tokens): + key = ' '.join(tokens) if key.startswith('\x01'): return # Check the factoid db for an appropriate reply cursor = self.db.cursor() cursor.execute("""SELECT fact FROM factoids WHERE key LIKE %s""", key) if cursor.rowcount == 0: - text = self._getDunno(msg.nick) - irc.reply(msg, text, prefixName=False) + return False else: fact = cursor.fetchone()[0] # Update the requested count/requested by for this key @@ -225,19 +212,7 @@ class MoobotFactoids(callbacks.PrivmsgCommandAndRegexp): irc.reply(msg, "%s is %s" % (key, text), prefixName=False) else: irc.error(msg, "Spurious type from parseFactoid.") - - def _getDunno(self, nick): - """Retrieves a "dunno" from the database.""" - cursor = self.db.cursor() - cursor.execute("""SELECT dunno - FROM dunnos - ORDER BY random() - LIMIT 1""") - if cursor.rowcount == 0: - return "No dunno's available, add some with dunnoadd." - dunno = cursor.fetchone()[0] - dunno = dunno.replace('$who', nick) - return dunno + return True def addFactoid(self, irc, msg, match): r"^(?!no\s+)(.+)\s+is\s+(?!also)(.+)" @@ -448,7 +423,7 @@ class MoobotFactoids(callbacks.PrivmsgCommandAndRegexp): if locked_by is None: irc.error(msg, "Factoid '%r is not locked." % key) return - # Can only lock/unlock own factoids + # Can only lock/unlock own factoids unless you're an admin if not (ircdb.checkCapability(id, 'admin') or created_by == id): s = "unlock" if lock: @@ -574,56 +549,6 @@ class MoobotFactoids(callbacks.PrivmsgCommandAndRegexp): self.db.commit() irc.reply(msg, conf.replySuccess) - def dunnoadd(self, irc, msg, args): - """ - - Adds as a "dunno" to be used as a random response when no - command or factoid key matches. Can optionally contain '$who', which - will be replaced by the user's name when the dunno is displayed. - """ - # Must be registered to use this - try: - id = ircdb.users.getUserId(msg.prefix) - except KeyError: - irc.error(msg, conf.replyNotRegistered) - return - text = privmsgs.getArgs(args, needed=1) - cursor = self.db.cursor() - cursor.execute("""INSERT INTO dunnos - VALUES(NULL, %s, %s, %s)""", - id, int(time.time()), text) - self.db.commit() - irc.reply(msg, conf.replySuccess) - - def dunnoremove(self, irc, msg, args): - """ - - Removes dunno with the given . - """ - # Must be registered to use this - try: - user_id = ircdb.users.getUserId(msg.prefix) - except KeyError: - irc.error(msg, conf.replyNotRegistered) - return - dunno_id = privmsgs.getArgs(args, needed=1) - cursor = self.db.cursor() - cursor.execute("""SELECT added_by, dunno - FROM dunnos - WHERE id = %s""" % dunno_id) - if cursor.rowcount == 0: - irc.error(msg, 'No dunno with id: %d' % dunno_id) - return - (added_by, dunno) = cursor.fetchone() - if not (ircdb.checkCapability(user_id, 'admin') or \ - added_by == user_id): - irc.error(msg, 'Only admins and the dunno creator may delete a ' - 'dunno.') - return - cursor.execute("""DELETE FROM dunnos WHERE id = %s""" % dunno_id) - self.db.commit() - irc.reply(msg, conf.replySuccess) - Class = MoobotFactoids # vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78: