for Factoids: make approximate fuzzy key searches also when invoking whatis directly.

also add tests.
while there, remove useless config setting for replyinvalidcommand testing, since it is true by default.
This commit is contained in:
Daniel Folkinshteyn 2010-04-18 03:33:10 -04:00 committed by Valentin Lorentz
parent e939cfd124
commit d433bfc8f0
3 changed files with 36 additions and 29 deletions

View File

@ -60,11 +60,11 @@ conf.registerChannelValue(Factoids, 'replyWhenInvalidCommand',
registry.Boolean(True, _("""Determines whether the bot will reply to invalid registry.Boolean(True, _("""Determines whether the bot will reply to invalid
commands by searching for a factoid; basically making the whatis commands by searching for a factoid; basically making the whatis
unnecessary when you want all factoids for a given key."""))) unnecessary when you want all factoids for a given key.""")))
conf.registerChannelValue(Factoids, 'replyWhenInvalidCommandSearchKeys', conf.registerChannelValue(Factoids, 'replyApproximateSearchKeys',
registry.Boolean(True, _("""If replyWhenInvalidCommand is True, and you registry.Boolean(True, _("""If you try to look up a nonexistent factoid,
supply a nonexistent factoid as a command, this setting make the bot try a this setting make the bot try to find some possible matching keys through
wildcard search for factoid keys, returning a list of matching keys, several approximate matching algorithms and return a list of matching keys,
before giving up with an invalid command error."""))) before giving up.""")))
conf.registerChannelValue(Factoids, 'format', conf.registerChannelValue(Factoids, 'format',
FactoidFormat(_('$key could be $value.'), _("""Determines the format of FactoidFormat(_('$key could be $value.'), _("""Determines the format of
the response given when a factoid's value is requested. All the standard the response given when a factoid's value is requested. All the standard

View File

@ -194,7 +194,6 @@ class Factoids(callbacks.Plugin, plugins.ChannelDBHandler):
ORDER BY factoids.id ORDER BY factoids.id
LIMIT 20""", (key,)) LIMIT 20""", (key,))
return cursor.fetchall() return cursor.fetchall()
#return [t[0] for t in cursor.fetchall()]
def _searchFactoid(self, channel, key): def _searchFactoid(self, channel, key):
"""Try to typo-match input to possible factoids. """Try to typo-match input to possible factoids.
@ -272,6 +271,16 @@ class Factoids(callbacks.Plugin, plugins.ChannelDBHandler):
elif error: elif error:
irc.error(_('No factoid matches that key.')) irc.error(_('No factoid matches that key.'))
def _replyApproximateFactoids(self, irc, msg, channel, key, error=True):
if self.registryValue('replyApproximateSearchKeys'):
factoids = self._searchFactoid(channel, key)
if factoids:
keylist = ["'%s'" % (fact,) for fact in factoids]
keylist = ', '.join(keylist)
irc.reply("I do not know about '%s', but I do know about these similar topics: %s" % (key, keylist))
elif error:
irc.error('No factoid matches that key.')
def invalidCommand(self, irc, msg, tokens): def invalidCommand(self, irc, msg, tokens):
if irc.isChannel(msg.args[0]): if irc.isChannel(msg.args[0]):
channel = msg.args[0] channel = msg.args[0]
@ -281,12 +290,7 @@ class Factoids(callbacks.Plugin, plugins.ChannelDBHandler):
if factoids: if factoids:
self._replyFactoids(irc, msg, key, channel, factoids, error=False) self._replyFactoids(irc, msg, key, channel, factoids, error=False)
else: else:
if self.registryValue('replyWhenInvalidCommandSearchKeys'): self._replyApproximateFactoids(irc, msg, channel, key, error=False)
factoids = self._searchFactoid(channel, key)
if factoids:
keylist = ["'%s'" % (fact,) for fact in factoids]
keylist = ', '.join(keylist)
irc.reply("I do not know about '%s', but I do know about these similar topics: %s" % (key, keylist))
@internationalizeDocstring @internationalizeDocstring
def whatis(self, irc, msg, args, channel, words): def whatis(self, irc, msg, args, channel, words):
@ -304,7 +308,10 @@ class Factoids(callbacks.Plugin, plugins.ChannelDBHandler):
irc.errorInvalid(_('key id')) irc.errorInvalid(_('key id'))
key = ' '.join(words) key = ' '.join(words)
factoids = self._lookupFactoid(channel, key) factoids = self._lookupFactoid(channel, key)
self._replyFactoids(irc, msg, key, channel, factoids, number) if factoids:
self._replyFactoids(irc, msg, key, channel, factoids, number)
else:
self._replyApproximateFactoids(irc, msg, channel, key)
whatis = wrap(whatis, ['channel', many('something')]) whatis = wrap(whatis, ['channel', many('something')])
@internationalizeDocstring @internationalizeDocstring

View File

@ -157,22 +157,22 @@ class FactoidsTestCase(ChannelPluginTestCase):
showFactoidIfOnlyOneMatch.setValue(orig) showFactoidIfOnlyOneMatch.setValue(orig)
def testInvalidCommand(self): def testInvalidCommand(self):
orig = conf.supybot.plugins.Factoids.replyWhenInvalidCommand() self.assertNotError('learn foo as bar')
try: self.assertRegexp('foo', 'bar')
conf.supybot.plugins.Factoids.\ self.assertNotError('learn mooz as cowz')
replyWhenInvalidCommand.setValue(True) self.assertRegexp('moo', 'mooz')
self.assertNotError('learn foo as bar') self.assertRegexp('mzo', 'mooz')
self.assertRegexp('foo', 'bar') self.assertRegexp('moz', 'mooz')
self.assertNotError('learn mooz as cowz') self.assertNotError('learn moped as pretty fast')
self.assertRegexp('moo', 'mooz') self.assertRegexp('moe', 'mooz.*moped')
self.assertRegexp('mzo', 'mooz') self.assertError('nosuchthing')
self.assertRegexp('moz', 'mooz')
self.assertNotError('learn moped as pretty fast') def testWhatis(self):
self.assertRegexp('moe', 'mooz.*moped') self.assertNotError('learn foo as bar')
self.assertError('nosuchthing') self.assertRegexp('whatis foo', 'bar')
finally: self.assertRegexp('whatis foob', 'foo')
conf.supybot.plugins.Factoids.\ self.assertNotError('learn foob as barb')
replyWhenInvalidCommand.setValue(orig) self.assertRegexp('whatis foom', 'foo.*foob')
def testAlias(self): def testAlias(self):
self.assertNotError('learn foo as bar') self.assertNotError('learn foo as bar')