diff --git a/plugins/MoobotFactoids.py b/plugins/MoobotFactoids.py index 3d9a8f143..78a63428a 100644 --- a/plugins/MoobotFactoids.py +++ b/plugins/MoobotFactoids.py @@ -471,67 +471,56 @@ class MoobotFactoids(callbacks.PrivmsgCommandAndRegexp): self._lock(irc, msg, args, False) _mostCount = 10 - # _mostDict is maps the requested statsitic to the set of commands that - # need to be done to generate the response. Each tuple consists of 5 - # items. These are: - # 1) the SQL used to retrieve the information, - # 2) the format string for the list of 'most' items - # 3) a lambda expression which returns a tuple of the items from - # cursor.fetchall(). This tuple contains the items that will be used - # in the string supplied in 2). - # 4) the format string that will be at the head of the irc.reply message - # 5) the word which describes what we are generating statistics about. - # This will be used in the string from 4) - _mostDict = {'popular': - {'sql':"""SELECT key,requested_count FROM factoids WHERE - requested_count > 0 ORDER by requested_count DESC - LIMIT %s""", - 'format':'%s (%s)', - 'genlist':lambda c: [(t[0], t[1]) for t in c], - 'head':'Top %s %s: %s', - 'desc':'factoid' - }, - 'authored': - {'sql':"""SELECT count(key),created_by FROM factoids GROUP - BY created_by ORDER BY count(key) DESC LIMIT %s""", - 'format':'%s (%s)', - 'genlist':lambda c: [(ircdb.users.getUser(t[1]).name, - t[0]) for t in c], - 'head':'Top %s %s: %s', - 'desc':'author' - }, - 'recent': - {'sql':"""SELECT key FROM factoids ORDER by created_at DESC - LIMIT %s""", - 'format':'%s', - 'genlist':lambda c: [t[0] for t in c], - 'head':'%s latest %s: %s', - 'desc':'factoid' - } - } + class MostException(Exception): + pass def most(self, irc, msg, args): """ - Lists the most factoids. list the + Lists the most factoids. lists the most frequently requested factoids. lists the author with the most factoids. lists the most recently created factoids. """ - arg = privmsgs.getArgs(args,needed=1) - arg = arg.lower() - if arg in self._mostDict: - args = self._mostDict[arg] - cursor = self.db.cursor() - cursor.execute(args['sql'] % self._mostCount) - if cursor.rowcount == 0: - irc.reply(msg, 'I can\'t find any factoids.') - else: - resp = [args['format'] % t for t in args['genlist']( - cursor.fetchall())] - l = len(resp) - irc.reply(msg, args['head'] % (l, utils.pluralize(l, - args['desc']), utils.commaAndify(resp))) - else: + arg = privmsgs.getArgs(args) + arg = arg.capitalize() + method = getattr(self, '_most%s' % arg, None) + if method is None: raise callbacks.ArgumentError + cursor = self.db.cursor() + cursor.execute("""SELECT COUNT(*) FROM factoids""") + if int(cursor.fetchone()[0]) == 0: + irc.error(msg, 'I don\'t have any factoids in my database!') + else: + try: + irc.reply(msg, method(cursor, self._mostCount)) + except self.MostException, e: + irc.error(msg, str(e)) + + def _mostAuthored(self, cursor, limit): + cursor.execute("""SELECT created_by, count(key) FROM factoids + GROUP BY created_by + ORDER BY count(key) DESC LIMIT %s""", limit) + L = ['%s (%s)' % (ircdb.users.getUser(t[0]).name, t[1]) + for t in cursor.fetchall()] + return 'Top %s: %s' % \ + (utils.nItems(len(L), 'author'), utils.commaAndify(L)) + + def _mostRecent(self, cursor, limit): + cursor.execute("""SELECT key FROM factoids + ORDER by created_at DESC LIMIT %s""", limit) + L = [repr(t[0]) for t in cursor.fetchall()] + return '%s: %s' % \ + (utils.nItems(len(L), 'factoid', between='latest'), + utils.commaAndify(L)) + + def _mostPopular(self, cursor, limit): + cursor.execute("""SELECT key, requested_count FROM factoids + WHERE requested_count > 0 + ORDER BY requested_count DESC LIMIT %s""", limit) + if cursor.rowcount == 0: + raise self.MostException, 'No factoids have been requested.' + L = ['%r (%s)' % (t[0], t[1]) for t in cursor.fetchall()] + return 'Top %s: %s' % \ + (utils.nItems(len(L), 'factoid'), utils.commaAndify(L)) def listauth(self, irc, msg, args): """ diff --git a/test/test_MoobotFactoids.py b/test/test_MoobotFactoids.py index e37e914f5..0bc323321 100644 --- a/test/test_MoobotFactoids.py +++ b/test/test_MoobotFactoids.py @@ -91,26 +91,31 @@ if sqlite is not None: self.assertNotError('moo is foo') self.assertRegexp('factinfo moo', '^moo: Created by tester on.*$') self.assertNotError('moo') - self.assertRegexp('factinfo moo', '^moo: Created by tester on' + self.assertRegexp('factinfo moo', + '^moo: Created by tester on' '.*?\. Last requested by foo!bar@baz on .*?, ' 'requested 1 time.$') self.assertNotError('moo') - self.assertRegexp('factinfo moo', '^moo: Created by tester on' + self.assertRegexp('factinfo moo', + '^moo: Created by tester on' '.*?\. Last requested by foo!bar@baz on .*?, ' 'requested 2 times.$') self.assertNotError('moo =~ s/foo/bar/') - self.assertRegexp('factinfo moo', '^moo: Created by tester on' + self.assertRegexp('factinfo moo', + '^moo: Created by tester on' '.*?\. Last modified by tester on .*?\. ' 'Last requested by foo!bar@baz on .*?, ' 'requested 2 times.$') self.assertNotError('lock moo') - self.assertRegexp('factinfo moo', '^moo: Created by tester on' + self.assertRegexp('factinfo moo', + '^moo: Created by tester on' '.*?\. Last modified by tester on .*?\. ' 'Last requested by foo!bar@baz on .*?, ' 'requested 2 times. ' 'Locked by tester on .*\.$') self.assertNotError('unlock moo') - self.assertRegexp('factinfo moo', '^moo: Created by tester on' + self.assertRegexp('factinfo moo', + '^moo: Created by tester on' '.*?\. Last modified by tester on .*?\. ' 'Last requested by foo!bar@baz on .*?, ' 'requested 2 times.$') @@ -120,26 +125,29 @@ if sqlite is not None: self.assertNotError('foo =~ s/bar/blah/') self.assertNotError('foo') self.assertNotError('no foo is baz') - self.assertRegexp('factinfo foo', '^foo: Created by tester on' + self.assertRegexp('factinfo foo', + '^foo: Created by tester on' '(?!(request|modif)).*?\.$') def testLockUnlock(self): self.assertNotError('moo is moo') self.assertNotError('lock moo') - self.assertRegexp('factinfo moo', '^moo: Created by tester on' + self.assertRegexp('factinfo moo', + '^moo: Created by tester on' '.*?\. Locked by tester on .*?\.') # switch user self.prefix = 'moo!moo@moo' self.assertNotError('register nottester moo') self.assertError('unlock moo') - self.assertRegexp('factinfo moo', '^moo: Created by tester on' + self.assertRegexp('factinfo moo', + '^moo: Created by tester on' '.*?\. Locked by tester on .*?\.') # switch back self.prefix = 'foo!bar@baz' self.assertNotError('identify tester moo') self.assertNotError('unlock moo') - self.assertRegexp('factinfo moo', '^moo: Created by tester on' - '.*?\.') + self.assertRegexp('factinfo moo', + '^moo: Created by tester on.*?\.') def testChangeFactoid(self): self.assertNotError('moo is moo') @@ -171,51 +179,54 @@ if sqlite is not None: self.assertNotError('moogle is moo') self.assertError('most popular') self.assertResponse('most authored', 'Top 1 author: moo (1)') - self.assertResponse('most recent', '1 latest factoid: moogle') + self.assertResponse('most recent', "1 latest factoid: 'moogle'") self.assertResponse('moogle', 'moo') - self.assertResponse('most popular', 'Top 1 factoid: moogle (1)') + self.assertResponse('most popular', "Top 1 factoid: 'moogle' (1)") # Check plural response self.prefix = userPrefix2 self.assertNotError('mogle is mo') - self.assertResponse('most authored', 'Top 2 authors: moo (1) and '\ - 'boo (1)') - self.assertResponse('most recent', '2 latest factoids: mogle and '\ - 'moogle') + self.assertResponse('most authored', + 'Top 2 authors: moo (1) and boo (1)') + self.assertResponse('most recent', + "2 latest factoids: 'mogle' and 'moogle'") self.assertResponse('moogle', 'moo') - self.assertResponse('most popular', 'Top 1 factoid: moogle (2)') + self.assertResponse('most popular', "Top 1 factoid: 'moogle' (2)") self.assertResponse('mogle', 'mo') - self.assertResponse('most popular', 'Top 2 factoids: moogle (2) '\ - 'and mogle (1)') + self.assertResponse('most popular', + "Top 2 factoids: 'moogle' (2) and 'mogle' (1)") # Check most author ordering self.assertNotError('moo is oom') - self.assertResponse('most authored', 'Top 2 authors: boo (2) and '\ - 'moo (1)') + self.assertResponse('most authored', + 'Top 2 authors: boo (2) and moo (1)') def testListkeys(self): self.assertResponse('listkeys %', 'No keys matching \'%\' found.') self.assertNotError('moo is moo') - self.assertResponse('listkeys moo', 'Key search for \'moo\' ' - '(1 found): \'moo\'') + self.assertResponse('listkeys moo', + 'Key search for \'moo\' (1 found): \'moo\'') self.assertResponse('listkeys foo', 'No keys matching \'foo\' ' 'found.') # Throw in a bunch more for i in range(10): self.assertNotError('moo%s is moo' % i) - self.assertRegexp('listkeys moo', '^Key search for \'moo\' ' + self.assertRegexp('listkeys moo', + '^Key search for \'moo\' ' '\(11 found\): (\'moo\d*\', )+and \'moo9\'$') self.assertNotError('foo is bar') - self.assertRegexp('listkeys %', '^Key search for \'\%\' ' + self.assertRegexp('listkeys %', + '^Key search for \'\%\' ' '\(12 found\): \'foo\', (\'moo\d*\', )+and ' '\'moo9\'$') # Check quoting self.assertNotError('foo\' is bar') - self.assertResponse('listkeys foo', 'Key search for \'foo\' ' + self.assertResponse('listkeys foo', + 'Key search for \'foo\' ' '(2 found): \'foo\' and "foo\'"') def testListvalues(self): self.assertNotError('moo is moo') - self.assertResponse('listvalues moo', 'Value search for \'moo\' ' - '(1 found): \'moo\'') + self.assertResponse('listvalues moo', + 'Value search for \'moo\' (1 found): \'moo\'') def testListauth(self): self.assertNotError('moo is moo')