mirror of
https://github.com/Mikaela/Limnoria.git
synced 2025-01-29 21:54:22 +01:00
Moved the appropriate commands from Misc to Plugin, and fixed the test failures in the process.
This commit is contained in:
parent
180291dd34
commit
8756b79cc4
@ -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
|
||||
|
@ -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):
|
||||
"""<command>
|
||||
|
||||
Returns the plugin (or plugins) <command> 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):
|
||||
"""<plugin>
|
||||
|
||||
Returns the author of <plugin>. 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):
|
||||
"""[<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):
|
||||
"""<plugin> [<nick>]
|
||||
|
||||
Replies with a list of people who made contributions to a given plugin.
|
||||
If <nick> is specified, that person's specific contributions will
|
||||
be listed. Note: The <nick> 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
|
||||
|
||||
|
@ -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])
|
||||
|
@ -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.
|
||||
|
@ -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):
|
||||
"""<plugin>
|
||||
|
||||
@ -58,6 +62,161 @@ class Plugin(callbacks.Plugin):
|
||||
L.sort()
|
||||
irc.reply(format('%L', L))
|
||||
|
||||
def plugin(self, irc, msg, args, command):
|
||||
"""<command>
|
||||
|
||||
Returns the plugin(s) that <command> 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):
|
||||
"""<plugin>
|
||||
|
||||
Returns the author of <plugin>. 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):
|
||||
"""<plugin> [<nick>]
|
||||
|
||||
Replies with a list of people who made contributions to a given plugin.
|
||||
If <nick> is specified, that person's specific contributions will
|
||||
be listed. Note: The <nick> 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:
|
||||
|
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user