diff --git a/plugins/FunDB.py b/plugins/FunDB.py
index e4f6503f0..94bf6b7b1 100755
--- a/plugins/FunDB.py
+++ b/plugins/FunDB.py
@@ -38,14 +38,10 @@ __revision__ = "$Id$"
import supybot.plugins as plugins
import re
+import csv
import sets
-import time
-import getopt
-import string
-import os.path
-from itertools import imap
-
-import supybot.registry as registry
+import random
+import itertools
import supybot.conf as conf
import supybot.ircdb as ircdb
@@ -54,74 +50,165 @@ import supybot.world as world
import supybot.ircmsgs as ircmsgs
import supybot.ircutils as ircutils
import supybot.privmsgs as privmsgs
+import supybot.registry as registry
import supybot.callbacks as callbacks
-try:
- import sqlite
-except ImportError:
- raise callbacks.Error, 'You need to have PySQLite installed to use this ' \
- 'plugin. Download it at '
-tableCreateStatements = {
- 'larts': ("""CREATE TABLE larts (
- id INTEGER PRIMARY KEY,
- lart TEXT,
- added_by TEXT
- )""",),
- 'praises': ("""CREATE TABLE praises (
- id INTEGER PRIMARY KEY,
- praise TEXT,
- added_by TEXT
- )""",),
- 'insults': ("""CREATE TABLE insults (
- id INTEGER PRIMARY KEY,
- insult TEXT,
- added_by TEXT
- )""",),
- 'excuses': ("""CREATE TABLE excuses (
- id INTEGER PRIMARY KEY,
- excuse TEXT,
- added_by TEXT
- )""",),
- }
+class FunDBDBInterface(object):
+ def close(self):
+ pass
+
+ def flush(self):
+ pass
+
+ def get(self, channel, type, id):
+ """Returns just the text associated with the channel, type, and id."""
+ raise NotImplementedError
+
+ def info(self, channel, type, id):
+ """Returns the test and the metadata associated with the
+ channel, type, and id."""
+ raise NotImplementedError
+
+ def add(self, channel, type, text, by):
+ raise NotImplementedError
+
+ def remove(self, channel, type, id):
+ raise NotImplementedError
+
+ def change(self, channel, type, id, f):
+ raise NotImplementedError
+
+ def random(self, channel, type):
+ raise NotImplementedError
+
+ def size(self, channel, type):
+ raise NotImplementedError
+
+ def search(self, channel, type, p):
+ """Returns a list of (id, text) pairs whose text matches predicate p"""
+ raise NotImplementedError
+
+class FlatfileFunDBDB(FunDBDBInterface):
+ class FunDBDB(plugins.FlatfileDB):
+ def serialize(self, v):
+ return csv.join(map(str, v))
+
+ def deserialize(self, s):
+ return csv.split(s)
+
+ def __init__(self):
+ self.dbs = ircutils.IrcDict()
+ self.filenames = sets.Set()
+
+ def close(self):
+ for filename in self.filenames:
+ try:
+ db = self.FunDBDB(filename)
+ db.close()
+ except EnvironmentError:
+ pass
+
+ def _getDb(self, channel, type):
+ type = type.lower()
+ if channel not in self.dbs:
+ self.dbs[channel] = {}
+ if type not in self.dbs[channel]:
+ filename = type.capitalize() + '.db'
+ filename = plugins.makeChannelFilename(channel, filename)
+ self.filenames.add(filename)
+ self.dbs[channel][type] = self.FunDBDB(filename)
+ return self.dbs[channel][type]
+
+ def get(self, channel, type, id):
+ return self.info(channel, type, id)[1]
+
+ def info(self, channel, type, id):
+ db = self._getDb(channel, type)
+ return db.getRecord(id)
+
+ def add(self, channel, type, text, by):
+ db = self._getDb(channel, type)
+ return db.addRecord([by, text])
+
+ def remove(self, channel, type, id):
+ db = self._getDb(channel, type)
+ db.delRecord(id)
+
+ def change(self, channel, type, id, f):
+ db = self._getDb(channel, type)
+ (by, text) = db.getRecord(id)
+ db.setRecord(id, [by, f(text)])
+
+ def random(self, channel, type):
+ db = self._getDb(channel, type)
+ t = random.choice(db.records())
+ if t is not None:
+ (id, (by, text)) = t
+ t = (id, text)
+ return t
+
+ def size(self, channel, type):
+ db = self._getDb(channel, type)
+ return itertools.ilen(db.records())
+
+ def search(self, channel, type, p):
+ db = self._getDb(channel, type)
+ L = []
+ for (id, record) in db.records():
+ text = record[1]
+ if p(text):
+ L.append((id, text))
+ return L
+
+
+def FunDBDB():
+ return FlatfileFunDBDB()
conf.registerPlugin('FunDB')
conf.registerChannelValue(conf.supybot.plugins.FunDB, 'showIds',
- registry.Boolean(True, """Determine whether the bot will show the id of an
- excuse/insult/praise/lart."""))
+ registry.Boolean(True, """Determines whether the bot will show the id of an
+ insult/praise/lart."""))
-class FunDB(callbacks.Privmsg, plugins.ChannelDBHandler):
+class FunDB(callbacks.Privmsg):
"""
Contains the 'fun' commands that require a database. Currently includes
- database-backed commands for crossword puzzle solving, anagram searching,
- larting, praising, excusing, and insulting.
+ commands for larting, praising, excusing, and insulting.
"""
- _tables = sets.Set(['lart', 'insult', 'excuse', 'praise'])
+ _types = ('insult', 'lart', 'praise')
def __init__(self):
callbacks.Privmsg.__init__(self)
- plugins.ChannelDBHandler.__init__(self)
+ self.db = FunDBDB()
def die(self):
- callbacks.Privmsg.die(self)
- plugins.ChannelDBHandler.die(self)
+ self.db.die()
- def makeDb(self, dbfilename, replace=False):
- if os.path.exists(dbfilename):
- if replace:
- os.remove(dbfilename)
- db = sqlite.connect(dbfilename)
- cursor = db.cursor()
- for table in tableCreateStatements:
- try:
- cursor.execute("""SELECT * FROM %s LIMIT 1""" % table)
- except sqlite.DatabaseError: # The table doesn't exist.
- for sql in tableCreateStatements[table]:
- cursor.execute(sql)
- db.commit()
- return db
+ def _validType(self, irc, type, error=True):
+ if type not in self._types:
+ if error:
+ irc.error('%r is not a valid type. Valid types include %s.' %
+ (type, utils.commaAndify(self._types)))
+ return False
+ else:
+ return True
+
+ def _validId(self, irc, id, error=True):
+ try:
+ return int(id)
+ except ValueError:
+ if error:
+ irc.error('The argument must be an integer.')
+ return None
+
+ def _isRegistered(self, irc, msg):
+ try:
+ return ircdb.users.getUserId(msg.prefix)
+ except KeyError:
+ irc.errorNotRegistered()
+ return None
def add(self, irc, msg, args):
- """[]
+ """[]
Adds another record to the data referred to in the first argument. For
commands that will later respond with an ACTION (lart and praise), $who
@@ -132,65 +219,44 @@ class FunDB(callbacks.Privmsg, plugins.ChannelDBHandler):
the message isn't sent in the channel itself.
"""
channel = privmsgs.getChannel(msg, args)
- (table, s) = privmsgs.getArgs(args, required=2)
- table = table.lower()
- try:
- name = ircdb.users.getUser(msg.prefix).name
- except KeyError:
- irc.errorNotRegistered()
+ (type, s) = privmsgs.getArgs(args, required=2)
+ type = type.lower()
+ userId = self._isRegistered(irc, msg)
+ if not userId:
return
- if table == "lart" or table == "praise":
+ if not self._validType(irc, type):
+ return
+ if type == "lart" or type == "praise":
if '$who' not in s:
irc.error('There must be a $who in the lart/praise somewhere')
return
- elif table not in self._tables:
- irc.error('"%s" is not valid. Valid values include %s.' %
- (table, utils.commaAndify(self._tables)))
- return
- db = self.getDb(channel)
- cursor = db.cursor()
- sql = """INSERT INTO %ss VALUES (NULL, %%s, %%s)""" % table
- cursor.execute(sql, s, name)
- db.commit()
- sql = """SELECT id FROM %ss WHERE %s=%%s
- ORDER BY id DESC LIMIT 1""" % (table, table)
- cursor.execute(sql, s)
- id = cursor.fetchone()[0]
- irc.replySuccess('(%s #%s added)' % (table, id))
+ id = self.db.add(channel, type, s, userId)
+ irc.replySuccess('(%s #%s added)' % (type, id))
def remove(self, irc, msg, args):
- """[]
+ """[]
Removes the data, referred to in the first argument, with the id
number from the database. is only necessary if the
message isn't sent in the channel itself.
"""
channel = privmsgs.getChannel(msg, args)
- (table, id) = privmsgs.getArgs(args, required=2)
- table = table.lower()
+ (type, id) = privmsgs.getArgs(args, required=2)
+ if not self._isRegistered(irc, msg):
+ return
+ if not self._validType(irc, type):
+ return
+ id = self._validId(irc, id)
+ if id is None:
+ return
try:
- ircdb.users.getUser(msg.prefix).name
+ self.db.remove(channel, type, id)
+ irc.replySuccess()
except KeyError:
- irc.errorNotRegistered()
- return
- try:
- id = int(id)
- except ValueError:
- irc.error('The argument must be an integer.')
- return
- if table not in self._tables:
- irc.error('"%s" is not valid. Valid values include %s.' %
- (table, utils.commaAndify(self._tables)))
- return
- db = self.getDb(channel)
- cursor = db.cursor()
- sql = """DELETE FROM %ss WHERE id=%%s""" % table
- cursor.execute(sql, id)
- db.commit()
- irc.replySuccess()
+ irc.error('There is no %s with that id.' % type)
def change(self, irc, msg, args):
- """[]
+ """[]
Changes the data, referred to in the first argument, with the id
number according to the regular expression . is the
@@ -199,130 +265,96 @@ class FunDB(callbacks.Privmsg, plugins.ChannelDBHandler):
message isn't sent in the channel itself.
"""
channel = privmsgs.getChannel(msg, args)
- (table, id, regexp) = privmsgs.getArgs(args, required=3)
- table = table.lower()
- try:
- name = ircdb.users.getUser(msg.prefix).name
- except KeyError:
- irc.errorNotRegistered()
+ (type, id, regexp) = privmsgs.getArgs(args, required=3)
+ if not self._validType(irc, type):
return
- try:
- id = int(id)
- except ValueError:
- irc.error('The argument must be an integer.')
+ id = self._validId(irc, id)
+ if id is None:
return
- if table not in self._tables:
- irc.error('"%s" is not valid. Valid values include %s.' %
- (table, utils.commaAndify(self._tables)))
+ if not self._isRegistered(irc, msg):
return
try:
replacer = utils.perlReToReplacer(regexp)
except ValueError, e:
- irc.error('The regexp wasn\'t valid: %s.' % e.args[0])
+ irc.error('That regexp wasn\'t valid: %s.' % e.args[0])
+ return
except re.error, e:
irc.error(utils.exnToString(e))
return
- db = self.getDb(channel)
- cursor = db.cursor()
- sql = """SELECT %s FROM %ss WHERE id=%%s""" % (table, table)
- cursor.execute(sql, id)
- if cursor.rowcount == 0:
- irc.error('There is no such %s.' % table)
- else:
- old_entry = cursor.fetchone()[0]
- new_entry = replacer(old_entry)
- sql = """UPDATE %ss SET %s=%%s, added_by=%%s WHERE id=%%s""" % \
- (table, table)
- cursor.execute(sql, new_entry, name, id)
- db.commit()
+ try:
+ self.db.change(channel, type, id, replacer)
irc.replySuccess()
+ except KeyError:
+ irc.error('There is no %s with that id.' % type)
def stats(self, irc, msg, args):
- """[]
+ """[]
Returns the number of records, of the type specified, currently in
the database. is only necessary if the message isn't sent
in the channel itself.
"""
channel = privmsgs.getChannel(msg, args)
- table = privmsgs.getArgs(args)
- table = table.lower()
- if table not in self._tables:
- irc.error('%r is not valid. Valid values include %s.' %
- (table, utils.commaAndify(self._tables)))
+ type = privmsgs.getArgs(args)
+ if not self._validType(irc, type):
return
- db = self.getDb(channel)
- cursor = db.cursor()
- sql = """SELECT count(*) FROM %ss""" % table
- cursor.execute(sql)
- total = int(cursor.fetchone()[0])
+ total = self.db.size(channel, type)
irc.reply('There %s currently %s in my database.' %
- (utils.be(total), utils.nItems(table, total)))
+ (utils.be(total), utils.nItems(type, total)))
def get(self, irc, msg, args):
- """[]
+ """[]
- Gets the record with id from the table specified. is
+ Gets the record with id from the type specified. is
only necessary if the message isn't sent in the channel itself.
"""
channel = privmsgs.getChannel(msg, args)
- (table, id) = privmsgs.getArgs(args, required=2)
- table = table.lower()
+ (type, id) = privmsgs.getArgs(args, required=2)
+ if not self._validType(irc, type):
+ return
+ id = self._validId(irc, id)
+ if id is None:
+ return
try:
- id = int(id)
- except ValueError:
- irc.error('The argument must be an integer.')
- return
- if table not in self._tables:
- irc.error('"%s" is not valid. Valid values include %s.' %
- (table, utils.commaAndify(self._tables)))
- return
- db = self.getDb(channel)
- cursor = db.cursor()
- sql = """SELECT %s FROM %ss WHERE id=%%s""" % (table, table)
- cursor.execute(sql, id)
- if cursor.rowcount == 0:
- irc.error('There is no such %s.' % table)
- else:
- reply = cursor.fetchone()[0]
- irc.reply(reply)
+ text = self.db.get(channel, type, id)
+ irc.reply(text)
+ except KeyError:
+ irc.error('There is no %s with that id.' % type)
def info(self, irc, msg, args):
- """[]
+ """[]
- Gets the info for the record with id from the table specified.
+ Gets the info for the record with id from the type specified.
is only necessary if the message isn't sent in the channel
itself.
"""
channel = privmsgs.getChannel(msg, args)
- (table, id) = privmsgs.getArgs(args, required=2)
- table = table.lower()
+ (type, id) = privmsgs.getArgs(args, required=2)
+ if not self._validType(irc, type):
+ return
+ id = self._validId(irc, id)
+ if id is None:
+ return
try:
- id = int(id)
- except ValueError:
- irc.error('The argument must be an integer.')
- return
- if table not in self._tables:
- irc.error('"%s" is not valid. Valid values include %s.' %
- (table, utils.commaAndify(self._tables)))
- return
- db = self.getDb(channel)
- cursor = db.cursor()
- sql = """SELECT added_by FROM %ss WHERE id=%%s""" % table
- cursor.execute(sql, id)
- if cursor.rowcount == 0:
- irc.error('There is no such %s.' % table)
- else:
- add = cursor.fetchone()[0]
- reply = '%s #%s: Created by %s.' % (table, id, add)
+ (text, by) = self.db.info(channel, type, id)
+ reply = '%s #%s: %r; Created by %s.' % (type, id, text, by)
irc.reply(reply)
+ except KeyError:
+ irc.error('There is no %s with that id.' % type)
- def _formatResponse(self, s, id, showids):
- if showids:
+ def _formatResponse(self, s, id, channel):
+ if self.registryValue('showIds', channel):
return '%s (#%s)' % (s, id)
else:
return s
+ _meRe = re.compile(r'\bme\b', re.I)
+ _myRe = re.compile(r'\bmy\b', re.I)
+ def _replaceFirstPerson(self, s, nick):
+ s = self._meRe.sub(nick, s)
+ s = self._myRe.sub('%s\'s' % nick, s)
+ return s
+
def insult(self, irc, msg, args):
"""[]
@@ -333,57 +365,16 @@ class FunDB(callbacks.Privmsg, plugins.ChannelDBHandler):
nick = privmsgs.getArgs(args)
if not nick:
raise callbacks.ArgumentError
- db = self.getDb(channel)
- cursor = db.cursor()
- cursor.execute("""SELECT id, insult FROM insults
- WHERE insult NOT NULL
- ORDER BY random()
- LIMIT 1""")
- if cursor.rowcount == 0:
+ t = self.db.random(channel, 'insult')
+ if t is None:
irc.error('There are currently no available insults.')
else:
- (id, insult) = cursor.fetchone()
- nick = re.sub(r'\bme\b', msg.nick, nick)
- nick = re.sub(r'\bmy\b', '%s\'s' % msg.nick, nick)
+ (id, insult) = t
+ nick = self._replaceFirstPerson(nick, msg.nick)
insult = '%s: %s' % (nick, insult.replace('$who', nick))
- showid = self.registryValue('showIds', channel)
- irc.reply(self._formatResponse(insult, id, showid),
+ irc.reply(self._formatResponse(insult, id, channel),
prefixName=False)
- def excuse(self, irc, msg, args):
- """[] []
-
- Gives you a standard, random BOFH excuse or the excuse with the given
- . is only necessary if the message isn't sent in the
- channel itself.
- """
- channel = privmsgs.getChannel(msg, args)
- id = privmsgs.getArgs(args, required=0, optional=1)
- db = self.getDb(channel)
- cursor = db.cursor()
- if id:
- try:
- id = int(id)
- except ValueError:
- irc.error('The argument must be an integer.')
- return
- cursor.execute("""SELECT id, excuse FROM excuses WHERE id=%s""",
- id)
- if cursor.rowcount == 0:
- irc.error('There is no such excuse.')
- return
- else:
- cursor.execute("""SELECT id, excuse FROM excuses
- WHERE excuse NOTNULL
- ORDER BY random()
- LIMIT 1""")
- if cursor.rowcount == 0:
- irc.error('There are currently no available excuses.')
- else:
- (id, excuse) = cursor.fetchone()
- showid = self.registryValue('showIds', channel)
- irc.reply(self._formatResponse(excuse, id, showid))
-
def lart(self, irc, msg, args):
"""[] [] [for ]
@@ -393,51 +384,39 @@ class FunDB(callbacks.Privmsg, plugins.ChannelDBHandler):
"""
channel = privmsgs.getChannel(msg, args)
(id, nick) = privmsgs.getArgs(args, optional=1)
- try:
- id = int(id)
- if id < 1:
- irc.error('There is no such lart.')
- return
- except ValueError:
- nick = ' '.join([id, nick]).strip()
- id = 0
+ id = self._validId(irc, id, error=False)
+ if id is None:
+ nick = privmsgs.getArgs(args)
nick = nick.rstrip('.')
if not nick:
raise callbacks.ArgumentError
if nick == irc.nick:
nick = msg.nick
try:
- (nick, reason) = imap(' '.join,
+ (nick, reason) = itertools.imap(' '.join,
utils.itersplit('for'.__eq__, nick.split(), 1))
except ValueError:
reason = ''
- db = self.getDb(channel)
- cursor = db.cursor()
if id:
- cursor.execute("""SELECT id, lart FROM larts WHERE id=%s""", id)
- if cursor.rowcount == 0:
+ try:
+ lart = self.db.get(channel, 'lart', id)
+ t = (id, lart)
+ except KeyError:
irc.error('There is no such lart.')
return
else:
- cursor.execute("""SELECT id, lart FROM larts
- WHERE lart NOTNULL
- ORDER BY random()
- LIMIT 1""")
- if cursor.rowcount == 0:
+ t = self.db.random(channel, 'lart')
+ if t is None:
irc.error('There are currently no available larts.')
else:
- (id, lart) = cursor.fetchone()
- nick = re.sub(r'\bme\b', msg.nick, nick)
- reason = re.sub(r'\bme\b', msg.nick, reason)
- nick = re.sub(r'\bmy\b', '%s\'s' % msg.nick, nick)
- reason = re.sub(r'\bmy\b', '%s\'s' % msg.nick, reason)
- lartee = nick
- s = lart.replace('$who', lartee)
+ (id, lart) = t
+ nick = self._replaceFirstPerson(nick, msg.nick)
+ reason = self._replaceFirstPerson(reason, msg.nick)
+ s = lart.replace('$who', nick)
if reason:
s = '%s for %s' % (s, reason)
s = s.rstrip('.')
- showid = self.registryValue('showIds', channel)
- irc.reply(self._formatResponse(s, id, showid), action=True)
+ irc.reply(self._formatResponse(s, id, channel), action=True)
def praise(self, irc, msg, args):
"""[] [] [for ]
@@ -449,90 +428,39 @@ class FunDB(callbacks.Privmsg, plugins.ChannelDBHandler):
"""
channel = privmsgs.getChannel(msg, args)
(id, nick) = privmsgs.getArgs(args, optional=1)
- try:
- id = int(id)
- if id < 1:
- irc.error('There is no such praise.')
- return
- except ValueError:
- nick = ' '.join([id, nick]).strip()
- id = 0
+ id = self._validId(irc, id, error=False)
+ if id is None:
+ nick = privmsgs.getArgs(args)
nick = nick.rstrip('.')
if not nick:
raise callbacks.ArgumentError
try:
- (nick, reason) = imap(' '.join,
+ (nick, reason) = itertools.imap(' '.join,
utils.itersplit('for'.__eq__, nick.split(), 1))
except ValueError:
reason = ''
- db = self.getDb(channel)
- cursor = db.cursor()
if id:
- cursor.execute("""SELECT id, praise FROM praises WHERE id=%s""",id)
- if cursor.rowcount == 0:
+ try:
+ praise = self.db.get(channel, 'praise', id)
+ t = (id, praise)
+ except KeyError:
irc.error('There is no such praise.')
return
else:
- cursor.execute("""SELECT id, praise FROM praises
- WHERE praise NOTNULL
- ORDER BY random()
- LIMIT 1""")
- if cursor.rowcount == 0:
+ t = self.db.random(channel, 'praise')
+ if t is None:
irc.error('There are currently no available praises.')
else:
- (id, praise) = cursor.fetchone()
- nick = re.sub(r'\bme\b', msg.nick, nick)
- reason = re.sub(r'\bme\b', msg.nick, reason)
- nick = re.sub(r'\bmy\b', '%s\'s' % msg.nick, nick)
- reason = re.sub(r'\bmy\b', '%s\'s' % msg.nick, reason)
- praisee = nick
- s = praise.replace('$who', praisee)
+ (id, praise) = t
+ nick = self._replaceFirstPerson(nick, msg.nick)
+ reason = self._replaceFirstPerson(reason, msg.nick)
+ s = praise.replace('$who', nick)
if reason:
s = '%s for %s' % (s, reason)
s = s.rstrip('.')
- showid = self.registryValue('showIds', channel)
- irc.reply(self._formatResponse(s, id, showid), action=True)
+ irc.reply(self._formatResponse(s, id, channel), action=True)
Class = FunDB
-if __name__ == '__main__':
- import sys
- if len(sys.argv) < 3 or len(sys.argv) > 4:
- print 'Usage: %s file' \
- ' []' % sys.argv[0]
- sys.exit(-1)
- if len(sys.argv) == 4:
- added_by = sys.argv.pop()
- else:
- added_by = ''
- (channel, category, filename) = sys.argv[1:]
- plugin = Class()
- db = plugin.getDb(channel)
- cursor = db.cursor()
- for line in open(filename, 'r'):
- line = line.rstrip()
- if not line:
- continue
- elif category == 'larts':
- if '$who' in line:
- cursor.execute("""INSERT INTO larts VALUES (NULL, %s, %s)""",
- line, added_by)
- else:
- print 'Invalid lart: %s' % line
- elif category == 'praises':
- if '$who' in line:
- cursor.execute("""INSERT INTO praises VALUES (NULL, %s, %s)""",
- line, added_by)
- else:
- print 'Invalid praise: %s' % line
- elif category == 'insults':
- cursor.execute("""INSERT INTO insults VALUES (NULL, %s, %s)""",
- line, added_by)
- elif category == 'excuses':
- cursor.execute("""INSERT INTO excuses VALUES (NULL, %s, %s )""",
- line, added_by)
- db.commit()
- db.close()
-
# vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78:
diff --git a/test/test_FunDB.py b/test/test_FunDB.py
index 34b579054..d2d93804e 100644
--- a/test/test_FunDB.py
+++ b/test/test_FunDB.py
@@ -122,20 +122,6 @@ if sqlite is not None:
self.assertNotError('remove praise 1')
self.assertNotError('remove insult 1')
- def testExcuse(self):
- self.assertNotError('add excuse Power failure')
- self.assertResponse('excuse', 'Power failure (#1)')
- self.assertError('excuse a few random words')
- self.assertRegexp('stats excuse', r'currently 1 excuse')
- self.assertNotError('add excuse /pub/lunch')
- self.assertResponse('excuse 1', 'Power failure (#1)')
- self.assertNotError('remove excuse 1')
- self.assertRegexp('stats excuse', r'currently 1 excuse')
- self.assertResponse('excuse', '/pub/lunch (#2)')
- self.assertNotError('remove excuse 2')
- self.assertRegexp('stats excuse', r'currently 0')
- self.assertError('excuse')
-
def testInsult(self):
self.assertNotError('add insult Fatty McFatty')
self.assertResponse('insult jemfinch',
@@ -152,8 +138,6 @@ if sqlite is not None:
self.assertNotError('add lart stubs $who')
self.assertNotError('add #tester insult nimrod')
self.assertNotError('add insult nimwit')
- self.assertNotError('add #tester excuse He did it!')
- self.assertNotError('add excuse She did it!')
self.assertResponse('praise jemfinch',
'\x01ACTION pats jemfinch (#1)\x01')
self.assertResponse('praise #tester jemfinch',
@@ -165,8 +149,6 @@ if sqlite is not None:
self.assertResponse('insult jemfinch', 'jemfinch: nimwit (#1)')
self.assertResponse('insult #tester jemfinch',
'jemfinch: nimrod (#1)')
- self.assertResponse('excuse', 'She did it! (#1)')
- self.assertResponse('excuse #tester', 'He did it! (#1)')
def testPraise(self):
self.assertNotError('add praise pets $who')
@@ -211,7 +193,6 @@ if sqlite is not None:
self.assertError('stats 1')
self.assertRegexp('stats praise', r'currently 0')
self.assertRegexp('stats lart', r'currently 0')
- self.assertRegexp('stats excuse', r'currently 0')
self.assertRegexp('stats insult', r'currently 0')
def testChange(self):