From 8756b79cc48dedafc831ab98d0866a0eaf935642 Mon Sep 17 00:00:00 2001 From: Jeremy Fincher Date: Fri, 18 Feb 2005 06:31:26 +0000 Subject: [PATCH] Moved the appropriate commands from Misc to Plugin, and fixed the test failures in the process. --- plugins/Misc/__init__.py | 4 +- plugins/Misc/plugin.py | 153 ---------------------------------- plugins/Misc/test.py | 31 ------- plugins/Plugin/__init__.py | 4 +- plugins/Plugin/plugin.py | 163 ++++++++++++++++++++++++++++++++++++- plugins/Plugin/test.py | 41 +++++++++- 6 files changed, 205 insertions(+), 191 deletions(-) diff --git a/plugins/Misc/__init__.py b/plugins/Misc/__init__.py index 7b1e61a43..67c0e2677 100644 --- a/plugins/Misc/__init__.py +++ b/plugins/Misc/__init__.py @@ -42,9 +42,7 @@ __author__ = supybot.authors.jemfinch # This is a dictionary mapping supybot.Author instances to lists of # contributions. -__contributors__ = { - supybot.authors.skorobeus: ['contributors'], - } +__contributors__ = {} import config import plugin diff --git a/plugins/Misc/plugin.py b/plugins/Misc/plugin.py index c5f2069ec..32bbf4541 100644 --- a/plugins/Misc/plugin.py +++ b/plugins/Misc/plugin.py @@ -220,45 +220,6 @@ class Misc(callbacks.Plugin): irc.reply('My source is at http://supybot.com/') source = wrap(source) - def plugin(self, irc, msg, args, command): - """ - - Returns the plugin (or plugins) is in. If this command is - nested, it returns only the plugin name(s). If given as a normal - command, it returns a more verbose, user-friendly response. - """ - cbs = callbacks.findCallbackForCommand(irc, command) - if cbs: - names = [cb.name() for cb in cbs] - names.sort() - if irc.nested: - irc.reply(format('%L', names)) - else: - s = 'plugin' - if len(names) > 1: - s = utils.str.pluralize(s) - irc.reply(format('The %q command is available in the %L %s.', - command, names, s)) - else: - irc.error('There is no such command %s.' % command) - plugin = wrap(plugin, ['commandName']) - - def author(self, irc, msg, args, cb): - """ - - Returns the author of . This is the person you should talk to - if you have ideas, suggestions, or other comments about a given plugin. - """ - if cb is None: - irc.error('That plugin does not seem to be loaded.') - return - module = sys.modules[cb.__class__.__module__] - if hasattr(module, '__author__') and module.__author__: - irc.reply(utils.web.mungeEmail(str(module.__author__))) - else: - irc.reply('That plugin doesn\'t have an author that claims it.') - author = wrap(author, [('plugin')]) - def more(self, irc, msg, args, nick): """[] @@ -412,120 +373,6 @@ class Misc(callbacks.Plugin): irc.reply(s, to=target, private=True) tell = wrap(tell, ['something', 'text']) - def contributors(self, irc, msg, args, cb, nick): - """ [] - - Replies with a list of people who made contributions to a given plugin. - If is specified, that person's specific contributions will - be listed. Note: The is the part inside of the parentheses - in the people listing. - """ - def getShortName(authorInfo): - """ - Take an Authors object, and return only the name and nick values - in the format 'First Last (nick)'. - """ - return '%(name)s (%(nick)s)' % authorInfo.__dict__ - def buildContributorsString(longList): - """ - Take a list of long names and turn it into : - shortname[, shortname and shortname]. - """ - L = [getShortName(n) for n in longList] - return format('%L', L) - def sortAuthors(): - """ - Sort the list of 'long names' based on the number of contributions - associated with each. - """ - L = module.__contributors__.items() - def negativeSecondElement(x): - return -len(x[1]) - utils.sortBy(negativeSecondElement, L) - return [t[0] for t in L] - def buildPeopleString(module): - """ - Build the list of author + contributors (if any) for the requested - plugin. - """ - head = 'The %s plugin' % cb.name() - author = 'has not been claimed by an author' - conjunction = 'and' - contrib = 'has no contributors listed.' - hasAuthor = False - hasContribs = False - if getattr(module, '__author__', None): - author = 'was written by %s' % \ - utils.web.mungeEmail(str(module.__author__)) - hasAuthor = True - if getattr(module, '__contributors__', None): - contribs = sortAuthors() - if hasAuthor: - try: - contribs.remove(module.__author__) - except ValueError: - pass - if contribs: - contrib = format('%s %h contributed to it.', - buildContributorsString(contribs), - len(contribs)) - hasContribs = True - elif hasAuthor: - contrib = 'has no additional contributors listed.' - if hasContribs and not hasAuthor: - conjunction = 'but' - return ' '.join([head, author, conjunction, contrib]) - def buildPersonString(module): - """ - Build the list of contributions (if any) for the requested person - for the requested plugin - """ - isAuthor = False - authorInfo = getattr(supybot.authors, nick, None) - if not authorInfo: - return 'The nick specified (%s) is not a registered ' \ - 'contributor.' % nick - fullName = utils.web.mungeEmail(str(authorInfo)) - contributions = [] - if hasattr(module, '__contributors__'): - if authorInfo not in module.__contributors__: - return 'The %s plugin does not have \'%s\' listed as a ' \ - 'contributor.' % (cb.name(), nick) - contributions = module.__contributors__[authorInfo] - if getattr(module, '__author__', False) == authorInfo: - isAuthor = True - (nonCommands, commands) = utils.iter.partition(lambda s: ' ' in s, - contributions) - results = [] - if commands: - s = 'command' - if len(commands) > 1: - s = utils.str.pluralize(s) - results.append(format('the %L %s', commands, s)) - if nonCommands: - results.append(format('the %L', nonCommands)) - if results and isAuthor: - return format( - '%s wrote the %s plugin and also contributed %L.', - (fullName, cb.name(), results)) - elif results and not isAuthor: - return format('%s contributed %L to the %s plugin.', - fullName, results, cb.name()) - elif isAuthor and not results: - return '%s wrote the %s plugin' % (fullName, cb.name()) - # XXX Does this ever actually get reached? - else: - return '%s has no listed contributions for the %s plugin.' % \ - (fullName, cb.name()) - # First we need to check and see if the requested plugin is loaded - module = sys.modules[cb.__class__.__module__] - if not nick: - irc.reply(buildPeopleString(module)) - else: - nick = ircutils.toLower(nick) - irc.reply(buildPersonString(module)) - contributors = wrap(contributors, ['plugin', additional('nick')]) - def ping(self, irc, msg, args): """takes no arguments diff --git a/plugins/Misc/test.py b/plugins/Misc/test.py index c1cb433b6..399298c15 100644 --- a/plugins/Misc/test.py +++ b/plugins/Misc/test.py @@ -106,33 +106,6 @@ class MiscTestCase(ChannelPluginTestCase): def testListIncludesDispatcherIfThereIsAnOriginalCommand(self): self.assertRegexp('list Dict', r'\bdict\b') - def testContributors(self): - # Test ability to list contributors - self.assertNotError('contributors Misc') - # Test ability to list contributions - # Verify that when a single command contribution has been made, - # the word "command" is properly not pluralized. - # Note: This will break if the listed person ever makes more than - # one contribution to the Misc plugin - self.assertRegexp('contributors Misc skorobeus', 'command') - # Test handling of pluralization of "command" when person has - # contributed more than one command to the plugin. - # -- Need to create this case, check it with the regexp 'commands' - # Test handling of invalid plugin - self.assertRegexp('contributors InvalidPlugin', 'not a valid plugin') - # Test handling of invalid person - self.assertRegexp('contributors Misc noname', - 'not a registered contributor') - # Test handling of valid person with no contributions - # Note: This will break if the listed person ever makes a contribution - # to the Misc plugin - self.assertRegexp('contributors Misc bwp', - 'listed as a contributor') - - def testContributorsIsCaseInsensitive(self): - self.assertNotError('contributors Misc Skorobeus') - self.assertNotError('contributors Misc sKoRoBeUs') - if network: def testVersion(self): print '*** This test should start passing when we have our '\ @@ -142,10 +115,6 @@ class MiscTestCase(ChannelPluginTestCase): def testSource(self): self.assertNotError('source') - def testPlugin(self): - self.assertRegexp('plugin plugin', 'available.*Misc') - self.assertResponse('echo [plugin plugin]', 'Misc') - def testTell(self): m = self.getMsg('tell foo [plugin tell]') self.failUnless('let you do' in m.args[1]) diff --git a/plugins/Plugin/__init__.py b/plugins/Plugin/__init__.py index a21411662..e33761905 100644 --- a/plugins/Plugin/__init__.py +++ b/plugins/Plugin/__init__.py @@ -45,7 +45,9 @@ __author__ = supybot.authors.jemfinch # This is a dictionary mapping supybot.Author instances to lists of # contributions. -__contributors__ = {} +__contributors__ = { + supybot.authors.skorobeus: ['contributors'], + } import config # This had to be renamed because of stupid case-insensitivity issues. diff --git a/plugins/Plugin/plugin.py b/plugins/Plugin/plugin.py index be8e588d0..96a8ca2c1 100644 --- a/plugins/Plugin/plugin.py +++ b/plugins/Plugin/plugin.py @@ -27,6 +27,8 @@ # POSSIBILITY OF SUCH DAMAGE. ### +import supybot + import supybot.utils as utils from supybot.commands import * import supybot.plugins as plugins @@ -35,8 +37,10 @@ import supybot.callbacks as callbacks class Plugin(callbacks.Plugin): - """Add the help for "@help Plugin" here - This should describe *how* to use this plugin.""" + """This plugin exists to help users manage their plugins. Use 'plugin + list' to list the loaded plugins; use 'plugin help' to get this sort of + help from other plugins; use the 'plugin' command itself to determine what + plugin a command exists in.""" def help(self, irc, msg, args, cb): """ @@ -58,6 +62,161 @@ class Plugin(callbacks.Plugin): L.sort() irc.reply(format('%L', L)) + def plugin(self, irc, msg, args, command): + """ + + Returns the plugin(s) that is in. + """ + (maxL, cbs) = irc.findCallbacksForArgs(command) + L = [] + for cb in cbs: + if maxL == command: + L.append(cb.name()) + command = callbacks.formatCommand(command) + if L: + if irc.nested: + irc.reply(format('%L', L)) + else: + if len(L) > 1: + plugin = 'plugins' + else: + plugin = 'plugin' + irc.reply(format('The %q command is available in the %L %s.', + command, L, plugin)) + else: + irc.error('There is no command %q', command) + plugin = wrap(plugin, [many('something')]) + + def author(self, irc, msg, args, cb): + """ + + Returns the author of . This is the person you should talk to + if you have ideas, suggestions, or other comments about a given plugin. + """ + if cb is None: + irc.error('That plugin does not seem to be loaded.') + return + module = cb.classModule + if hasattr(module, '__author__') and module.__author__: + irc.reply(utils.web.mungeEmail(str(module.__author__))) + else: + irc.reply('That plugin doesn\'t have an author that claims it.') + author = wrap(author, [('plugin')]) + + def contributors(self, irc, msg, args, cb, nick): + """ [] + + Replies with a list of people who made contributions to a given plugin. + If is specified, that person's specific contributions will + be listed. Note: The is the part inside of the parentheses + in the people listing. + """ + def getShortName(authorInfo): + """ + Take an Authors object, and return only the name and nick values + in the format 'First Last (nick)'. + """ + return '%(name)s (%(nick)s)' % authorInfo.__dict__ + def buildContributorsString(longList): + """ + Take a list of long names and turn it into : + shortname[, shortname and shortname]. + """ + L = [getShortName(n) for n in longList] + return format('%L', L) + def sortAuthors(): + """ + Sort the list of 'long names' based on the number of contributions + associated with each. + """ + L = module.__contributors__.items() + def negativeSecondElement(x): + return -len(x[1]) + utils.sortBy(negativeSecondElement, L) + return [t[0] for t in L] + def buildPeopleString(module): + """ + Build the list of author + contributors (if any) for the requested + plugin. + """ + head = 'The %s plugin' % cb.name() + author = 'has not been claimed by an author' + conjunction = 'and' + contrib = 'has no contributors listed.' + hasAuthor = False + hasContribs = False + if getattr(module, '__author__', None): + author = 'was written by %s' % \ + utils.web.mungeEmail(str(module.__author__)) + hasAuthor = True + if getattr(module, '__contributors__', None): + contribs = sortAuthors() + if hasAuthor: + try: + contribs.remove(module.__author__) + except ValueError: + pass + if contribs: + contrib = format('%s %h contributed to it.', + buildContributorsString(contribs), + len(contribs)) + hasContribs = True + elif hasAuthor: + contrib = 'has no additional contributors listed.' + if hasContribs and not hasAuthor: + conjunction = 'but' + return ' '.join([head, author, conjunction, contrib]) + def buildPersonString(module): + """ + Build the list of contributions (if any) for the requested person + for the requested plugin + """ + isAuthor = False + authorInfo = getattr(supybot.authors, nick, None) + if not authorInfo: + return 'The nick specified (%s) is not a registered ' \ + 'contributor.' % nick + fullName = utils.web.mungeEmail(str(authorInfo)) + contributions = [] + if hasattr(module, '__contributors__'): + if authorInfo not in module.__contributors__: + return 'The %s plugin does not have \'%s\' listed as a ' \ + 'contributor.' % (cb.name(), nick) + contributions = module.__contributors__[authorInfo] + if getattr(module, '__author__', False) == authorInfo: + isAuthor = True + (nonCommands, commands) = utils.iter.partition(lambda s: ' ' in s, + contributions) + results = [] + if commands: + s = 'command' + if len(commands) > 1: + s = utils.str.pluralize(s) + results.append(format('the %L %s', commands, s)) + if nonCommands: + results.append(format('the %L', nonCommands)) + if results and isAuthor: + return format( + '%s wrote the %s plugin and also contributed %L.', + (fullName, cb.name(), results)) + elif results and not isAuthor: + return format('%s contributed %L to the %s plugin.', + fullName, results, cb.name()) + elif isAuthor and not results: + return '%s wrote the %s plugin' % (fullName, cb.name()) + # XXX Does this ever actually get reached? + else: + return '%s has no listed contributions for the %s plugin.' % \ + (fullName, cb.name()) + # First we need to check and see if the requested plugin is loaded + module = cb.classModule + if not nick: + irc.reply(buildPeopleString(module)) + else: + nick = ircutils.toLower(nick) + irc.reply(buildPersonString(module)) + contributors = wrap(contributors, ['plugin', additional('nick')]) + Class = Plugin # vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78: diff --git a/plugins/Plugin/test.py b/plugins/Plugin/test.py index 7ac30d3cf..6f949f112 100644 --- a/plugins/Plugin/test.py +++ b/plugins/Plugin/test.py @@ -30,7 +30,46 @@ from supybot.test import * class PluginTestCase(PluginTestCase): - plugins = ('Plugin',) + plugins = ('Plugin', 'Utilities') + def testPlugin(self): + self.assertRegexp('plugin plugin', 'available.*Plugin plugin') + self.assertResponse('echo [plugin plugin]', 'Plugin') + + def testList(self): + self.assertRegexp('plugin list', 'Plugin.*Utilities') + + def testHelp(self): + self.assertRegexp('plugin help plugin', 'manage their plugins') + + def testAuthor(self): + self.assertRegexp('plugin author plugin', 'jemfinch') + + def testContributors(self): + # Test ability to list contributors + self.assertNotError('contributors Plugin') + # Test ability to list contributions + # Verify that when a single command contribution has been made, + # the word "command" is properly not pluralized. + # Note: This will break if the listed person ever makes more than + # one contribution to the Plugin plugin + self.assertRegexp('contributors Plugin skorobeus', 'command') + # Test handling of pluralization of "command" when person has + # contributed more than one command to the plugin. + # -- Need to create this case, check it with the regexp 'commands' + # Test handling of invalid plugin + self.assertRegexp('contributors InvalidPlugin', 'not a valid plugin') + # Test handling of invalid person + self.assertRegexp('contributors Plugin noname', + 'not a registered contributor') + # Test handling of valid person with no contributions + # Note: This will break if the listed person ever makes a contribution + # to the Plugin plugin + self.assertRegexp('contributors Plugin bwp', + 'listed as a contributor') + + def testContributorsIsCaseInsensitive(self): + self.assertNotError('contributors Plugin Skorobeus') + self.assertNotError('contributors Plugin sKoRoBeUs') # vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78: