mirror of
https://github.com/Mikaela/Limnoria.git
synced 2025-01-23 02:24:12 +01:00
Removed the syntax command; changed interface of callbacks.findCallbackForCommand to return a list of the matching callbacks; fix help to handle the prefixing of the plugin name.
This commit is contained in:
parent
112303af56
commit
55ccb85542
@ -198,8 +198,8 @@ class Alias(callbacks.Privmsg):
|
||||
if name != realName:
|
||||
raise AliasError,'That name isn\'t valid. Try %r instead'%realName
|
||||
name = realName
|
||||
cb = callbacks.findCallbackForCommand(irc, name)
|
||||
if cb is not None and cb != self:
|
||||
cbs = callbacks.findCallbackForCommand(irc, name)
|
||||
if [cb for cb in cbs if cb != self]:
|
||||
raise AliasError, 'A command with the name %r already exists.'%name
|
||||
if name in self.frozen:
|
||||
raise AliasError, 'Alias %r is frozen.' % name
|
||||
|
@ -124,79 +124,60 @@ class MiscCommands(callbacks.Privmsg):
|
||||
irc.error(msg, 'There is no plugin named %s, ' \
|
||||
'or that plugin has no commands.' % name)
|
||||
|
||||
def syntax(self, irc, msg, args):
|
||||
"""<command>
|
||||
|
||||
Gives the syntax for a specific command. To find commands,
|
||||
use the 'list' command to go see the commands offered by a plugin.
|
||||
The 'list' command by itself will show you what plugins have commands.
|
||||
"""
|
||||
command = privmsgs.getArgs(args, needed=0, optional=1)
|
||||
if not command:
|
||||
command = 'help'
|
||||
command = callbacks.canonicalName(command)
|
||||
cb = callbacks.findCallbackForCommand(irc, command)
|
||||
if cb:
|
||||
method = getattr(cb, command)
|
||||
if hasattr(method, '__doc__') and method.__doc__ is not None:
|
||||
doclines = method.__doc__.strip().splitlines()
|
||||
help = doclines.pop(0)
|
||||
irc.reply(msg, '%s %s' % (command, help))
|
||||
else:
|
||||
irc.reply(msg, 'That command exists, '
|
||||
'but has no syntax description.')
|
||||
else:
|
||||
cb = irc.getCallback(command)
|
||||
if cb:
|
||||
s = ''
|
||||
if hasattr(cb, '__doc__') and cb.__doc__ is not None:
|
||||
s = cb.__doc__
|
||||
else:
|
||||
module = sys.modules[cb.__module__]
|
||||
if hasattr(module, '__doc__') and module.__doc__:
|
||||
s = module.__doc__
|
||||
if s:
|
||||
s = ' '.join(map(str.strip, s.splitlines()))
|
||||
if not s.endswith('.'):
|
||||
s += '.'
|
||||
s += ' Use the list command to see what commands this ' \
|
||||
'plugin supports.'
|
||||
else:
|
||||
s = 'That plugin has no help description.'
|
||||
irc.reply(msg, s)
|
||||
else:
|
||||
irc.error(msg, 'There is no such command or plugin.')
|
||||
|
||||
def help(self, irc, msg, args):
|
||||
"""<command>
|
||||
"""[<plugin>] <command>
|
||||
|
||||
This command gives a much more useful description than the simple
|
||||
argument list given by the command 'syntax'.
|
||||
argument list given by the command 'syntax'. <plugin> is only
|
||||
necessary if the command is in more than one plugin.
|
||||
"""
|
||||
def helpFor(method):
|
||||
doclines = method.__doc__.splitlines()
|
||||
simplehelp = '(%s %s)' % (method.__name__, doclines.pop(0))
|
||||
if doclines:
|
||||
doclines = filter(None, doclines)
|
||||
doclines = map(str.strip, doclines)
|
||||
help = ' '.join(doclines)
|
||||
s = '%s -- %s' % (ircutils.bold(simplehelp), help)
|
||||
return s
|
||||
else:
|
||||
return 'That command has no help. The syntax is: %s' % \
|
||||
simplehelp[1:-1]
|
||||
if len(args) > 1:
|
||||
cb = irc.getCallback(args[0])
|
||||
if cb is not None:
|
||||
command = callbacks.canonicalName(privmsgs.getArgs(args[1:]))
|
||||
if hasattr(cb, 'isCommand') and cb.isCommand(command):
|
||||
method = getattr(cb, command)
|
||||
if hasattr(method, '__doc__') and method.__doc__ != None:
|
||||
irc.reply(msg, helpFor(method))
|
||||
else:
|
||||
irc.error(msg, 'That command has no help.')
|
||||
else:
|
||||
irc.error(msg, 'There is no such command %s %s.' %
|
||||
(args[0], command))
|
||||
else:
|
||||
irc.error(msg, 'There is no such plugin %s' % args[0])
|
||||
return
|
||||
command = callbacks.canonicalName(privmsgs.getArgs(args))
|
||||
# Users might expect "@help @list" to work.
|
||||
command = command.lstrip(conf.prefixChars)
|
||||
cb = callbacks.findCallbackForCommand(irc, command)
|
||||
if cb:
|
||||
cbs = callbacks.findCallbackForCommand(irc, command)
|
||||
if len(cbs) > 1:
|
||||
irc.error(msg, 'That command exists in the %s %s. Please specify '
|
||||
'exactly which plugin command you want help with.'%\
|
||||
(utils.commaAndify([cb.name() for cb in cbs]),
|
||||
utils.nItems(len(cbs), 'plugin')))
|
||||
return
|
||||
elif not cbs:
|
||||
irc.error(msg, 'There is no such command %s.' % command)
|
||||
else:
|
||||
cb = cbs[0]
|
||||
method = getattr(cb, command)
|
||||
if hasattr(method, '__doc__') and method.__doc__ is not None:
|
||||
doclines = method.__doc__.splitlines()
|
||||
simplehelp = doclines.pop(0)
|
||||
simplehelp = '(%s %s)' % (command, simplehelp)
|
||||
if doclines:
|
||||
doclines = filter(None, doclines)
|
||||
doclines = map(str.strip, doclines)
|
||||
help = ' '.join(doclines)
|
||||
s = '%s %s' % (ircutils.bold(simplehelp),help)
|
||||
irc.reply(msg, s)
|
||||
else:
|
||||
irc.reply(msg, 'That command has no help. '\
|
||||
'The syntax is this: %s %s' % \
|
||||
(command, simplehelp))
|
||||
irc.reply(msg, helpFor(method))
|
||||
else:
|
||||
irc.error(msg, '%s has no help or syntax description.'%command)
|
||||
else:
|
||||
irc.error(msg, 'There is no such command %s.' % command)
|
||||
|
||||
def hostmask(self, irc, msg, args):
|
||||
"""<nick>
|
||||
@ -257,9 +238,9 @@ class MiscCommands(callbacks.Privmsg):
|
||||
Returns the plugin <command> is in.
|
||||
"""
|
||||
command = callbacks.canonicalName(privmsgs.getArgs(args))
|
||||
cb = callbacks.findCallbackForCommand(irc, command)
|
||||
if cb is not None:
|
||||
irc.reply(msg, cb.name())
|
||||
cbs = callbacks.findCallbackForCommand(irc, command)
|
||||
if cbs:
|
||||
irc.reply(msg, utils.commaAndify([cb.name() for cb in cbs]))
|
||||
else:
|
||||
irc.error(msg, 'There is no such command %s' % command)
|
||||
|
||||
|
@ -297,14 +297,15 @@ def getCommands(tokens):
|
||||
return L
|
||||
|
||||
def findCallbackForCommand(irc, commandName):
|
||||
"""Given a command name and an Irc object, returns the callback that
|
||||
command is in. Returns None if there is no callback with that command."""
|
||||
"""Given a command name and an Irc object, returns a list of callbacks that
|
||||
commandName is in."""
|
||||
L = []
|
||||
for callback in irc.callbacks:
|
||||
if not isinstance(callback, PrivmsgRegexp):
|
||||
if hasattr(callback, 'isCommand'):
|
||||
if callback.isCommand(commandName):
|
||||
return callback
|
||||
return None
|
||||
L.append(callback)
|
||||
return L
|
||||
|
||||
class IrcObjectProxy:
|
||||
"A proxy object to allow proper nested of commands (even threaded ones)."
|
||||
@ -341,9 +342,22 @@ class IrcObjectProxy:
|
||||
self.finalEvaled = True
|
||||
originalName = self.args.pop(0)
|
||||
name = canonicalName(originalName)
|
||||
cb = findCallbackForCommand(self, name)
|
||||
try:
|
||||
if cb is not None:
|
||||
cbs = findCallbackForCommand(self, name)
|
||||
if len(cbs) == 0:
|
||||
self.args.insert(0, originalName)
|
||||
if not isinstance(self.irc, irclib.Irc):
|
||||
# If self.irc is an actual irclib.Irc, then this is the
|
||||
# first command given, and should be ignored as usual.
|
||||
self.reply(self.msg, '[%s]' % ' '.join(self.args))
|
||||
return
|
||||
elif len(cbs) > 1:
|
||||
s = 'The command %s is available in plugins %s. Please specify ' \
|
||||
'the plugin whose command you wish to call.' % \
|
||||
(originalName, utils.commaAndify([cb.name() for cb in cbs]))
|
||||
self.error(self.msg, s)
|
||||
else:
|
||||
try:
|
||||
cb = cbs[0]
|
||||
anticap = ircdb.makeAntiCapability(name)
|
||||
#debug.printf('Checking for %s' % anticap)
|
||||
if ircdb.checkCapability(self.msg.prefix, anticap):
|
||||
@ -371,26 +385,20 @@ class IrcObjectProxy:
|
||||
t.start()
|
||||
else:
|
||||
cb.callCommand(command, self, self.msg, self.args)
|
||||
else:
|
||||
self.args.insert(0, originalName)
|
||||
except (getopt.GetoptError, ArgumentError):
|
||||
if hasattr(command, '__doc__'):
|
||||
s = '%s %s' % (name, command.__doc__.splitlines()[0])
|
||||
else:
|
||||
s = 'Invalid arguments for %s.' % name
|
||||
self.reply(self.msg, s)
|
||||
except CannotNest, e:
|
||||
if not isinstance(self.irc, irclib.Irc):
|
||||
# If self.irc is an actual irclib.Irc, then this is the
|
||||
# first command given, and should be ignored as usual.
|
||||
self.reply(self.msg, '[%s]' % ' '.join(self.args))
|
||||
except (getopt.GetoptError, ArgumentError):
|
||||
if hasattr(command, '__doc__'):
|
||||
s = '%s %s' % (name, command.__doc__.splitlines()[0])
|
||||
else:
|
||||
s = 'Invalid arguments for %s.' % name
|
||||
self.reply(self.msg, s)
|
||||
except CannotNest, e:
|
||||
if not isinstance(self.irc, irclib.Irc):
|
||||
self.error(self.msg, 'Command %r cannot be nested.' % name)
|
||||
except (SyntaxError, Error), e:
|
||||
self.reply(self.msg, debug.exnToString(e))
|
||||
except Exception, e:
|
||||
debug.recoverableException()
|
||||
self.error(self.msg, debug.exnToString(e))
|
||||
self.error(self.msg, 'Command %r cannot be nested.' % name)
|
||||
except (SyntaxError, Error), e:
|
||||
self.reply(self.msg, debug.exnToString(e))
|
||||
except Exception, e:
|
||||
debug.recoverableException()
|
||||
self.error(self.msg, debug.exnToString(e))
|
||||
|
||||
def reply(self, msg, s, noLengthCheck=False, prefixName=True,
|
||||
action=False, private=False, notice=False):
|
||||
|
@ -70,7 +70,6 @@ class AliasTestCase(ChannelPluginTestCase, PluginDocumentation):
|
||||
plugins = ('Alias', 'Fun', 'Utilities', 'MiscCommands')
|
||||
def testAliasHelp(self):
|
||||
self.assertNotError('alias slashdot foo')
|
||||
self.assertNotRegexp('syntax slashdot', 'None')
|
||||
self.assertRegexp('help slashdot', "Alias for 'foo'")
|
||||
|
||||
def testDollars(self):
|
||||
|
@ -61,10 +61,6 @@ class MiscCommandsTestCase(ChannelPluginTestCase, PluginDocumentation):
|
||||
finally:
|
||||
conf.repylWhenNotCommand = False
|
||||
|
||||
def testSyntax(self):
|
||||
self.assertNotError('syntax list')
|
||||
self.assertNotError('syntax help')
|
||||
|
||||
def testHelp(self):
|
||||
self.assertNotError('help list')
|
||||
try:
|
||||
@ -73,7 +69,7 @@ class MiscCommandsTestCase(ChannelPluginTestCase, PluginDocumentation):
|
||||
self.assertNotError('help @list')
|
||||
finally:
|
||||
conf.prefixChars = original
|
||||
self.assertNotError('help syntax')
|
||||
self.assertNotError('help list')
|
||||
self.assertRegexp('help help', r'^\x02\(help')
|
||||
self.assertError('help morehelp')
|
||||
|
||||
|
@ -163,7 +163,7 @@ class FunctionsTestCase(unittest.TestCase):
|
||||
|
||||
|
||||
class PrivmsgTestCase(ChannelPluginTestCase):
|
||||
plugins = ('Utilities', 'OwnerCommands')
|
||||
plugins = ('Utilities', 'OwnerCommands', 'MiscCommands')
|
||||
conf.allowEval = True
|
||||
timeout = 2
|
||||
def testEmptySquareBrackets(self):
|
||||
@ -239,12 +239,15 @@ class PrivmsgTestCase(ChannelPluginTestCase):
|
||||
self.assertNotRegexp('firstcmd', '(foo.*baz|baz.*foo)')
|
||||
self.assertResponse('first firstcmd', 'foo')
|
||||
self.assertResponse('firstrepeat firstcmd', 'baz')
|
||||
|
||||
def testHelpDispatching(self):
|
||||
self.irc.addCallback(self.First())
|
||||
self.assertNotError('help firstcmd')
|
||||
self.assertNotError('help first firstcmd')
|
||||
self.irc.addCallback(self.FirstRepeat())
|
||||
self.assertError('help firstcmd')
|
||||
self.assertRegexp('help first firstcmd', 'First', 0) # no re.I flag.
|
||||
self.assertRegexp('help firstrepeat firstcmd', 'FirstRepeat', 0)
|
||||
self.assertResponse('syntax first firstcmd', 'firstcmd First')
|
||||
self.assertResponse('syntax firstrepeat firstcmd',
|
||||
'firstcmd FirstRepeat')
|
||||
|
||||
def testDefaultCommand(self):
|
||||
self.irc.addCallback(self.First())
|
||||
|
Loading…
Reference in New Issue
Block a user