mirror of
https://github.com/Mikaela/Limnoria.git
synced 2024-11-27 05:09:23 +01:00
Changed searchfactoids to default to a glob search; --regexp and --exact searches work with specific options.
This commit is contained in:
parent
bbbc97c11b
commit
9543859047
@ -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
|
||||||
|
@ -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:
|
||||||
|
Loading…
Reference in New Issue
Block a user