mirror of https://github.com/Mikaela/Limnoria.git
Updated completely.
This commit is contained in:
parent
d5a324a0d2
commit
4b5909331a
|
@ -181,7 +181,7 @@ class Admin(privmsgs.CapabilityCheckingPrivmsg):
|
|||
irc.reply(utils.commaAndify(L))
|
||||
else:
|
||||
irc.reply('I\'m not currently in any channels.')
|
||||
channels = commands.wrap(channels, wrappers=['private'], noExtra=True)
|
||||
channels = commands.wrap(channels, ['private'], noExtra=True)
|
||||
|
||||
def do484(self, irc, msg):
|
||||
irc = self.pendingNickChanges.get(irc, None)
|
||||
|
@ -231,7 +231,7 @@ class Admin(privmsgs.CapabilityCheckingPrivmsg):
|
|||
self.pendingNickChanges[irc.getRealIrc()] = irc
|
||||
else:
|
||||
irc.reply(irc.nick)
|
||||
nick = commands.wrap(nick, optional=['nick'])
|
||||
nick = commands.wrap(nick, ['?nick'])
|
||||
|
||||
def part(self, irc, msg, args):
|
||||
"""<channel> [<channel> ...] [<reason>]
|
||||
|
@ -342,7 +342,7 @@ class Admin(privmsgs.CapabilityCheckingPrivmsg):
|
|||
expires += time.time()
|
||||
ircdb.ignores.add(hostmask, expires)
|
||||
irc.replySuccess()
|
||||
ignore = commands.wrap(ignore, ['hostmask'], [('int', 0)])
|
||||
ignore = commands.wrap(ignore, ['hostmask', ('?int', 0)])
|
||||
|
||||
def unignore(self, irc, msg, args, hostmask):
|
||||
"""<hostmask|nick>
|
||||
|
|
266
src/Channel.py
266
src/Channel.py
|
@ -62,50 +62,41 @@ conf.registerChannelValue(conf.supybot.plugins.Channel, 'alwaysRejoin',
|
|||
rejoin a channel whenever it's kicked from the channel."""))
|
||||
|
||||
class Channel(callbacks.Privmsg):
|
||||
def haveOps(self, irc, channel, what):
|
||||
try:
|
||||
if irc.nick in irc.state.channels[channel].ops:
|
||||
return True
|
||||
else:
|
||||
irc.error('How can I %s? I\'m not opped in %s.' %
|
||||
(what, channel))
|
||||
return False
|
||||
except KeyError:
|
||||
irc.error('I don\'t seem to be in %s.' % channel)
|
||||
|
||||
def doKick(self, irc, msg):
|
||||
channel = msg.args[0]
|
||||
if msg.args[1] == irc.nick:
|
||||
if self.registryValue('alwaysRejoin', channel):
|
||||
irc.sendMsg(ircmsgs.join(channel)) # Fix for keys.
|
||||
|
||||
def mode(self, irc, msg, args, channel, mode):
|
||||
def mode(self, irc, msg, args, channel):
|
||||
"""[<channel>] <mode> [<arg> ...]
|
||||
|
||||
Sets the mode in <channel> to <mode>, sending the arguments given.
|
||||
<channel> is only necessary if the message isn't sent in the channel
|
||||
itself.
|
||||
"""
|
||||
if self.haveOps(irc, channel, 'change the mode'):
|
||||
irc.queueMsg(ircmsgs.mode(channel, mode))
|
||||
mode = commands.wrap(mode, [('channel', 'op'), 'something'])
|
||||
irc.queueMsg(ircmsgs.mode(channel, args))
|
||||
mode = commands.wrap(mode,
|
||||
['channel',
|
||||
('checkChannelCapability', 'op'),
|
||||
('haveOp', 'change the mode')],
|
||||
requireExtra=True)
|
||||
|
||||
def limit(self, irc, msg, args, channel, limit):
|
||||
"""[<channel>] <limit>
|
||||
"""[<channel>] [<limit>]
|
||||
|
||||
Sets the channel limit to <limit>. If <limit> is 0, removes the
|
||||
channel limit. <channel> is only necessary if the message isn't sent
|
||||
in the channel itself.
|
||||
Sets the channel limit to <limit>. If <limit> is 0, or isn't given,
|
||||
removes the channel limit. <channel> is only necessary if the message
|
||||
isn't sent in the channel itself.
|
||||
"""
|
||||
if limit < 0:
|
||||
irc.error('%r is not a positive integer.' % limit, Raise=True)
|
||||
if limit:
|
||||
if self.haveOps(irc, channel, 'set the limit'):
|
||||
irc.queueMsg(ircmsgs.mode(channel, ['+l', limit]))
|
||||
irc.queueMsg(ircmsgs.mode(channel, ['+l', limit]))
|
||||
else:
|
||||
if self.haveOps(irc, channel, 'unset the limit'):
|
||||
irc.queueMsg(ircmsgs.mode(channel, ['-l']))
|
||||
limit = commands.wrap(mode, [('channel', 'op'), 'int'])
|
||||
irc.queueMsg(ircmsgs.mode(channel, ['-l']))
|
||||
limit = commands.wrap(mode, ['channel',
|
||||
('checkChannelCapability', 'op'),
|
||||
('haveOp', 'change the limit'),
|
||||
('?nonNegativeInt', 0)])
|
||||
|
||||
def moderate(self, irc, msg, args, channel):
|
||||
"""[<channel>]
|
||||
|
@ -114,9 +105,10 @@ class Channel(callbacks.Privmsg):
|
|||
send messages to the channel. <channel> is only necessary if the
|
||||
message isn't sent in the channel itself.
|
||||
"""
|
||||
if self.haveOps(irc, channel, 'moderate the channel'):
|
||||
irc.queueMsg(ircmsgs.mode(channel, ['+m']))
|
||||
moderate = commands.wrap(moderate, [('channel', 'op')])
|
||||
irc.queueMsg(ircmsgs.mode(channel, ['+m']))
|
||||
moderate = commands.wrap(moderate, ['channel',
|
||||
('checkChannelCapability', 'op'),
|
||||
('haveOp', 'moderate the channel')])
|
||||
|
||||
def unmoderate(self, irc, msg, args, channel):
|
||||
"""[<channel>]
|
||||
|
@ -125,9 +117,11 @@ class Channel(callbacks.Privmsg):
|
|||
send messages to the channel. <channel> is only necessary if the
|
||||
message isn't sent in the channel itself.
|
||||
"""
|
||||
if self.haveOps(irc, channel, 'unmoderate the channel'):
|
||||
irc.queueMsg(ircmsgs.mode(channel, ['-m']))
|
||||
unmoderate = commands.wrap(unmoderate, [('channel', 'op')])
|
||||
irc.queueMsg(ircmsgs.mode(channel, ['-m']))
|
||||
unmoderate = commands.wrap(unmoderate, ['channel',
|
||||
('checkChannelCapability', 'op'),
|
||||
('haveOp',
|
||||
'unmoderate the channel')])
|
||||
|
||||
def key(self, irc, msg, args, channel, key):
|
||||
"""[<channel>] [<key>]
|
||||
|
@ -137,12 +131,13 @@ class Channel(callbacks.Privmsg):
|
|||
if the message isn't sent in the channel itself.
|
||||
"""
|
||||
if key:
|
||||
if self.haveOps(irc, channel, 'set the keyword'):
|
||||
irc.queueMsg(ircmsgs.mode(channel, ['+k', key]))
|
||||
irc.queueMsg(ircmsgs.mode(channel, ['+k', key]))
|
||||
else:
|
||||
if self.haveOps(irc, channel, 'unset the keyword'):
|
||||
irc.queueMsg(ircmsgs.mode(channel, ['-k']))
|
||||
key = commands.wrap(key, [('channel', 'op')], ['something'])
|
||||
irc.queueMsg(ircmsgs.mode(channel, ['-k']))
|
||||
key = commands.wrap(key, ['channel',
|
||||
('checkChannelCapability', 'op'),
|
||||
('haveOp', 'change the keyword'),
|
||||
'?somethingWithoutSpaces'])
|
||||
|
||||
def op(self, irc, msg, args, channel):
|
||||
"""[<channel>] [<nick> ...]
|
||||
|
@ -154,9 +149,10 @@ class Channel(callbacks.Privmsg):
|
|||
"""
|
||||
if not args:
|
||||
args = [msg.nick]
|
||||
if self.haveOps(irc, channel, 'op you'):
|
||||
irc.queueMsg(ircmsgs.ops(channel, args))
|
||||
op = commands.wrap(op, [('channel', 'op')])
|
||||
irc.queueMsg(ircmsgs.ops(channel, args))
|
||||
op = commands.wrap(op, ['channel',
|
||||
('checkChannelCapability', 'op'),
|
||||
('haveOp', 'op someone')])
|
||||
|
||||
def halfop(self, irc, msg, args, channel):
|
||||
"""[<channel>]
|
||||
|
@ -168,9 +164,10 @@ class Channel(callbacks.Privmsg):
|
|||
"""
|
||||
if not args:
|
||||
args = [msg.nick]
|
||||
if self.haveOps(irc, channel, 'halfop you'):
|
||||
irc.queueMsg(ircmsgs.halfops(channel, args))
|
||||
halfop = commands.wrap(halfop, [('channel', 'halfop')])
|
||||
irc.queueMsg(ircmsgs.halfops(channel, args))
|
||||
halfop = commands.wrap(halfop, ['channel',
|
||||
('checkChannelCapability', 'halfop'),
|
||||
('haveOp', 'halfop someone')])
|
||||
|
||||
def voice(self, irc, msg, args, channel):
|
||||
"""[<channel>]
|
||||
|
@ -182,9 +179,10 @@ class Channel(callbacks.Privmsg):
|
|||
"""
|
||||
if not args:
|
||||
args = [msg.nick]
|
||||
if self.haveOps(irc, channel, 'voice you'):
|
||||
irc.queueMsg(ircmsgs.voices(channel, args))
|
||||
voice = commands.wrap(voice, [('channel', 'voice')])
|
||||
irc.queueMsg(ircmsgs.voices(channel, args))
|
||||
voice = commands.wrap(voice, ['channel',
|
||||
('checkChannelCapability', 'voice'),
|
||||
('haveOp', 'voice someone')])
|
||||
|
||||
def deop(self, irc, msg, args, channel):
|
||||
"""[<channel>] [<nick> ...]
|
||||
|
@ -199,9 +197,11 @@ class Channel(callbacks.Privmsg):
|
|||
irc.error('I cowardly refuse to deop myself. If you really want '
|
||||
'me deopped, tell me to op you and then deop me '
|
||||
'yourself.')
|
||||
elif self.haveOps(irc, channel, 'deop someone'):
|
||||
else:
|
||||
irc.queueMsg(ircmsgs.deops(channel, args))
|
||||
deop = commands.wrap(deop, [('channel', 'op')])
|
||||
deop = commands.wrap(deop, ['channel',
|
||||
('checkChannelCapability', 'op'),
|
||||
('haveOp', 'deop someone')])
|
||||
|
||||
def dehalfop(self, irc, msg, args, channel):
|
||||
"""[<channel>] [<nick> ...]
|
||||
|
@ -216,9 +216,11 @@ class Channel(callbacks.Privmsg):
|
|||
irc.error('I cowardly refuse to dehalfop myself. If you really '
|
||||
'want me dehalfopped, tell me to op you and then '
|
||||
'dehalfop me yourself.')
|
||||
elif self.haveOps(irc, channel, 'dehalfop someone'):
|
||||
else:
|
||||
irc.queueMsg(ircmsgs.dehalfops(channel, args))
|
||||
dehalfop = commands.wrap(dehalfop, [('channel', 'halfop')])
|
||||
dehalfop = commands.wrap(dehalfop, ['channel',
|
||||
('checkChannelCapability', 'halfop'),
|
||||
('haveOp', 'dehalfop someone')])
|
||||
|
||||
def devoice(self, irc, msg, args, channel):
|
||||
"""[<channel>] [<nick> ...]
|
||||
|
@ -233,9 +235,11 @@ class Channel(callbacks.Privmsg):
|
|||
irc.error('I cowardly refuse to devoice myself. If you really '
|
||||
'want me devoiced, tell me to op you and then devoice '
|
||||
'me yourself.')
|
||||
elif self.haveOps(irc, channel, 'devoice someone'):
|
||||
else:
|
||||
irc.queueMsg(ircmsgs.devoices(channel, args))
|
||||
devoice = commands.wrap(devoice, [('channel', 'voice')])
|
||||
devoice = commands.wrap(devoice, ['channel',
|
||||
('checkChannelCapability', 'voice'),
|
||||
('haveOp', 'devoice someone')])
|
||||
|
||||
def cycle(self, irc, msg, args, channel, key):
|
||||
"""[<channel>] [<key>]
|
||||
|
@ -249,7 +253,9 @@ class Channel(callbacks.Privmsg):
|
|||
key = None
|
||||
irc.queueMsg(ircmsgs.part(channel))
|
||||
irc.queueMsg(ircmsgs.join(channel, key))
|
||||
cycle = commands.wrap(cycle, [('channel', 'op')], ['something'])
|
||||
cycle = commands.wrap(cycle, ['channel',
|
||||
('checkChannelCapability', 'op'),
|
||||
'anything'])
|
||||
|
||||
def kick(self, irc, msg, args, channel, nick, reason):
|
||||
"""[<channel>] <nick> [<reason>]
|
||||
|
@ -259,21 +265,25 @@ class Channel(callbacks.Privmsg):
|
|||
<channel> is only necessary if the message isn't sent in the channel
|
||||
itself.
|
||||
"""
|
||||
if self.haveOps(irc, channel, 'kick someone'):
|
||||
if nick not in irc.state.channels[channel].users:
|
||||
irc.error('%s isn\'t in %s.' % (nick, channel))
|
||||
return
|
||||
if not reason:
|
||||
reason = msg.nick
|
||||
kicklen = irc.state.supported.get('kicklen', sys.maxint)
|
||||
if len(reason) > kicklen:
|
||||
irc.error('The reason you gave is longer than the allowed '
|
||||
'length for a KICK reason on this server.')
|
||||
return
|
||||
irc.queueMsg(ircmsgs.kick(channel, nick, reason))
|
||||
kick = commands.wrap(kick, [('channel', 'op'), 'something'], ['something'])
|
||||
if nick not in irc.state.channels[channel].users:
|
||||
irc.error('%s isn\'t in %s.' % (nick, channel))
|
||||
return
|
||||
if not reason:
|
||||
reason = msg.nick
|
||||
kicklen = irc.state.supported.get('kicklen', sys.maxint)
|
||||
if len(reason) > kicklen:
|
||||
irc.error('The reason you gave is longer than the allowed '
|
||||
'length for a KICK reason on this server.')
|
||||
return
|
||||
irc.queueMsg(ircmsgs.kick(channel, nick, reason))
|
||||
kick = commands.wrap(kick, ['channel',
|
||||
('checkChannelCapability', 'op'),
|
||||
('haveOp', 'kick someone'),
|
||||
'nick',
|
||||
'?anything'])
|
||||
|
||||
def kban(self, irc, msg, args, channel, bannedNick, length, reason, *optlist):
|
||||
def kban(self, irc, msg, args,
|
||||
optlist, channel, bannedNick, length, reason):
|
||||
"""[<channel>] [--{exact,nick,user,host}] <nick> [<seconds>] [<reason>]
|
||||
|
||||
If you have the #channel,op capability, this will kickban <nick> for
|
||||
|
@ -287,7 +297,7 @@ class Channel(callbacks.Privmsg):
|
|||
itself.
|
||||
"""
|
||||
# Check that they're not trying to make us kickban ourself.
|
||||
self.log.critical('In kban')
|
||||
self.log.debug('In kban')
|
||||
if not ircutils.isNick(bannedNick):
|
||||
self.log.warning('%r tried to kban a non nick: %r',
|
||||
msg.prefix, bannedNick)
|
||||
|
@ -358,29 +368,29 @@ class Channel(callbacks.Privmsg):
|
|||
irc.queueMsg(ircmsgs.unban(channel, banmask))
|
||||
schedule.addEvent(f, time.time() + length)
|
||||
if bannedNick == msg.nick:
|
||||
if self.haveOps(irc, channel, 'kick or ban someone'):
|
||||
doBan()
|
||||
doBan()
|
||||
elif ircdb.checkCapability(msg.prefix, capability):
|
||||
if ircdb.checkCapability(bannedHostmask, capability):
|
||||
self.log.warning('%r tried to ban %r, but both have %s',
|
||||
self.log.warning('%s tried to ban %r, but both have %s',
|
||||
msg.prefix, bannedHostmask, capability)
|
||||
irc.error('%s has %s too, you can\'t ban him/her/it.' %
|
||||
(bannedNick, capability))
|
||||
elif self.haveOps(irc, channel, 'kick or ban someone'):
|
||||
else:
|
||||
doBan()
|
||||
else:
|
||||
self.log.warning('%r attempted kban without %s',
|
||||
msg.prefix, capability)
|
||||
irc.errorNoCapability(capability)
|
||||
exact,nick,user,host
|
||||
kban = \
|
||||
commands.wrap(kban, ['channel', 'something'],
|
||||
[('expiry', 0), 'something'],
|
||||
getopts={'exact': None,
|
||||
'nick': None,
|
||||
'user': None,
|
||||
'host': None})
|
||||
|
||||
kban = commands.wrap(kban, ['channel',
|
||||
('checkChannelCapability', 'op'),
|
||||
('haveOp', 'kick or ban someone'),
|
||||
'nick', ('expiry?', 0), '?anything'],
|
||||
getopts={'exact': None,
|
||||
'nick': None,
|
||||
'user': None,
|
||||
'host': None})
|
||||
|
||||
def unban(self, irc, msg, args, channel, hostmask):
|
||||
"""[<channel>] <hostmask>
|
||||
|
||||
|
@ -389,9 +399,11 @@ class Channel(callbacks.Privmsg):
|
|||
the channel. <channel> is only necessary if the message isn't sent
|
||||
in the channel itself.
|
||||
"""
|
||||
if self.haveOps(irc, channel, 'unban someone'):
|
||||
irc.queueMsg(ircmsgs.unban(channel, hostmask))
|
||||
unban = commands.wrap(unban, [('channel', 'op'), 'hostmask'])
|
||||
irc.queueMsg(ircmsgs.unban(channel, hostmask))
|
||||
unban = commands.wrap(unban, ['channel',
|
||||
('checkChannelCapability', 'op'),
|
||||
('haveOp', 'unban someone'),
|
||||
'hostmask'])
|
||||
|
||||
def invite(self, irc, msg, args, channel, nick):
|
||||
"""[<channel>] <nick>
|
||||
|
@ -400,9 +412,11 @@ class Channel(callbacks.Privmsg):
|
|||
to join <channel>. <channel> is only necessary if the message isn't
|
||||
sent in the channel itself.
|
||||
"""
|
||||
if self.haveOps(irc, channel, 'invite someone'):
|
||||
irc.queueMsg(ircmsgs.invite(nick, channel))
|
||||
invite = commands.wrap(invite, [('channel', 'op'), 'something'])
|
||||
irc.queueMsg(ircmsgs.invite(nick, channel))
|
||||
invite = commands.wrap(invite, ['channel',
|
||||
('checkChannelCapability', 'op'),
|
||||
('haveOp', 'invite someone'),
|
||||
'nick'])
|
||||
|
||||
def lobotomize(self, irc, msg, args, channel):
|
||||
"""[<channel>]
|
||||
|
@ -416,7 +430,8 @@ class Channel(callbacks.Privmsg):
|
|||
c.lobotomized = True
|
||||
ircdb.channels.setChannel(channel, c)
|
||||
irc.replySuccess()
|
||||
lobotomize = commands.wrap(lobotomize, [('channel', 'op')])
|
||||
lobotomize = commands.wrap(lobotomize, ['channel',
|
||||
('checkChannelCapability', 'op')])
|
||||
|
||||
def unlobotomize(self, irc, msg, args, channel):
|
||||
"""[<channel>]
|
||||
|
@ -430,7 +445,9 @@ class Channel(callbacks.Privmsg):
|
|||
c.lobotomized = False
|
||||
ircdb.channels.setChannel(channel, c)
|
||||
irc.replySuccess()
|
||||
unlobotomize = commands.wrap(unlobotomize, [('channel', 'op')])
|
||||
unlobotomize = commands.wrap(unlobotomize,
|
||||
['channel',
|
||||
('checkChannelCapability', 'op')])
|
||||
|
||||
def permban(self, irc, msg, args, channel, banmask, expires):
|
||||
"""[<channel>] <nick|hostmask> [<expires>]
|
||||
|
@ -448,8 +465,10 @@ class Channel(callbacks.Privmsg):
|
|||
c.addBan(banmask, expires)
|
||||
ircdb.channels.setChannel(channel, c)
|
||||
irc.replySuccess()
|
||||
permban = \
|
||||
commands.wrap(permban, [('channel', 'op'), 'banmask', ('expiry', 0)])
|
||||
permban = commands.wrap(permban, ['channel',
|
||||
('checkChannelCapability', 'op'),
|
||||
'hostmask',
|
||||
('?expiry', 0)])
|
||||
|
||||
def unpermban(self, irc, msg, args, channel, banmask):
|
||||
"""[<channel>] <hostmask>
|
||||
|
@ -458,13 +477,13 @@ class Channel(callbacks.Privmsg):
|
|||
ban on <hostmask>. <channel> is only necessary if the message isn't
|
||||
sent in the channel itself.
|
||||
"""
|
||||
banmask = privmsgs.getArgs(args)
|
||||
c = ircdb.channels.getChannel(channel)
|
||||
c.removeBan(banmask)
|
||||
ircdb.channels.setChannel(channel, c)
|
||||
#irc.queueMsg(ircmsgs.unban(channel, banmask))
|
||||
irc.replySuccess()
|
||||
unpermban = commands.wrap(unpermban, [('channel', 'op'), 'banmask'])
|
||||
unpermban = commands.wrap(unpermban, ['channel',
|
||||
('checkChannelCapability', 'op'),
|
||||
'hostmask'])
|
||||
|
||||
def permbans(self, irc, msg, args, channel):
|
||||
"""[<channel>]
|
||||
|
@ -478,7 +497,8 @@ class Channel(callbacks.Privmsg):
|
|||
irc.reply(utils.commaAndify(map(utils.dqrepr, c.bans)))
|
||||
else:
|
||||
irc.reply('There are currently no permanent bans on %s' % channel)
|
||||
permbans = commands.wrap(permbans, [('channel', 'op')])
|
||||
permbans = commands.wrap(permbans, ['channel',
|
||||
('checkChannelCapability', 'op')])
|
||||
|
||||
def ignore(self, irc, msg, args, channel, banmask, expires):
|
||||
"""[<channel>] <nick|hostmask> [<expires>]
|
||||
|
@ -494,8 +514,10 @@ class Channel(callbacks.Privmsg):
|
|||
c.addIgnore(banmask, expires)
|
||||
ircdb.channels.setChannel(channel, c)
|
||||
irc.replySuccess()
|
||||
ignore = \
|
||||
commands.wrap(ignore,[('channel', 'op'), 'banmask', ('expiry', 0)])
|
||||
ignore = commands.wrap(ignore, ['channel',
|
||||
('checkChannelCapability', 'op'),
|
||||
'hostmask',
|
||||
('?expiry', 0)])
|
||||
|
||||
def unignore(self, irc, msg, args, channel, banmask):
|
||||
"""[<channel>] <hostmask>
|
||||
|
@ -508,7 +530,9 @@ class Channel(callbacks.Privmsg):
|
|||
c.removeIgnore(banmask)
|
||||
ircdb.channels.setChannel(channel, c)
|
||||
irc.replySuccess()
|
||||
unignore = commands.wrap(unignore, [('channel', 'op'), 'something'])
|
||||
unignore = commands.wrap(unignore, ['channel',
|
||||
('checkChannelCapability', 'op'),
|
||||
'hostmask'])
|
||||
|
||||
def ignores(self, irc, msg, args, channel):
|
||||
"""[<channel>]
|
||||
|
@ -525,7 +549,8 @@ class Channel(callbacks.Privmsg):
|
|||
else:
|
||||
L = sorted(c.ignores)
|
||||
irc.reply(utils.commaAndify(imap(repr, L)))
|
||||
ignores = commands.wrap(ignores, [('channel', 'op')])
|
||||
ignores = commands.wrap(ignores, ['channel',
|
||||
('checkChannelCapability', 'op')])
|
||||
|
||||
def addcapability(self, irc, msg, args, channel, hostmask, capabilities):
|
||||
"""[<channel>] <name|hostmask> <capability> [<capability> ...]
|
||||
|
@ -545,9 +570,11 @@ class Channel(callbacks.Privmsg):
|
|||
user.addCapability(c)
|
||||
ircdb.users.setUser(id, user)
|
||||
irc.replySuccess()
|
||||
addcapability = \
|
||||
commands.wrap(addcapability,
|
||||
[('channel', 'op'), 'hostmask', 'something'])
|
||||
addcapability = commands.wrap(addcapability,
|
||||
['channel',
|
||||
('checkChannelCapability', 'op'),
|
||||
'hostmask',
|
||||
'somethingWithoutSpaces'])
|
||||
|
||||
def removecapability(self, irc, msg, args, channel, hostmask, capabilities):
|
||||
"""[<channel>] <name|hostmask> <capability> [<capability> ...]
|
||||
|
@ -576,10 +603,14 @@ class Channel(callbacks.Privmsg):
|
|||
(utils.commaAndify(fail),
|
||||
utils.pluralize('capability', len(fail))), Raise=True)
|
||||
irc.replySuccess()
|
||||
removecapability = \
|
||||
commands.wrap(removecapability,
|
||||
[('channel', 'op'), 'hostmask', 'something'])
|
||||
removecapability = commands.wrap(removecapability,
|
||||
['channel',
|
||||
('checkChannelCapability', 'op'),
|
||||
'hostmask',
|
||||
'somethingWithoutSpaces'])
|
||||
|
||||
# XXX This needs to be fix0red to be like Owner.defaultcapability. Or
|
||||
# something else. This is a horrible interface.
|
||||
def setdefaultcapability(self, irc, msg, args, channel, v):
|
||||
"""[<channel>] {True|False}
|
||||
|
||||
|
@ -595,8 +626,10 @@ class Channel(callbacks.Privmsg):
|
|||
c.setDefaultCapability(False)
|
||||
ircdb.channels.setChannel(channel, c)
|
||||
irc.replySuccess()
|
||||
setdefaultcapability = \
|
||||
commands.wrap(setdefaultcapability, [('channel', 'op'), 'boolean'])
|
||||
setdefaultcapability = commands.wrap(setdefaultcapability,
|
||||
['channel',
|
||||
('checkChannelCapability', 'op'),
|
||||
'boolean'])
|
||||
|
||||
def setcapability(self, irc, msg, args, channel, capabilities):
|
||||
"""[<channel>] <capability> [<capability> ...]
|
||||
|
@ -610,8 +643,10 @@ class Channel(callbacks.Privmsg):
|
|||
chan.addCapability(c)
|
||||
ircdb.channels.setChannel(channel, chan)
|
||||
irc.replySuccess()
|
||||
setcapability = \
|
||||
commands.wrap(setcapability, [('channel', 'op'), 'something'])
|
||||
setcapability = commands.wrap(setcapability,
|
||||
['channel',
|
||||
('checkChannelCapability', 'op'),
|
||||
'something'])
|
||||
|
||||
def unsetcapability(self, irc, msg, args, channel, capabilities):
|
||||
"""[<channel>] <capability> [<capability> ...]
|
||||
|
@ -634,8 +669,10 @@ class Channel(callbacks.Privmsg):
|
|||
(utils.commaAndify(fail),
|
||||
utils.pluralize('capability', len(fail))), Raise=True)
|
||||
irc.replySuccess()
|
||||
unsetcapability = \
|
||||
commands.wrap(unsetcapability, [('channel', 'op'), 'something'])
|
||||
unsetcapability = commands.wrap(unsetcapability,
|
||||
['channel',
|
||||
('checkChannelCapability', 'op'),
|
||||
'somethingWithoutSpaces'])
|
||||
|
||||
def capabilities(self, irc, msg, args, channel):
|
||||
"""[<channel>]
|
||||
|
@ -645,7 +682,7 @@ class Channel(callbacks.Privmsg):
|
|||
"""
|
||||
c = ircdb.channels.getChannel(channel)
|
||||
L = sorted(c.capabilities)
|
||||
irc.reply('[%s]' % '; '.join(L))
|
||||
irc.reply(' '.join(L))
|
||||
capabilities = commands.wrap(capabilities, ['channel'])
|
||||
|
||||
def lobotomies(self, irc, msg, args):
|
||||
|
@ -687,15 +724,16 @@ class Channel(callbacks.Privmsg):
|
|||
if ircdb.checkCapability(hostmask, capability):
|
||||
irc.reply(s, to=nick, private=True)
|
||||
|
||||
def alert(self, irc, msg, args, channel):
|
||||
def alert(self, irc, msg, args, channel, text):
|
||||
"""[<channel>] <text>
|
||||
|
||||
Sends <text> to all the users in <channel> who have the <channel>,op
|
||||
capability.
|
||||
"""
|
||||
text = privmsgs.getArgs(args)
|
||||
self.alertOps(irc, channel, text, frm=msg.nick)
|
||||
alert = privmsgs.checkChannelCapability(alert, 'op')
|
||||
alert = commands.wrap(alert, ['channel',
|
||||
('checkChannelCapability', 'op'),
|
||||
'something'])
|
||||
|
||||
|
||||
Class = Channel
|
||||
|
|
435
src/commands.py
435
src/commands.py
|
@ -43,6 +43,7 @@ import time
|
|||
import types
|
||||
import threading
|
||||
|
||||
import supybot.log as log
|
||||
import supybot.conf as conf
|
||||
import supybot.utils as utils
|
||||
import supybot.world as world
|
||||
|
@ -69,31 +70,6 @@ def thread(f):
|
|||
f(self, irc, msg, args, *L, **kwargs)
|
||||
return utils.changeFunctionName(newf, f.func_name, f.__doc__)
|
||||
|
||||
def private(f):
|
||||
"""Makes sure a command is given in private."""
|
||||
def newf(self, irc, msg, args, *L, **kwargs):
|
||||
if ircutils.isChannel(msg.args[0]):
|
||||
irc.errorRequiresPrivacy()
|
||||
else:
|
||||
f(self, irc, msg, args, *L, **kwargs)
|
||||
return utils.changeFunctionName(newf, f.func_name, f.__doc__)
|
||||
|
||||
def checkCapability(f, capability):
|
||||
"""Makes sure a user has a certain capability before a command will run.
|
||||
capability can be either a string or a callable object which will be called
|
||||
in order to produce a string for ircdb.checkCapability."""
|
||||
def newf(self, irc, msg, args):
|
||||
cap = capability
|
||||
if callable(cap):
|
||||
cap = cap()
|
||||
if ircdb.checkCapability(msg.prefix, cap):
|
||||
f(self, irc, msg, args)
|
||||
else:
|
||||
self.log.info('%s attempted %s without %s.',
|
||||
msg.prefix, f.func_name, cap)
|
||||
irc.errorNoCapability(cap)
|
||||
return utils.changeFunctionName(newf, f.func_name, f.__doc__)
|
||||
|
||||
class UrlSnarfThread(threading.Thread):
|
||||
def __init__(self, *args, **kwargs):
|
||||
assert 'url' in kwargs
|
||||
|
@ -158,105 +134,141 @@ def urlSnarfer(f):
|
|||
newf = utils.changeFunctionName(newf, f.func_name, f.__doc__)
|
||||
return newf
|
||||
|
||||
wrappers = ircutils.IrcDict({
|
||||
decorators = ircutils.IrcDict({
|
||||
'thread': thread,
|
||||
'private': private,
|
||||
'urlSnarfer': urlSnarfer,
|
||||
'checkCapability': checkCapability,
|
||||
})
|
||||
|
||||
|
||||
###
|
||||
# Arg wrappers, wrappers that add arguments to the command.
|
||||
# Arg wrappers, wrappers that add arguments to the command. They accept the
|
||||
# irc, msg, and args, of course, as well as a State object which holds the args
|
||||
# (and kwargs, though none currently take advantage of that) to be given to the
|
||||
# command being decorated, as well as the name of the command, the plugin, the
|
||||
# log, etc.
|
||||
###
|
||||
def getInt(irc, msg, args, default=None, type='integer'):
|
||||
s = args.pop(0)
|
||||
|
||||
# This is just so we can centralize this, since it may change.
|
||||
def _int(s):
|
||||
return int(float(s))
|
||||
|
||||
def getInt(irc, msg, args, state, default=None, type='integer', p=None):
|
||||
try:
|
||||
return int(s)
|
||||
i = _int(args[0])
|
||||
if p is not None:
|
||||
if not p(i):
|
||||
raise ValueError
|
||||
state.args.append(_int(args[0]))
|
||||
del args[0]
|
||||
except ValueError:
|
||||
if default is not None:
|
||||
return default
|
||||
state.args.append(default)
|
||||
else:
|
||||
irc.errorInvalid(type, s, Raise=True)
|
||||
irc.errorInvalid(type, args[0])
|
||||
|
||||
def getId(irc, msg, args):
|
||||
getInt(irc, msg, args, type='id')
|
||||
def getPositiveInt(irc, msg, args, state, *L):
|
||||
getInt(irc, msg, args, state,
|
||||
p=lambda i: i<=0, type='positive integer', *L)
|
||||
|
||||
def getExpiry(irc, msg, args, default=None):
|
||||
s = args.pop(0)
|
||||
def getNonNegativeInt(irc, msg, args, state, *L):
|
||||
getInt(irc, msg, args, state,
|
||||
p=lambda i: i<0, type='non-negative integer', *L)
|
||||
|
||||
def getId(irc, msg, args, state):
|
||||
getInt(irc, msg, args, state, type='id')
|
||||
|
||||
def getExpiry(irc, msg, args, state, default=None):
|
||||
now = int(time.time())
|
||||
try:
|
||||
expires = int(float(s))
|
||||
expires += int(time.time())
|
||||
expires = _int(args[0])
|
||||
if expires:
|
||||
expires += now
|
||||
state.args.append(expires)
|
||||
del args[0]
|
||||
except ValueError:
|
||||
if default is not None:
|
||||
return default
|
||||
if default:
|
||||
default += now
|
||||
state.args.append(default)
|
||||
else:
|
||||
irc.errorInvalid('number of seconds', s, Raise=True)
|
||||
irc.errorInvalid('number of seconds', args[0])
|
||||
# XXX This should be handled elsewhere; perhaps all optional args should
|
||||
# consider their first extra arg to be a default.
|
||||
except IndexError:
|
||||
if default is not None:
|
||||
if default:
|
||||
default += now
|
||||
state.args.append(default)
|
||||
else:
|
||||
raise
|
||||
|
||||
def getBoolean(irc, msg, args, default=None):
|
||||
s = args.pop(0).strip().lower()
|
||||
if s in ('true', 'on', 'enable', 'enabled'):
|
||||
return True
|
||||
elif s in ('false', 'off', 'disable', 'disabled'):
|
||||
return False
|
||||
elif default is not None:
|
||||
return default
|
||||
else:
|
||||
irc.error("Value must be either True or False (or On or Off).",
|
||||
Raise=True)
|
||||
def getBoolean(irc, msg, args, state, default=None):
|
||||
try:
|
||||
state.args.append(utils.toBool(args[0]))
|
||||
del args[0]
|
||||
except ValueError:
|
||||
if default is not None:
|
||||
state.args.append(default)
|
||||
else:
|
||||
irc.errorInvalid('boolean', args[0])
|
||||
|
||||
def getChannelDb(irc, msg, args, **kwargs):
|
||||
def getChannelDb(irc, msg, args, state, **kwargs):
|
||||
if not conf.supybot.databases.plugins.channelSpecific():
|
||||
return None
|
||||
state.args.append(None)
|
||||
state.channel = None
|
||||
else:
|
||||
return channel(irc, msg, args, **kwargs)
|
||||
getChannel(irc, msg, args, state, **kwargs)
|
||||
|
||||
def validChannel(irc, msg, args):
|
||||
s = args.pop(0)
|
||||
if ircutils.isChannel(s):
|
||||
return s
|
||||
def getHaveOp(irc, msg, args, state, action='do that'):
|
||||
if state.channel not in irc.state.channels:
|
||||
irc.error('I\'m not even in %s.' % state.channel, Raise=True)
|
||||
if irc.nick not in irc.state.channels[state.channel].ops:
|
||||
irc.error('I need to be opped to %s.' % action, Raise=True)
|
||||
|
||||
def validChannel(irc, msg, args, state):
|
||||
if ircutils.isChannel(args[0]):
|
||||
# XXX Check maxlength in irc.state.supported.
|
||||
state.args.append(args.pop(0))
|
||||
else:
|
||||
irc.errorInvalid('channel', s, Raise=True)
|
||||
irc.errorInvalid('channel', args[0])
|
||||
|
||||
def getHostmask(irc, msg, args):
|
||||
def getHostmask(irc, msg, args, state):
|
||||
if ircutils.isUserHostmask(args[0]):
|
||||
return args.pop(0)
|
||||
state.args.append(args.pop(0))
|
||||
else:
|
||||
try:
|
||||
s = args.pop(0)
|
||||
return irc.state.nickToHostmask(s)
|
||||
hostmask = irc.state.nickToHostmask(args[0])
|
||||
state.args.append(hostmask)
|
||||
del args[0]
|
||||
except KeyError:
|
||||
irc.errorInvalid('nick or hostmask', s, Raise=True)
|
||||
irc.errorInvalid('nick or hostmask', args[0])
|
||||
|
||||
def getBanmask(irc, msg, args):
|
||||
if ircutils.isUserHostmask(args[0]):
|
||||
return args.pop(0)
|
||||
else:
|
||||
try:
|
||||
s = args.pop(0)
|
||||
return ircutils.banmask(irc.state.nickToHostmask(s))
|
||||
except KeyError:
|
||||
irc.errorInvalid('nick or hostmask', s, Raise=True)
|
||||
def getBanmask(irc, msg, args, state):
|
||||
getHostmask(irc, msg, args, state)
|
||||
# XXX Channel-specific stuff.
|
||||
state.args[-1] = ircutils.banmask(state.args[-1])
|
||||
|
||||
def getUser(irc, msg, args):
|
||||
def getUser(irc, msg, args, state):
|
||||
try:
|
||||
return ircdb.users.getUser(msg.prefix)
|
||||
state.args.append(ircdb.users.getUser(msg.prefix))
|
||||
except KeyError:
|
||||
irc.errorNotRegistered(Raise=True)
|
||||
|
||||
def getOtherUser(irc, msg, args):
|
||||
s = args.pop(0)
|
||||
def getOtherUser(irc, msg, args, state):
|
||||
try:
|
||||
return ircdb.users.getUser(s)
|
||||
state.args.append(ircdb.users.getUser(args[0]))
|
||||
del args[0]
|
||||
except KeyError:
|
||||
try:
|
||||
hostmask = getHostmask(irc, msg, [s])
|
||||
return ircdb.users.getUser(hostmask)
|
||||
getHostmask(irc, msg, args, state)
|
||||
hostmask = state.args.pop()
|
||||
state.args.append(ircdb.users.getUser(hostmask))
|
||||
except (KeyError, IndexError, callbacks.Error):
|
||||
irc.errorNoUser(Raise=True)
|
||||
|
||||
def _getRe(f):
|
||||
def get(irc, msg, args):
|
||||
def get(irc, msg, args, state):
|
||||
original = args[:]
|
||||
s = args.pop(0)
|
||||
def isRe(s):
|
||||
try:
|
||||
|
@ -264,170 +276,233 @@ def _getRe(f):
|
|||
return True
|
||||
except ValueError:
|
||||
return False
|
||||
while not isRe(s):
|
||||
s += ' ' + args.pop(0)
|
||||
return f(s)
|
||||
try:
|
||||
while not isRe(s):
|
||||
s += ' ' + args.pop(0)
|
||||
state.args.append(f(s))
|
||||
except IndexError:
|
||||
args[:] = original
|
||||
raise
|
||||
return get
|
||||
|
||||
getMatcher = _getRe(utils.perlReToPythonRe)
|
||||
getReplacer = _getRe(utils.perlReToReplacer)
|
||||
|
||||
def getNick(irc, msg, args):
|
||||
s = args.pop(0)
|
||||
if ircutils.isNick(s):
|
||||
def getNick(irc, msg, args, state):
|
||||
if ircutils.isNick(args[0]):
|
||||
if 'nicklen' in irc.state.supported:
|
||||
if len(s) > irc.state.supported['nicklen']:
|
||||
if len(args[0]) > irc.state.supported['nicklen']:
|
||||
irc.errorInvalid('nick', s,
|
||||
'That nick is too long for this server.',
|
||||
Raise=True)
|
||||
return s
|
||||
'That nick is too long for this server.')
|
||||
state.args.append(args.pop(0))
|
||||
else:
|
||||
irc.errorInvalid('nick', s, Raise=True)
|
||||
irc.errorInvalid('nick', s)
|
||||
|
||||
def getChannel(irc, msg, args, cap=None):
|
||||
if ircutils.isChannel(args[0]):
|
||||
def getChannel(irc, msg, args, state):
|
||||
if args and ircutils.isChannel(args[0]):
|
||||
channel = args.pop(0)
|
||||
elif ircutils.isChannel(msg.args[0]):
|
||||
channel = msg.args[0]
|
||||
else:
|
||||
state.log.debug('Raising ArgumentError because there is no channel.')
|
||||
raise callbacks.ArgumentError
|
||||
if cap is not None:
|
||||
if callable(cap):
|
||||
cap = cap()
|
||||
cap = ircdb.makeChannelCapability(channel, cap)
|
||||
if not ircdb.checkCapability(msg.prefix, cap):
|
||||
irc.errorNoCapability(cap, Raise=True)
|
||||
return channel
|
||||
state.channel = channel
|
||||
state.args.append(channel)
|
||||
|
||||
def getLowered(irc, msg, args):
|
||||
return ircutils.toLower(args.pop(0))
|
||||
def checkChannelCapability(irc, msg, args, state, cap):
|
||||
assert state.channel, \
|
||||
'You must use a channel arg before you use checkChannelCapability.'
|
||||
cap = ircdb.canonicalCapability(cap)
|
||||
cap = ircdb.makeChannelCapability(state.channel, cap)
|
||||
if not ircdb.checkCapability(msg.prefix, cap):
|
||||
irc.errorNoCapability(cap, Raise=True)
|
||||
|
||||
def getLowered(irc, msg, args, state):
|
||||
state.args.append(ircutils.toLower(args.pop(0)))
|
||||
|
||||
def getSomething(irc, msg, args):
|
||||
s = args.pop(0)
|
||||
if not s:
|
||||
# XXX Better reply? How?
|
||||
irc.error('You must not give the empty string as an argument.',
|
||||
Raise=True)
|
||||
return s
|
||||
def getSomething(irc, msg, args, state, errorMsg=None, p=None):
|
||||
if p is None:
|
||||
p = lambda _: True
|
||||
if not args[0] or not p(args[0]):
|
||||
if errorMsg is None:
|
||||
errorMsg = 'You must not give the empty string as an argument.'
|
||||
irc.error(errorMsg, Raise=True)
|
||||
else:
|
||||
state.args.append(args.pop(0))
|
||||
|
||||
def getPlugin(irc, msg, args, requirePresent=False):
|
||||
s = args.pop(0)
|
||||
cb = irc.getCallback(s)
|
||||
def getSomethingNoSpaces(irc, msg, args, state, *L):
|
||||
def p(s):
|
||||
return len(s.split(None, 1)) == 1
|
||||
getSomething(irc, msg, args, state, p=p, *L)
|
||||
|
||||
def getPlugin(irc, msg, args, state, requirePresent=False):
|
||||
cb = irc.getCallback(args[0])
|
||||
if requirePresent and cb is None:
|
||||
irc.errorInvalid('plugin', s, Raise=True)
|
||||
return cb
|
||||
irc.errorInvalid('plugin', s)
|
||||
state.args.append(cb)
|
||||
del args[0]
|
||||
|
||||
argWrappers = ircutils.IrcDict({
|
||||
def private(irc, msg, args, state):
|
||||
if ircutils.isChannel(msg.args[0]):
|
||||
irc.errorRequiresPrivacy(Raise=True)
|
||||
|
||||
def checkCapability(irc, msg, args, state, cap):
|
||||
cap = ircdb.canonicalCapability(cap)
|
||||
if not ircdb.checkCapability(msg.prefix, cap):
|
||||
state.log.warning('%s tried %s without %s.',
|
||||
msg.prefix, state.name, cap)
|
||||
irc.errorNoCapability(cap, Raise=True)
|
||||
|
||||
def anything(irc, msg, args, state):
|
||||
state.args.append(args.pop(0))
|
||||
|
||||
wrappers = ircutils.IrcDict({
|
||||
'id': getId,
|
||||
'int': getInt,
|
||||
'positiveInt': getPositiveInt,
|
||||
'nonNegativeInt': getNonNegativeInt,
|
||||
'haveOp': getHaveOp,
|
||||
'expiry': getExpiry,
|
||||
'nick': getNick,
|
||||
'channel': getChannel,
|
||||
'plugin': getPlugin,
|
||||
'boolean': getBoolean,
|
||||
'lowered': getLowered,
|
||||
'anything': anything,
|
||||
'something': getSomething,
|
||||
'somethingWithoutSpaces': getSomethingNoSpaces,
|
||||
'channelDb': getChannelDb,
|
||||
'hostmask': getHostmask,
|
||||
'banmask': getBanmask,
|
||||
'user': getUser,
|
||||
'private': private,
|
||||
'otherUser': getOtherUser,
|
||||
'regexpMatcher': getMatcher,
|
||||
'validChannel': validChannel,
|
||||
'regexpReplacer': getReplacer,
|
||||
'checkCapability': checkCapability,
|
||||
'checkChannelCapability': checkChannelCapability,
|
||||
})
|
||||
|
||||
def args(irc,msg,args, required=[], optional=[], getopts=None, noExtra=False):
|
||||
starArgs = []
|
||||
req = required[:]
|
||||
opt = optional[:]
|
||||
class State(object):
|
||||
def __init__(self, name=None, logger=None):
|
||||
if logger is None:
|
||||
logger = log
|
||||
self.args = []
|
||||
self.kwargs = {}
|
||||
self.name = name
|
||||
self.log = logger
|
||||
self.getopts = []
|
||||
self.channel = None
|
||||
|
||||
def args(irc,msg,args, types=[], state=None,
|
||||
getopts=None, noExtra=False, requireExtra=False, combineRest=True):
|
||||
orig = args[:]
|
||||
if state is None:
|
||||
state = State(name='unknown', logger=log)
|
||||
if requireExtra:
|
||||
combineRest = False # Implied by requireExtra.
|
||||
types = types[:] # We're going to destroy this.
|
||||
if getopts is not None:
|
||||
getoptL = []
|
||||
for (key, value) in getopts.iteritems():
|
||||
if value != '': # value can be None, remember.
|
||||
key += '='
|
||||
getoptL.append(key)
|
||||
def getArgWrapper(x):
|
||||
if isinstance(x, tuple):
|
||||
assert x
|
||||
name = x[0]
|
||||
args = x[1:]
|
||||
def callWrapper(spec):
|
||||
if isinstance(spec, tuple):
|
||||
assert spec, 'tuple specification cannot be empty.'
|
||||
name = spec[0]
|
||||
specArgs = spec[1:]
|
||||
else:
|
||||
assert isinstance(x, basestring) or x is None
|
||||
name = x
|
||||
args = ()
|
||||
if name is not None:
|
||||
return argWrappers[name], args
|
||||
else:
|
||||
return lambda irc, msg, args: args.pop(0), args
|
||||
def getConversion(name):
|
||||
(converter, convertArgs) = getArgWrapper(name)
|
||||
v = converter(irc, msg, args, *convertArgs)
|
||||
return v
|
||||
def callConverter(name):
|
||||
v = getConversion(name)
|
||||
starArgs.append(v)
|
||||
assert isinstance(spec, basestring) or spec is None
|
||||
name = spec
|
||||
specArgs = ()
|
||||
if name is None:
|
||||
name = 'anything'
|
||||
enforce = True
|
||||
optional = False
|
||||
if name.startswith('?'):
|
||||
optional = True
|
||||
name = name[1:]
|
||||
elif name.endswith('?'):
|
||||
optional = True
|
||||
enforce = False
|
||||
name = name[:-1]
|
||||
wrapper = wrappers[name]
|
||||
try:
|
||||
wrapper(irc, msg, args, state, *specArgs)
|
||||
except (callbacks.Error, ValueError, callbacks.ArgumentError), e:
|
||||
state.log.debug('%r when calling wrapper.', utils.exnToString(e))
|
||||
if not enforce:
|
||||
state.args.append('')
|
||||
else:
|
||||
state.log.debug('Re-raising %s because of enforce.', e)
|
||||
raise
|
||||
except IndexError, e:
|
||||
state.log.debug('%r when calling wrapper.', utils.exnToString(e))
|
||||
if optional:
|
||||
state.args.append('')
|
||||
else:
|
||||
state.log.debug('Raising ArgumentError because of '
|
||||
'non-optional args.')
|
||||
raise callbacks.ArgumentError
|
||||
|
||||
# First, we getopt stuff.
|
||||
if getopts is not None:
|
||||
L = []
|
||||
(optlist, args) = getopt.getopt(args, '', getoptL)
|
||||
for (opt, arg) in optlist:
|
||||
opt = opt[2:] # Strip --
|
||||
assert opt in getopts
|
||||
if arg is not None:
|
||||
assert getopts[opt] != ''
|
||||
L.append((opt, getConversion(getopts[opt])))
|
||||
state.getopts.append((opt, callWrapper(getopts[opt])))
|
||||
else:
|
||||
assert getopts[opt] == ''
|
||||
L.append((opt, True))
|
||||
starArgs.append(L)
|
||||
state.getopts.append((opt, True))
|
||||
|
||||
# Second, we get out everything but the last argument.
|
||||
try:
|
||||
while len(req) + len(opt) > 1:
|
||||
if req:
|
||||
callConverter(req.pop(0))
|
||||
else:
|
||||
assert opt
|
||||
callConverter(opt.pop(0))
|
||||
# Third, if there is a remaining required or optional argument
|
||||
# (there's a possibility that there were no required or optional
|
||||
# arguments) then we join the remaining args and work convert that.
|
||||
if req or opt:
|
||||
# Second, we get out everything but the last argument (or, if combineRest
|
||||
# is False, we'll clear out all the types).
|
||||
while len(types) > 1 or (types and not combineRest):
|
||||
callWrapper(types.pop(0))
|
||||
# Third, if there is a remaining required or optional argument
|
||||
# (there's a possibility that there were no required or optional
|
||||
# arguments) then we join the remaining args and work convert that.
|
||||
if types:
|
||||
assert len(types) == 1
|
||||
if args:
|
||||
rest = ' '.join(args)
|
||||
args = [rest]
|
||||
if required:
|
||||
converterName = req.pop(0)
|
||||
else:
|
||||
converterName = opt.pop(0)
|
||||
callConverter(converterName)
|
||||
except IndexError:
|
||||
if req:
|
||||
raise callbacks.ArgumentError
|
||||
while opt:
|
||||
del opt[-1]
|
||||
starArgs.append('')
|
||||
callWrapper(types.pop(0))
|
||||
if noExtra and args:
|
||||
log.debug('noExtra and args: %r (originally %r)', args, orig)
|
||||
raise callbacks.ArgumentError
|
||||
return starArgs
|
||||
if requireExtra and not args:
|
||||
log.debug('requireExtra and not args: %r (originally %r)', args, orig)
|
||||
log.debug('args: %r' % args)
|
||||
log.debug('State.args: %r' % state.args)
|
||||
log.debug('State.getopts: %r' % state.getopts)
|
||||
return state
|
||||
|
||||
# These are used below, but we need to rename them so their names aren't
|
||||
# shadowed by our locals.
|
||||
_args = args
|
||||
_wrappers = wrappers
|
||||
def wrap(f, required=[], optional=[],
|
||||
wrappers=None, getopts=None, noExtra=False):
|
||||
_decorators = decorators
|
||||
def wrap(f, *argsArgs, **argsKwargs):
|
||||
def newf(self, irc, msg, args, **kwargs):
|
||||
starArgs = _args(irc, msg, args,
|
||||
getopts=getopts, noExtra=noExtra,
|
||||
required=required, optional=optional)
|
||||
f(self, irc, msg, args, *starArgs, **kwargs)
|
||||
state = State('%s.%s' % (self.name(), f.func_name), self.log)
|
||||
state.cb = self # This should probably be in State.__init__.
|
||||
_args(irc,msg,args, state=state, *argsArgs, **argsKwargs)
|
||||
if state.getopts:
|
||||
f(self, irc, msg, args, state.getopts, *state.args, **state.kwargs)
|
||||
else:
|
||||
f(self, irc, msg, args, *state.args, **state.kwargs)
|
||||
|
||||
if wrappers is not None:
|
||||
wrappers = map(_wrappers.__getitem__, wrappers)
|
||||
for wrapper in wrappers:
|
||||
newf = wrapper(newf)
|
||||
decorators = argsKwargs.pop('decorators', None)
|
||||
if decorators is not None:
|
||||
decorators = map(_decorators.__getitem__, decorators)
|
||||
for decorator in decorators:
|
||||
newf = decorator(newf)
|
||||
return utils.changeFunctionName(newf, f.func_name, f.__doc__)
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue