mirror of
https://github.com/Mikaela/Limnoria.git
synced 2024-11-24 11:39:25 +01:00
New plugin prioritization method.
This commit is contained in:
parent
6243fe6baf
commit
c573ab5996
@ -65,12 +65,16 @@ conf.registerGlobalValue(conf.supybot.plugins.Misc, 'listPrivatePlugins',
|
|||||||
are loaded."""))
|
are loaded."""))
|
||||||
|
|
||||||
class Misc(callbacks.Privmsg):
|
class Misc(callbacks.Privmsg):
|
||||||
priority = sys.maxint
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(Misc, self).__init__()
|
super(Misc, self).__init__()
|
||||||
timeout = conf.supybot.abuse.flood.command.invalid
|
timeout = conf.supybot.abuse.flood.command.invalid
|
||||||
self.invalidCommands = ircutils.FloodQueue(timeout)
|
self.invalidCommands = ircutils.FloodQueue(timeout)
|
||||||
|
|
||||||
|
callAfter = utils.Everything()
|
||||||
|
callBefore = utils.Nothing()
|
||||||
|
def __cmp__(self, other):
|
||||||
|
return 1 # We should always be the last plugin.
|
||||||
|
|
||||||
def invalidCommand(self, irc, msg, tokens):
|
def invalidCommand(self, irc, msg, tokens):
|
||||||
self.log.debug('Misc.invalidCommand called (tokens %s)', tokens)
|
self.log.debug('Misc.invalidCommand called (tokens %s)', tokens)
|
||||||
# First, we check for invalidCommand floods. This is rightfully done
|
# First, we check for invalidCommand floods. This is rightfully done
|
||||||
|
20
src/Owner.py
20
src/Owner.py
@ -183,7 +183,6 @@ class LogProxy(object):
|
|||||||
class Owner(privmsgs.CapabilityCheckingPrivmsg):
|
class Owner(privmsgs.CapabilityCheckingPrivmsg):
|
||||||
# This plugin must be first; its priority must be lowest; otherwise odd
|
# This plugin must be first; its priority must be lowest; otherwise odd
|
||||||
# things will happen when adding callbacks.
|
# things will happen when adding callbacks.
|
||||||
priority = ~sys.maxint-1 # This must be first!
|
|
||||||
capability = 'owner'
|
capability = 'owner'
|
||||||
_srcPlugins = ircutils.IrcSet(('Admin', 'Channel', 'Config',
|
_srcPlugins = ircutils.IrcSet(('Admin', 'Channel', 'Config',
|
||||||
'Misc', 'Owner', 'User'))
|
'Misc', 'Owner', 'User'))
|
||||||
@ -227,6 +226,11 @@ class Owner(privmsgs.CapabilityCheckingPrivmsg):
|
|||||||
continue
|
continue
|
||||||
registerDefaultPlugin(name, s)
|
registerDefaultPlugin(name, s)
|
||||||
|
|
||||||
|
callAfter = utils.Nothing()
|
||||||
|
callBefore = utils.Everything()
|
||||||
|
def __cmp__(self, other):
|
||||||
|
return -1 # We should always be the first plugin.
|
||||||
|
|
||||||
def _getIrc(self, network):
|
def _getIrc(self, network):
|
||||||
network = network.lower()
|
network = network.lower()
|
||||||
for irc in world.ircs:
|
for irc in world.ircs:
|
||||||
@ -376,10 +380,12 @@ class Owner(privmsgs.CapabilityCheckingPrivmsg):
|
|||||||
def doPrivmsg(self, irc, msg):
|
def doPrivmsg(self, irc, msg):
|
||||||
callbacks.Privmsg.handled = False
|
callbacks.Privmsg.handled = False
|
||||||
callbacks.Privmsg.errored = False
|
callbacks.Privmsg.errored = False
|
||||||
if ircdb.checkIgnored(msg.prefix):
|
ignored = ircdb.checkIgnored(msg.prefix)
|
||||||
return
|
|
||||||
s = callbacks.addressed(irc.nick, msg)
|
s = callbacks.addressed(irc.nick, msg)
|
||||||
if s:
|
if s:
|
||||||
|
if ignored:
|
||||||
|
self.log.info('Ignoring command from %s.' % msg.prefix)
|
||||||
|
return
|
||||||
brackets = conf.supybot.reply.brackets.get(msg.args[0])()
|
brackets = conf.supybot.reply.brackets.get(msg.args[0])()
|
||||||
try:
|
try:
|
||||||
tokens = callbacks.tokenize(s, brackets=brackets)
|
tokens = callbacks.tokenize(s, brackets=brackets)
|
||||||
@ -595,17 +601,17 @@ class Owner(privmsgs.CapabilityCheckingPrivmsg):
|
|||||||
if name.endswith('.py'):
|
if name.endswith('.py'):
|
||||||
name = name[:-3]
|
name = name[:-3]
|
||||||
if irc.getCallback(name):
|
if irc.getCallback(name):
|
||||||
irc.error('That plugin is already loaded.')
|
irc.error('%s is already loaded.' % name.capitalize())
|
||||||
return
|
return
|
||||||
try:
|
try:
|
||||||
module = loadPluginModule(name, ignoreDeprecation)
|
module = loadPluginModule(name, ignoreDeprecation)
|
||||||
except Deprecated:
|
except Deprecated:
|
||||||
irc.error('That plugin is deprecated. '
|
irc.error('%s is deprecated. Use --deprecated '
|
||||||
'Use --deprecated to force it to load.')
|
'to force it to load.' % name.capitalize())
|
||||||
return
|
return
|
||||||
except ImportError, e:
|
except ImportError, e:
|
||||||
if name in str(e):
|
if name in str(e):
|
||||||
irc.error('No plugin %s exists.' % name)
|
irc.error('No plugin named %s exists.' % utils.dqrepr(name))
|
||||||
else:
|
else:
|
||||||
irc.error(str(e))
|
irc.error(str(e))
|
||||||
return
|
return
|
||||||
|
@ -570,6 +570,7 @@ class IrcObjectProxy(RichReplyMethods):
|
|||||||
def finalEval(self):
|
def finalEval(self):
|
||||||
assert not self.finalEvaled, 'finalEval called twice.'
|
assert not self.finalEvaled, 'finalEval called twice.'
|
||||||
self.finalEvaled = True
|
self.finalEvaled = True
|
||||||
|
# We can't canonicalName here because it might be a regexp method.
|
||||||
name = self.args[0]
|
name = self.args[0]
|
||||||
cbs = findCallbackForCommand(self, name)
|
cbs = findCallbackForCommand(self, name)
|
||||||
if len(cbs) == 0:
|
if len(cbs) == 0:
|
||||||
@ -595,6 +596,9 @@ class IrcObjectProxy(RichReplyMethods):
|
|||||||
# Ok, no regexp-based things matched.
|
# Ok, no regexp-based things matched.
|
||||||
self._callInvalidCommands()
|
self._callInvalidCommands()
|
||||||
else:
|
else:
|
||||||
|
# But we must canonicalName here, since we're comparing to a
|
||||||
|
# canonicalName.
|
||||||
|
name = canonicalName(name)
|
||||||
if len(cbs) > 1:
|
if len(cbs) > 1:
|
||||||
for cb in cbs:
|
for cb in cbs:
|
||||||
if canonicalName(cb.name()) == name:
|
if canonicalName(cb.name()) == name:
|
||||||
@ -862,6 +866,8 @@ class Privmsg(irclib.IrcCallback):
|
|||||||
alwaysCall = ()
|
alwaysCall = ()
|
||||||
threaded = False
|
threaded = False
|
||||||
noIgnore = False
|
noIgnore = False
|
||||||
|
callAfter = ()
|
||||||
|
callBefore = ()
|
||||||
Proxy = IrcObjectProxy
|
Proxy = IrcObjectProxy
|
||||||
commandArgs = ['self', 'irc', 'msg', 'args']
|
commandArgs = ['self', 'irc', 'msg', 'args']
|
||||||
# This must be class-scope, so all plugins use the same one.
|
# This must be class-scope, so all plugins use the same one.
|
||||||
@ -871,6 +877,10 @@ class Privmsg(irclib.IrcCallback):
|
|||||||
self.__parent = super(Privmsg, self)
|
self.__parent = super(Privmsg, self)
|
||||||
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.
|
||||||
|
# I guess plugin authors will have to get the capitalization right.
|
||||||
|
# self.callAfter = map(str.lower, self.callAfter)
|
||||||
|
# self.callBefore = map(str.lower, self.callBefore)
|
||||||
### Setup the dispatcher command.
|
### Setup the dispatcher command.
|
||||||
canonicalname = canonicalName(myName)
|
canonicalname = canonicalName(myName)
|
||||||
self._original = getattr(self, canonicalname, None)
|
self._original = getattr(self, canonicalname, None)
|
||||||
@ -919,6 +929,37 @@ class Privmsg(irclib.IrcCallback):
|
|||||||
dispatcher.isDispatcher = True
|
dispatcher.isDispatcher = True
|
||||||
setattr(self.__class__, canonicalname, dispatcher)
|
setattr(self.__class__, canonicalname, dispatcher)
|
||||||
|
|
||||||
|
# In addition to priority, plugins may specify callBefore and callAfter
|
||||||
|
# attributes which are lists of plugin names which the plugin should be
|
||||||
|
# called before and after, respectively. We may, at some future point,
|
||||||
|
# remove priority entirely.
|
||||||
|
def __cmp__(self, other, doAssert=True):
|
||||||
|
selfName = self.name()
|
||||||
|
otherName = other.name()
|
||||||
|
# We can't be certain of the order the callbacks list is in, so we
|
||||||
|
# can't be certain that our __cmp__ is the most specific one, so
|
||||||
|
# we basically run the other callback's as well.
|
||||||
|
if isinstance(other, Privmsg):
|
||||||
|
if otherName in self.callAfter or selfName in other.callBefore:
|
||||||
|
ret = 1
|
||||||
|
elif otherName in self.callBefore or selfName in other.callAfter:
|
||||||
|
ret = -1
|
||||||
|
else:
|
||||||
|
ret = self.__parent.__cmp__(other)
|
||||||
|
else:
|
||||||
|
ret = self.__parent.__cmp__(other)
|
||||||
|
if doAssert:
|
||||||
|
try:
|
||||||
|
otherRet = other.__cmp__(self, doAssert=False)
|
||||||
|
except TypeError, e:
|
||||||
|
if 'doAssert' in str(e): # unexpected keyword argument.
|
||||||
|
otherRet = cmp(other, self)
|
||||||
|
else:
|
||||||
|
otherRet = ret
|
||||||
|
assert ret+otherRet==0, 'callbacks\' __cmp__ disagree: %s, %s' % \
|
||||||
|
(selfName, otherName)
|
||||||
|
return ret
|
||||||
|
|
||||||
def __call__(self, irc, msg):
|
def __call__(self, irc, msg):
|
||||||
if msg.command == 'PRIVMSG':
|
if msg.command == 'PRIVMSG':
|
||||||
if self.noIgnore or not ircdb.checkIgnored(msg.prefix,msg.args[0]):
|
if self.noIgnore or not ircdb.checkIgnored(msg.prefix,msg.args[0]):
|
||||||
|
@ -76,14 +76,23 @@ class IrcCallback(IrcCommandDispatcher):
|
|||||||
# numbers mean *higher* priority (like nice values in *nix). Higher
|
# numbers mean *higher* priority (like nice values in *nix). Higher
|
||||||
# priority means the callback is called *earlier* on the inFilter chain,
|
# priority means the callback is called *earlier* on the inFilter chain,
|
||||||
# *earlier* on the __call__ chain, and *later* on the outFilter chain.
|
# *earlier* on the __call__ chain, and *later* on the outFilter chain.
|
||||||
|
|
||||||
priority = 99
|
priority = 99
|
||||||
__metaclass__ = log.MetaFirewall
|
__metaclass__ = log.MetaFirewall
|
||||||
__firewalled__ = {'die': None,
|
__firewalled__ = {'die': None,
|
||||||
'reset': None,
|
'reset': None,
|
||||||
'__call__': None,
|
'__call__': None,
|
||||||
|
'__cmp__': lambda self: 0,
|
||||||
'inFilter': lambda self, irc, msg: msg,
|
'inFilter': lambda self, irc, msg: msg,
|
||||||
'outFilter': lambda self, irc, msg: msg,
|
'outFilter': lambda self, irc, msg: msg,
|
||||||
'name': lambda self: self.__class__.__name__,}
|
'name': lambda self: self.__class__.__name__,}
|
||||||
|
|
||||||
|
def __cmp__(self, other):
|
||||||
|
ret = cmp(self.priority, other.priority)
|
||||||
|
if not ret:
|
||||||
|
ret = cmp(self.name(), other.name())
|
||||||
|
return ret
|
||||||
|
|
||||||
def name(self):
|
def name(self):
|
||||||
"""Returns the name of the callback."""
|
"""Returns the name of the callback."""
|
||||||
return self.__class__.__name__
|
return self.__class__.__name__
|
||||||
@ -586,7 +595,9 @@ class Irc(IrcCommandDispatcher):
|
|||||||
def addCallback(self, callback):
|
def addCallback(self, callback):
|
||||||
"""Adds a callback to the callbacks list."""
|
"""Adds a callback to the callbacks list."""
|
||||||
self.callbacks.append(callback)
|
self.callbacks.append(callback)
|
||||||
utils.sortBy(operator.attrgetter('priority'), self.callbacks)
|
self.callbacks.sort()
|
||||||
|
# We used to do this, then we implemented sorting in IrcCallback.
|
||||||
|
# utils.sortBy(operator.attrgetter('priority'), self.callbacks)
|
||||||
|
|
||||||
def getCallback(self, name):
|
def getCallback(self, name):
|
||||||
"""Gets a given callback by name."""
|
"""Gets a given callback by name."""
|
||||||
|
Loading…
Reference in New Issue
Block a user