mirror of
https://github.com/Mikaela/Limnoria.git
synced 2024-11-27 05:09:23 +01:00
Added support for source-nested plugins.
This commit is contained in:
parent
09eecf5a4e
commit
574e9509b7
@ -621,6 +621,7 @@ class IrcObjectProxy(RichReplyMethods):
|
|||||||
"""Returns a two-tuple of (command, plugins) that has the command
|
"""Returns a two-tuple of (command, plugins) that has the command
|
||||||
(a list of strings) and the plugins for which it was a command."""
|
(a list of strings) and the plugins for which it was a command."""
|
||||||
assert isinstance(args, list)
|
assert isinstance(args, list)
|
||||||
|
args = map(canonicalName, args)
|
||||||
cbs = []
|
cbs = []
|
||||||
maxL = []
|
maxL = []
|
||||||
for cb in self.irc.callbacks:
|
for cb in self.irc.callbacks:
|
||||||
@ -632,9 +633,10 @@ class IrcObjectProxy(RichReplyMethods):
|
|||||||
maxL = L
|
maxL = L
|
||||||
cbs.append((cb, L))
|
cbs.append((cb, L))
|
||||||
assert isinstance(L, list), \
|
assert isinstance(L, list), \
|
||||||
'getCommand now returns a list, not a bool.'
|
'getCommand now returns a list, not a method.'
|
||||||
assert utils.iter.startswith(L, args), \
|
assert utils.iter.startswith(L, args), \
|
||||||
'getCommand must return a prefix of the args given.'
|
'getCommand must return a prefix of the args given. ' \
|
||||||
|
'(args given: %r, returned: %r)' % (args, L)
|
||||||
log.debug('findCallbacksForCommands: %r', cbs)
|
log.debug('findCallbacksForCommands: %r', cbs)
|
||||||
cbs = [cb for (cb, L) in cbs if L == maxL]
|
cbs = [cb for (cb, L) in cbs if L == maxL]
|
||||||
if len(maxL) == 1:
|
if len(maxL) == 1:
|
||||||
@ -955,14 +957,27 @@ class DisabledCommands(object):
|
|||||||
if self.d[command] is not None:
|
if self.d[command] is not None:
|
||||||
self.d[command].remove(plugin)
|
self.d[command].remove(plugin)
|
||||||
|
|
||||||
|
class BasePlugin(object):
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
self.cbs = []
|
||||||
|
for attr in dir(self):
|
||||||
|
if attr != canonicalName(attr):
|
||||||
|
continue
|
||||||
|
obj = getattr(self, attr)
|
||||||
|
if isinstance(obj, type) and issubclass(obj, BasePlugin):
|
||||||
|
cb = obj(*args, **kwargs)
|
||||||
|
setattr(self, attr, cb)
|
||||||
|
self.cbs.append(cb)
|
||||||
|
cb.log = log.getPluginLogger('%s.%s' % (self.name(),cb.name()))
|
||||||
|
super(BasePlugin, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
class Commands(object):
|
class Commands(BasePlugin):
|
||||||
# For awhile, a comment stood here to say, "Eventually callCommand." But
|
# For awhile, a comment stood here to say, "Eventually callCommand." But
|
||||||
# that's wrong, because we can't do generic error handling in this
|
# that's wrong, because we can't do generic error handling in this
|
||||||
# callCommand -- plugins need to be able to override callCommand and do
|
# callCommand -- plugins need to be able to override callCommand and do
|
||||||
# error handling there (see the Http plugin for an example).
|
# error handling there (see the Http plugin for an example).
|
||||||
__firewalled__ = {'isCommand': None,}
|
__firewalled__ = {'isCommand': None,
|
||||||
# 'invalidCommand': None} # Gotta raise callbacks.Error.
|
'_callCommand': None}
|
||||||
commandArgs = ['self', 'irc', 'msg', 'args']
|
commandArgs = ['self', 'irc', 'msg', 'args']
|
||||||
# These must be class-scope, so all plugins use the same one.
|
# These must be class-scope, so all plugins use the same one.
|
||||||
_disabled = DisabledCommands()
|
_disabled = DisabledCommands()
|
||||||
@ -995,6 +1010,7 @@ class Commands(object):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
def isCommand(self, command):
|
def isCommand(self, command):
|
||||||
|
"""Convenience, backwards-compatibility, semi-deprecated."""
|
||||||
if isinstance(command, basestring):
|
if isinstance(command, basestring):
|
||||||
return self.isCommandMethod(command)
|
return self.isCommandMethod(command)
|
||||||
else:
|
else:
|
||||||
@ -1004,32 +1020,45 @@ class Commands(object):
|
|||||||
return self.getCommand(command) == command
|
return self.getCommand(command) == command
|
||||||
|
|
||||||
def getCommand(self, args):
|
def getCommand(self, args):
|
||||||
first = canonicalName(args[0])
|
first = args[0]
|
||||||
if len(args) >= 2 and first == self.canonicalName():
|
if len(args) >= 2 and first == self.canonicalName():
|
||||||
second = canonicalName(args[1])
|
command = self.getCommand(args[1:])
|
||||||
if second != self.canonicalName() and self.isCommandMethod(second):
|
if command:
|
||||||
return args[:2]
|
command.insert(0, first)
|
||||||
|
return command
|
||||||
|
for cb in self.cbs:
|
||||||
|
if first == cb.canonicalName():
|
||||||
|
command = cb.getCommand(args[1:])
|
||||||
|
if command:
|
||||||
|
command.insert(0, first)
|
||||||
|
return command
|
||||||
if self.isCommandMethod(first):
|
if self.isCommandMethod(first):
|
||||||
return args[:1]
|
return [first]
|
||||||
return []
|
return []
|
||||||
|
|
||||||
def getCommandMethod(self, command):
|
def getCommandMethod(self, command):
|
||||||
"""Gets the given command from this plugin."""
|
"""Gets the given command from this plugin."""
|
||||||
assert not isinstance(command, basestring)
|
assert not isinstance(command, basestring)
|
||||||
command = map(canonicalName, command)
|
assert command == map(canonicalName, command)
|
||||||
assert self.getCommand(command) == command
|
assert self.getCommand(command) == command
|
||||||
if len(command) == 2:
|
if len(command) > 1:
|
||||||
assert command[0] == self.canonicalName()
|
if command[0] == self.canonicalName():
|
||||||
return self.getCommandMethod([command[1]])
|
return self.getCommandMethod(command[1:])
|
||||||
|
for cb in self.cbs:
|
||||||
|
if command[0] == cb.canonicalName():
|
||||||
|
return cb.getCommandMethod(command)
|
||||||
else:
|
else:
|
||||||
return getattr(self, command[0])
|
return getattr(self, command[0])
|
||||||
|
|
||||||
def listCommands(self):
|
def listCommands(self):
|
||||||
commands = []
|
commands = []
|
||||||
name = canonicalName(self.name())
|
|
||||||
for s in dir(self):
|
for s in dir(self):
|
||||||
if self.isCommand(s):
|
if self.isCommand(s):
|
||||||
commands.append(s)
|
commands.append(s)
|
||||||
|
for cb in self.cbs:
|
||||||
|
name = cb.canonicalName()
|
||||||
|
for command in cb.listCommands():
|
||||||
|
commands.append(' '.join([name, command]))
|
||||||
commands.sort()
|
commands.sort()
|
||||||
return commands
|
return commands
|
||||||
|
|
||||||
@ -1072,12 +1101,11 @@ class Commands(object):
|
|||||||
def getCommandHelp(self, command):
|
def getCommandHelp(self, command):
|
||||||
method = self.getCommandMethod(command)
|
method = self.getCommandMethod(command)
|
||||||
if hasattr(method, '__doc__'):
|
if hasattr(method, '__doc__'):
|
||||||
return getHelp(method)
|
return getHelp(method, name=formatCommand(command))
|
||||||
else:
|
else:
|
||||||
return format('The %q command has no help.',formatCommand(command))
|
return format('The %q command has no help.',formatCommand(command))
|
||||||
|
|
||||||
|
class PluginMixin(BasePlugin, irclib.IrcCallback):
|
||||||
class PluginMixin(irclib.IrcCallback):
|
|
||||||
public = True
|
public = True
|
||||||
alwaysCall = ()
|
alwaysCall = ()
|
||||||
threaded = False
|
threaded = False
|
||||||
@ -1086,6 +1114,7 @@ class PluginMixin(irclib.IrcCallback):
|
|||||||
Proxy = IrcObjectProxy
|
Proxy = IrcObjectProxy
|
||||||
def __init__(self, irc):
|
def __init__(self, irc):
|
||||||
self.__parent = super(PluginMixin, self)
|
self.__parent = super(PluginMixin, self)
|
||||||
|
self.__parent.__init__(irc)
|
||||||
myName = self.name()
|
myName = self.name()
|
||||||
self.log = log.getPluginLogger(myName)
|
self.log = log.getPluginLogger(myName)
|
||||||
# We can't do this because of the specialness that Owner and Misc do.
|
# We can't do this because of the specialness that Owner and Misc do.
|
||||||
|
Loading…
Reference in New Issue
Block a user