diff --git a/ChangeLog b/ChangeLog index d99819243..a04460b4e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,5 @@ + * Added Lookup.search + * Updated Todo.remove to allow removing multiple taskids * Added Topic.reorder, a new command for reordering the topics in a diff --git a/plugins/Lookup.py b/plugins/Lookup.py index 444fc21c6..3b9e2f107 100644 --- a/plugins/Lookup.py +++ b/plugins/Lookup.py @@ -42,6 +42,8 @@ import re import sys import sets import types +import getopt +import string import conf import utils @@ -98,6 +100,9 @@ class Lookup(callbacks.Privmsg): self.lookupDomains = sets.Set() self.dbHandler = LookupDB(name=os.path.join(conf.dataDir, 'Lookup')) + def _shrink(self, s): + return utils.ellipsisify(s, 50) + def die(self): self.dbHandler.die() @@ -196,6 +201,56 @@ class Lookup(callbacks.Privmsg): self.lookupDomains.add(name) setattr(self.__class__, name, f) + _sqlTrans = string.maketrans('*?', '%_') + def search(self, irc, msg, args): + """[--{regexp,exact}=] + + Searches the domain for lookups matching . If --regexp + is given, its associated value is taken as a regexp and matched + against the lookups; if --exact is given, its associated value is + taken as an exact string to match against the lookups. + """ + (options, rest) = getopt.getopt(args, '', ['regexp=', 'exact=']) + (name, globs) = privmsgs.getArgs(rest, optional=1) + db = self.dbHandler.getDb() + criteria = [] + formats = [] + predicateName = 'p' + for (option, arg) in options: + if option == '--exact': + criteria.append('value LIKE %s') + formats.append('%' + arg + '%') + elif option == '--regexp': + criteria.append('%s(value)' % predicateName) + try: + r = utils.perlReToPythonRe(arg) + except ValueError, e: + irc.error(msg, '%r is not a valid regular expression' % + arg) + return + def p(s, r=r): + return int(bool(r.search(s))) + db.create_function(predicateName, 1, p) + predicateName += 'p' + for glob in globs.split(): + criteria.append('value LIKE %s') + if '?' not in glob and '*' not in glob: + glob = '*%s*' % glob + formats.append(glob.translate(self._sqlTrans)) + #print 'criteria: %s' % repr(criteria) + #print 'formats: %s' % repr(formats) + cursor = db.cursor() + sql = """SELECT key, value FROM %s WHERE %s""" % (name, + ' AND '.join(criteria)) + #print 'sql: %s' % sql + cursor.execute(sql, formats) + if cursor.rowcount == 0: + irc.reply(msg, 'No %ss matched that query.' % name) + else: + lookups = ['%s: %s' % (item[0], self._shrink(item[1])) + for item in cursor.fetchall()] + irc.reply(msg, utils.commaAndify(lookups)) + def _lookup(self, irc, msg, args): """ diff --git a/test/test_Lookup.py b/test/test_Lookup.py index a7047b812..64b3d3468 100644 --- a/test/test_Lookup.py +++ b/test/test_Lookup.py @@ -87,8 +87,13 @@ if sqlite: fd.write('\n') fd.close() self.assertNotError('lookup add test foo.supyfact') - + def testSearch(self): + self.assertNotError('lookup add test foo.supyfact') + self.assertResponse('search test mom', 'your mom: my mom') + self.assertResponse('search test b?r', 'foo: bar') + self.assertResponse('search --exact bar test', 'foo: bar') + self.assertResponse('search --regexp m/bar/ test', 'foo: bar') # vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78: