Changed searchfactoids to default to a glob search; --regexp and --exact searches work with specific options.

This commit is contained in:
Jeremy Fincher 2003-10-04 10:16:57 +00:00
parent bbbc97c11b
commit 9543859047
2 changed files with 49 additions and 29 deletions

View File

@ -37,6 +37,7 @@ available on demand via several commands.
from baseplugin import * from baseplugin import *
import time import time
import getopt
import os.path import os.path
import sqlite import sqlite
@ -350,29 +351,41 @@ class Factoids(ChannelDBHandler, callbacks.Privmsg):
_sqlTrans = string.maketrans('*?', '%_') _sqlTrans = string.maketrans('*?', '%_')
def searchfactoids(self, irc, msg, args): def searchfactoids(self, irc, msg, args):
"""[<channel>] <regexp|string> """[<channel>] [--{regexp,exact}=<value>] [<glob>]
Searches the keyspace for keys matching <regexp>. If <regexp|string> Searches the keyspace for keys matching <glob>. If --regexp is given,
isn't a regexp (i.e, it's not of the form m/foo/ or /bar/) then the it associated value is taken as a regexp and matched against the keys;
literal string is searched for. if --exact is given, its associated value is taken as an exact string
to match against the key.
""" """
channel = privmsgs.getChannel(msg, args) channel = privmsgs.getChannel(msg, args)
regexp = privmsgs.getArgs(args) (optlist, rest) = getopt.getopt(args, '', ['regexp=', 'exact='])
try: criteria = []
r = utils.perlReToPythonRe(regexp) formats = []
def p(s): predicateName = 'p'
return int(bool(r.search(s)))
except ValueError, e:
if not regexp.startswith('m/') or regexp[0] == '/' == regexp[-1]:
def p(s):
return int(regexp in s)
else:
irc.error(msg, 'Invalid regular expression.')
return
db = self.getDb(channel) db = self.getDb(channel)
db.create_function('p', 1, p) for (option, arg) in optlist:
if option == '--exact':
### FIXME: no way to escape LIKE metacharacters in SQLite.
criteria.append('key LIKE %s')
formats.append('%' + arg + '%')
elif option == '--regexp':
criteria.append('%s(key)' % predicateName)
try:
r = utils.perlReToPythonRe(arg)
except ValueError, e:
irc.error(msg, 'Invalid regexp: %s' % e)
return
def p(s, r=r):
return int(bool(r.search(s)))
db.create_function(predicateName, 1, p)
predicateName += 'p'
for glob in rest:
criteria.append('key LIKE %s')
formats.append(glob.translate(self._sqlTrans))
cursor = db.cursor() cursor = db.cursor()
cursor.execute("""SELECT key FROM keys WHERE p(key)""") sql = """SELECT key FROM keys WHERE %s""" % ' AND '.join(criteria)
cursor.execute(sql, formats)
if cursor.rowcount == 0: if cursor.rowcount == 0:
irc.reply(msg, 'No keys matched that query.') irc.reply(msg, 'No keys matched that query.')
elif cursor.rowcount > 100: elif cursor.rowcount > 100:
@ -381,12 +394,7 @@ class Factoids(ChannelDBHandler, callbacks.Privmsg):
else: else:
keys = [repr(t[0]) for t in cursor.fetchall()] keys = [repr(t[0]) for t in cursor.fetchall()]
s = utils.commaAndify(keys) s = utils.commaAndify(keys)
if len(s) > 450-len(irc.prefix): irc.reply(msg, s)
irc.reply(msg, '%s matched that query; '
'please narrow your query.' % \
utils.nItems(cursor.rowcount, 'key'))
else:
irc.reply(msg, s)
Class = Factoids Class = Factoids

View File

@ -73,12 +73,24 @@ class FactoidsTestCase(ChannelPluginTestCase, PluginDocumentation):
self.assertNotError('learn inkedmn as another of my developers') self.assertNotError('learn inkedmn as another of my developers')
self.assertNotError('learn jamessan as a developer of much python') self.assertNotError('learn jamessan as a developer of much python')
self.assertNotError('learn bwp as the author of my weather command') self.assertNotError('learn bwp as the author of my weather command')
self.assertRegexp('searchfactoids /.w./', 'bwp') self.assertRegexp('searchfactoids --regexp /.w./', 'bwp')
self.assertRegexp('searchfactoids /^.+i/', 'jemfinch.*strike') self.assertRegexp('searchfactoids --regexp /^.+i/', 'jemfinch.*strike')
self.assertNotRegexp('searchfactoids /^.+i/', 'inkedmn') self.assertNotRegexp('searchfactoids --regexp /^.+i/', 'inkedmn')
self.assertRegexp('searchfactoids /^j/', 'jemfinch.*jamessan') self.assertRegexp('searchfactoids --regexp /^j/', 'jemfinch.*jamessan')
self.assertRegexp('searchfactoids ke', self.assertRegexp('searchfactoids j*', 'jemfinch.*jamessan')
self.assertRegexp('searchfactoids --exact ke',
'inkedmn.*strike|strike.*inkedmn') 'inkedmn.*strike|strike.*inkedmn')
self.assertRegexp('searchfactoids *ke*',
'inkedmn.*strike|strike.*inkedmn')
def testNotZeroIndexed(self):
self.assertNotError('learn foo as bar')
self.assertNotRegexp('factoidinfo foo', '#0')
self.assertNotRegexp('whatis foo', '#0')
self.assertNotError('learn foo as baz')
self.assertNotRegexp('factoidinfo foo', '#0')
self.assertNotRegexp('whatis foo', '#0')
# vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78: # vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78: