Update src/Channels.py to use commands.wrap. Added some more converters to

ease the process. Hopefully this doesn't break anything. The tests passed!
This commit is contained in:
James Vega 2004-09-23 16:13:00 +00:00
parent 19b2e37dad
commit e381f11e12
2 changed files with 127 additions and 129 deletions

View File

@ -42,12 +42,14 @@ import supybot.fix as fix
import sys import sys
import time import time
import getopt import getopt
from itertools import imap from itertools import imap
import supybot.conf as conf import supybot.conf as conf
import supybot.ircdb as ircdb import supybot.ircdb as ircdb
import supybot.utils as utils import supybot.utils as utils
import supybot.ircmsgs as ircmsgs import supybot.ircmsgs as ircmsgs
import supybot.commands as commands
import supybot.schedule as schedule import supybot.schedule as schedule
import supybot.ircutils as ircutils import supybot.ircutils as ircutils
import supybot.privmsgs as privmsgs import supybot.privmsgs as privmsgs
@ -77,41 +79,33 @@ class Channel(callbacks.Privmsg):
if self.registryValue('alwaysRejoin', channel): if self.registryValue('alwaysRejoin', channel):
irc.sendMsg(ircmsgs.join(channel)) # Fix for keys. irc.sendMsg(ircmsgs.join(channel)) # Fix for keys.
def mode(self, irc, msg, args, channel): def mode(self, irc, msg, args, channel, mode):
"""[<channel>] <mode> [<arg> ...] """[<channel>] <mode> [<arg> ...]
Sets the mode in <channel> to <mode>, sending the arguments given. Sets the mode in <channel> to <mode>, sending the arguments given.
<channel> is only necessary if the message isn't sent in the channel <channel> is only necessary if the message isn't sent in the channel
itself. itself.
""" """
if not args:
raise callbacks.ArgumentError
if self.haveOps(irc, channel, 'change the mode'): if self.haveOps(irc, channel, 'change the mode'):
irc.queueMsg(ircmsgs.mode(channel, args)) irc.queueMsg(ircmsgs.mode(channel, mode))
mode = privmsgs.checkChannelCapability(mode, 'op') mode = commands.wrap(mode, [('channel', 'op'), 'something'])
def limit(self, irc, msg, args, channel): def limit(self, irc, msg, args, channel, limit):
"""[<channel>] <limit> """[<channel>] <limit>
Sets the channel limit to <limit>. If <limit> is 0, removes the Sets the channel limit to <limit>. If <limit> is 0, removes the
channel limit. <channel> is only necessary if the message isn't sent channel limit. <channel> is only necessary if the message isn't sent
in the channel itself. in the channel itself.
""" """
limit = privmsgs.getArgs(args) if limit < 0:
try: irc.error('%r is not a positive integer.' % limit, Raise=True)
limit = int(limit)
if limit < 0:
raise ValueError
except ValueError:
irc.error('%r is not a positive integer.' % limit)
return
if limit: if limit:
if self.haveOps(irc, channel, 'set the limit'): if self.haveOps(irc, channel, 'set the limit'):
irc.queueMsg(ircmsgs.mode(channel, ['+l', limit])) irc.queueMsg(ircmsgs.mode(channel, ['+l', limit]))
else: else:
if self.haveOps(irc, channel, 'unset the limit'): if self.haveOps(irc, channel, 'unset the limit'):
irc.queueMsg(ircmsgs.mode(channel, ['-l'])) irc.queueMsg(ircmsgs.mode(channel, ['-l']))
limit = privmsgs.checkChannelCapability(limit, 'op') limit = commands.wrap(mode, [('channel', 'op'), 'int'])
def moderate(self, irc, msg, args, channel): def moderate(self, irc, msg, args, channel):
"""[<channel>] """[<channel>]
@ -122,7 +116,7 @@ class Channel(callbacks.Privmsg):
""" """
if self.haveOps(irc, channel, 'moderate the channel'): if self.haveOps(irc, channel, 'moderate the channel'):
irc.queueMsg(ircmsgs.mode(channel, ['+m'])) irc.queueMsg(ircmsgs.mode(channel, ['+m']))
moderate = privmsgs.checkChannelCapability(moderate, 'op') moderate = commands.wrap(moderate, [('channel', 'op')])
def unmoderate(self, irc, msg, args, channel): def unmoderate(self, irc, msg, args, channel):
"""[<channel>] """[<channel>]
@ -133,23 +127,22 @@ class Channel(callbacks.Privmsg):
""" """
if self.haveOps(irc, channel, 'unmoderate the channel'): if self.haveOps(irc, channel, 'unmoderate the channel'):
irc.queueMsg(ircmsgs.mode(channel, ['-m'])) irc.queueMsg(ircmsgs.mode(channel, ['-m']))
unmoderate = privmsgs.checkChannelCapability(unmoderate, 'op') unmoderate = commands.wrap(unmoderate, [('channel', 'op')])
def key(self, irc, msg, args, channel): def key(self, irc, msg, args, channel, key):
"""[<channel>] [<key>] """[<channel>] [<key>]
Sets the keyword in <channel> to <key>. If <key> is not given, removes Sets the keyword in <channel> to <key>. If <key> is not given, removes
the keyword requirement to join <channel>. <channel> is only necessary the keyword requirement to join <channel>. <channel> is only necessary
if the message isn't sent in the channel itself. if the message isn't sent in the channel itself.
""" """
key = privmsgs.getArgs(args, required=0, optional=1)
if key: if key:
if self.haveOps(irc, channel, 'set the keyword'): if self.haveOps(irc, channel, 'set the keyword'):
irc.queueMsg(ircmsgs.mode(channel, ['+k', key])) irc.queueMsg(ircmsgs.mode(channel, ['+k', key]))
else: else:
if self.haveOps(irc, channel, 'unset the keyword'): if self.haveOps(irc, channel, 'unset the keyword'):
irc.queueMsg(ircmsgs.mode(channel, ['-k'])) irc.queueMsg(ircmsgs.mode(channel, ['-k']))
key = privmsgs.checkChannelCapability(key, 'op') key = commands.wrap(key, [('channel', 'op')], ['something'])
def op(self, irc, msg, args, channel): def op(self, irc, msg, args, channel):
"""[<channel>] [<nick> ...] """[<channel>] [<nick> ...]
@ -163,7 +156,7 @@ class Channel(callbacks.Privmsg):
args = [msg.nick] args = [msg.nick]
if self.haveOps(irc, channel, 'op you'): if self.haveOps(irc, channel, 'op you'):
irc.queueMsg(ircmsgs.ops(channel, args)) irc.queueMsg(ircmsgs.ops(channel, args))
op = privmsgs.checkChannelCapability(op, 'op') op = commands.wrap(op, [('channel', 'op')])
def halfop(self, irc, msg, args, channel): def halfop(self, irc, msg, args, channel):
"""[<channel>] """[<channel>]
@ -177,7 +170,7 @@ class Channel(callbacks.Privmsg):
args = [msg.nick] args = [msg.nick]
if self.haveOps(irc, channel, 'halfop you'): if self.haveOps(irc, channel, 'halfop you'):
irc.queueMsg(ircmsgs.halfops(channel, args)) irc.queueMsg(ircmsgs.halfops(channel, args))
halfop = privmsgs.checkChannelCapability(halfop, 'halfop') halfop = commands.wrap(halfop, [('channel', 'halfop')])
def voice(self, irc, msg, args, channel): def voice(self, irc, msg, args, channel):
"""[<channel>] """[<channel>]
@ -191,7 +184,7 @@ class Channel(callbacks.Privmsg):
args = [msg.nick] args = [msg.nick]
if self.haveOps(irc, channel, 'voice you'): if self.haveOps(irc, channel, 'voice you'):
irc.queueMsg(ircmsgs.voices(channel, args)) irc.queueMsg(ircmsgs.voices(channel, args))
voice = privmsgs.checkChannelCapability(voice, 'voice') voice = commands.wrap(voice, [('channel', 'voice')])
def deop(self, irc, msg, args, channel): def deop(self, irc, msg, args, channel):
"""[<channel>] [<nick> ...] """[<channel>] [<nick> ...]
@ -208,7 +201,7 @@ class Channel(callbacks.Privmsg):
'yourself.') 'yourself.')
elif self.haveOps(irc, channel, 'deop someone'): elif self.haveOps(irc, channel, 'deop someone'):
irc.queueMsg(ircmsgs.deops(channel, args)) irc.queueMsg(ircmsgs.deops(channel, args))
deop = privmsgs.checkChannelCapability(deop, 'op') deop = commands.wrap(deop, [('channel', 'op')])
def dehalfop(self, irc, msg, args, channel): def dehalfop(self, irc, msg, args, channel):
"""[<channel>] [<nick> ...] """[<channel>] [<nick> ...]
@ -225,7 +218,7 @@ class Channel(callbacks.Privmsg):
'dehalfop me yourself.') 'dehalfop me yourself.')
elif self.haveOps(irc, channel, 'dehalfop someone'): elif self.haveOps(irc, channel, 'dehalfop someone'):
irc.queueMsg(ircmsgs.dehalfops(channel, args)) irc.queueMsg(ircmsgs.dehalfops(channel, args))
dehalfop = privmsgs.checkChannelCapability(dehalfop, 'op') dehalfop = commands.wrap(dehalfop, [('channel', 'halfop')])
def devoice(self, irc, msg, args, channel): def devoice(self, irc, msg, args, channel):
"""[<channel>] [<nick> ...] """[<channel>] [<nick> ...]
@ -242,9 +235,9 @@ class Channel(callbacks.Privmsg):
'me yourself.') 'me yourself.')
elif self.haveOps(irc, channel, 'devoice someone'): elif self.haveOps(irc, channel, 'devoice someone'):
irc.queueMsg(ircmsgs.devoices(channel, args)) irc.queueMsg(ircmsgs.devoices(channel, args))
devoice = privmsgs.checkChannelCapability(devoice, 'op') devoice = commands.wrap(devoice, [('channel', 'voice')])
def cycle(self, irc, msg, args, channel): def cycle(self, irc, msg, args, channel, key):
"""[<channel>] [<key>] """[<channel>] [<key>]
If you have the #channel,op capability, this will cause the bot to If you have the #channel,op capability, this will cause the bot to
@ -252,14 +245,13 @@ class Channel(callbacks.Privmsg):
the channel using that key. <channel> is only necessary if the message the channel using that key. <channel> is only necessary if the message
isn't sent in the channel itself. isn't sent in the channel itself.
""" """
key = privmsgs.getArgs(args, required=0, optional=1)
if not key: if not key:
key = None key = None
irc.queueMsg(ircmsgs.part(channel)) irc.queueMsg(ircmsgs.part(channel))
irc.queueMsg(ircmsgs.join(channel, key)) irc.queueMsg(ircmsgs.join(channel, key))
cycle = privmsgs.checkChannelCapability(cycle, 'op') cycle = commands.wrap(cycle, [('channel', 'op')], ['something'])
def kick(self, irc, msg, args, channel): def kick(self, irc, msg, args, channel, nick, reason):
"""[<channel>] <nick> [<reason>] """[<channel>] <nick> [<reason>]
Kicks <nick> from <channel> for <reason>. If <reason> isn't given, Kicks <nick> from <channel> for <reason>. If <reason> isn't given,
@ -268,7 +260,6 @@ class Channel(callbacks.Privmsg):
itself. itself.
""" """
if self.haveOps(irc, channel, 'kick someone'): if self.haveOps(irc, channel, 'kick someone'):
(nick, reason) = privmsgs.getArgs(args, optional=1)
if nick not in irc.state.channels[channel].users: if nick not in irc.state.channels[channel].users:
irc.error('%s isn\'t in %s.' % (nick, channel)) irc.error('%s isn\'t in %s.' % (nick, channel))
return return
@ -280,9 +271,9 @@ class Channel(callbacks.Privmsg):
'length for a KICK reason on this server.') 'length for a KICK reason on this server.')
return return
irc.queueMsg(ircmsgs.kick(channel, nick, reason)) irc.queueMsg(ircmsgs.kick(channel, nick, reason))
kick = privmsgs.checkChannelCapability(kick, 'op') kick = commands.wrap(kick, [('channel', 'op'), 'something'], ['something'])
def kban(self, irc, msg, args): def kban(self, irc, msg, args, channel, bannedNick, length, reason, *optlist):
"""[<channel>] [--{exact,nick,user,host}] <nick> [<seconds>] [<reason>] """[<channel>] [--{exact,nick,user,host}] <nick> [<seconds>] [<reason>]
If you have the #channel,op capability, this will kickban <nick> for If you have the #channel,op capability, this will kickban <nick> for
@ -295,11 +286,8 @@ class Channel(callbacks.Privmsg):
<channel> is only necessary if the message isn't sent in the channel <channel> is only necessary if the message isn't sent in the channel
itself. itself.
""" """
channel = privmsgs.getChannel(msg, args)
(optlist, rest) = getopt.getopt(args, '', ['exact', 'nick',
'user', 'host'])
(bannedNick, length, reason) = privmsgs.getArgs(rest, optional=2)
# Check that they're not trying to make us kickban ourself. # Check that they're not trying to make us kickban ourself.
self.log.critical('In kban')
if not ircutils.isNick(bannedNick): if not ircutils.isNick(bannedNick):
self.log.warning('%r tried to kban a non nick: %r', self.log.warning('%r tried to kban a non nick: %r',
msg.prefix, bannedNick) msg.prefix, bannedNick)
@ -337,13 +325,13 @@ class Channel(callbacks.Privmsg):
buser = '*' buser = '*'
bhost = '*' bhost = '*'
for (option, _) in optlist: for (option, _) in optlist:
if option == '--nick': if option == 'nick':
bnick = nick bnick = nick
elif option == '--user': elif option == 'user':
buser = user buser = user
elif option == '--host': elif option == 'host':
bhost = host bhost = host
elif option == '--exact': elif option == 'exact':
(bnick, buser, bhost) = \ (bnick, buser, bhost) = \
ircutils.splitHostmask(bannedHostmask) ircutils.splitHostmask(bannedHostmask)
banmask = ircutils.joinHostmask(bnick, buser, bhost) banmask = ircutils.joinHostmask(bnick, buser, bhost)
@ -384,8 +372,16 @@ class Channel(callbacks.Privmsg):
self.log.warning('%r attempted kban without %s', self.log.warning('%r attempted kban without %s',
msg.prefix, capability) msg.prefix, capability)
irc.errorNoCapability(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})
def unban(self, irc, msg, args, channel): def unban(self, irc, msg, args, channel, hostmask):
"""[<channel>] <hostmask> """[<channel>] <hostmask>
Unbans <hostmask> on <channel>. Especially useful for unbanning Unbans <hostmask> on <channel>. Especially useful for unbanning
@ -393,22 +389,20 @@ class Channel(callbacks.Privmsg):
the channel. <channel> is only necessary if the message isn't sent the channel. <channel> is only necessary if the message isn't sent
in the channel itself. in the channel itself.
""" """
hostmask = privmsgs.getArgs(args)
if self.haveOps(irc, channel, 'unban someone'): if self.haveOps(irc, channel, 'unban someone'):
irc.queueMsg(ircmsgs.unban(channel, hostmask)) irc.queueMsg(ircmsgs.unban(channel, hostmask))
unban = privmsgs.checkChannelCapability(unban, 'op') unban = commands.wrap(unban, [('channel', 'op'), 'hostmask'])
def invite(self, irc, msg, args, channel): def invite(self, irc, msg, args, channel, nick):
"""[<channel>] <nick> """[<channel>] <nick>
If you have the #channel,op capability, this will invite <nick> If you have the #channel,op capability, this will invite <nick>
to join <channel>. <channel> is only necessary if the message isn't to join <channel>. <channel> is only necessary if the message isn't
sent in the channel itself. sent in the channel itself.
""" """
nick = privmsgs.getArgs(args)
if self.haveOps(irc, channel, 'invite someone'): if self.haveOps(irc, channel, 'invite someone'):
irc.queueMsg(ircmsgs.invite(nick, channel)) irc.queueMsg(ircmsgs.invite(nick, channel))
invite = privmsgs.checkChannelCapability(invite, 'op') invite = commands.wrap(invite, [('channel', 'op'), 'something'])
def lobotomize(self, irc, msg, args, channel): def lobotomize(self, irc, msg, args, channel):
"""[<channel>] """[<channel>]
@ -422,7 +416,7 @@ class Channel(callbacks.Privmsg):
c.lobotomized = True c.lobotomized = True
ircdb.channels.setChannel(channel, c) ircdb.channels.setChannel(channel, c)
irc.replySuccess() irc.replySuccess()
lobotomize = privmsgs.checkChannelCapability(lobotomize, 'op') lobotomize = commands.wrap(lobotomize, [('channel', 'op')])
def unlobotomize(self, irc, msg, args, channel): def unlobotomize(self, irc, msg, args, channel):
"""[<channel>] """[<channel>]
@ -436,9 +430,9 @@ class Channel(callbacks.Privmsg):
c.lobotomized = False c.lobotomized = False
ircdb.channels.setChannel(channel, c) ircdb.channels.setChannel(channel, c)
irc.replySuccess() irc.replySuccess()
unlobotomize = privmsgs.checkChannelCapability(unlobotomize, 'op') unlobotomize = commands.wrap(unlobotomize, [('channel', 'op')])
def permban(self, irc, msg, args, channel): def permban(self, irc, msg, args, channel, banmask, expires):
"""[<channel>] <nick|hostmask> [<expires>] """[<channel>] <nick|hostmask> [<expires>]
If you have the #channel,op capability, this will effect a permanent If you have the #channel,op capability, this will effect a permanent
@ -450,29 +444,14 @@ class Channel(callbacks.Privmsg):
will never automatically expire. <channel> is only necessary if the will never automatically expire. <channel> is only necessary if the
message isn't sent in the channel itself. message isn't sent in the channel itself.
""" """
(nickOrHostmask, expires) = privmsgs.getArgs(args, optional=1)
if ircutils.isNick(nickOrHostmask) and \
nickOrHostmask in irc.state.nicksToHostmasks:
banmask = ircutils.banmask(irc.state.nickToHostmask(nickOrHostmask))
elif ircutils.isUserHostmask(nickOrHostmask):
banmask = nickOrHostmask
else:
irc.errorInvalid('nick or hostmask', nickOrHostmask, Raise=True)
if expires:
try:
expires = int(float(expires))
expires += int(time.time())
except ValueError:
irc.errorInvalid('number of seconds',nickOrHostmask,Raise=True)
else:
expires = 0
c = ircdb.channels.getChannel(channel) c = ircdb.channels.getChannel(channel)
c.addBan(banmask, expires) c.addBan(banmask, expires)
ircdb.channels.setChannel(channel, c) ircdb.channels.setChannel(channel, c)
irc.replySuccess() irc.replySuccess()
permban = privmsgs.checkChannelCapability(permban, 'op') permban = \
commands.wrap(permban, [('channel', 'op'), 'banmask', ('expiry', 0)])
def unpermban(self, irc, msg, args, channel): def unpermban(self, irc, msg, args, channel, banmask):
"""[<channel>] <hostmask> """[<channel>] <hostmask>
If you have the #channel,op capability, this will remove the permanent If you have the #channel,op capability, this will remove the permanent
@ -485,7 +464,7 @@ class Channel(callbacks.Privmsg):
ircdb.channels.setChannel(channel, c) ircdb.channels.setChannel(channel, c)
#irc.queueMsg(ircmsgs.unban(channel, banmask)) #irc.queueMsg(ircmsgs.unban(channel, banmask))
irc.replySuccess() irc.replySuccess()
unpermban = privmsgs.checkChannelCapability(unpermban, 'op') unpermban = commands.wrap(unpermban, [('channel', 'op'), 'banmask'])
def permbans(self, irc, msg, args, channel): def permbans(self, irc, msg, args, channel):
"""[<channel>] """[<channel>]
@ -499,9 +478,9 @@ class Channel(callbacks.Privmsg):
irc.reply(utils.commaAndify(map(utils.dqrepr, c.bans))) irc.reply(utils.commaAndify(map(utils.dqrepr, c.bans)))
else: else:
irc.reply('There are currently no permanent bans on %s' % channel) irc.reply('There are currently no permanent bans on %s' % channel)
permbans = privmsgs.checkChannelCapability(permbans, 'op') permbans = commands.wrap(permbans, [('channel', 'op')])
def ignore(self, irc, msg, args, channel): def ignore(self, irc, msg, args, channel, banmask, expires):
"""[<channel>] <nick|hostmask> [<expires>] """[<channel>] <nick|hostmask> [<expires>]
If you have the #channel,op capability, this will set a permanent If you have the #channel,op capability, this will set a permanent
@ -511,40 +490,25 @@ class Channel(callbacks.Privmsg):
ignore will never automatically expire. <channel> is only necessary ignore will never automatically expire. <channel> is only necessary
if the message isn't sent in the channel itself. if the message isn't sent in the channel itself.
""" """
(nickOrHostmask, expires) = privmsgs.getArgs(args, optional=1)
if ircutils.isNick(nickOrHostmask):
banmask = ircutils.banmask(irc.state.nickToHostmask(nickOrHostmask))
elif ircutils.isUserHostmask(nickOrHostmask):
banmask = nickOrHostmask
else:
irc.errorInvalid('nick or hostmask', nickOrHostmask, Raise=True)
if expires:
try:
expires = int(float(expires))
expires += int(time.time())
except ValueError:
irc.errorInvalid('number of seconds',nickOrHostmask,Raise=True)
else:
expires = 0
c = ircdb.channels.getChannel(channel) c = ircdb.channels.getChannel(channel)
c.addIgnore(banmask, expires) c.addIgnore(banmask, expires)
ircdb.channels.setChannel(channel, c) ircdb.channels.setChannel(channel, c)
irc.replySuccess() irc.replySuccess()
ignore = privmsgs.checkChannelCapability(ignore, 'op') ignore = \
commands.wrap(ignore,[('channel', 'op'), 'banmask', ('expiry', 0)])
def unignore(self, irc, msg, args, channel): def unignore(self, irc, msg, args, channel, banmask):
"""[<channel>] <hostmask> """[<channel>] <hostmask>
If you have the #channel,op capability, this will remove the permanent If you have the #channel,op capability, this will remove the permanent
ignore on <hostmask> in the channel. <channel> is only necessary if the ignore on <hostmask> in the channel. <channel> is only necessary if the
message isn't sent in the channel itself. message isn't sent in the channel itself.
""" """
banmask = privmsgs.getArgs(args)
c = ircdb.channels.getChannel(channel) c = ircdb.channels.getChannel(channel)
c.removeIgnore(banmask) c.removeIgnore(banmask)
ircdb.channels.setChannel(channel, c) ircdb.channels.setChannel(channel, c)
irc.replySuccess() irc.replySuccess()
unignore = privmsgs.checkChannelCapability(unignore, 'op') unignore = commands.wrap(unignore, [('channel', 'op'), 'something'])
def ignores(self, irc, msg, args, channel): def ignores(self, irc, msg, args, channel):
"""[<channel>] """[<channel>]
@ -554,8 +518,6 @@ class Channel(callbacks.Privmsg):
itself. itself.
""" """
# XXX Add the expirations. # XXX Add the expirations.
channelarg = privmsgs.getArgs(args, required=0, optional=1)
channel = channelarg or channel
c = ircdb.channels.getChannel(channel) c = ircdb.channels.getChannel(channel)
if len(c.ignores) == 0: if len(c.ignores) == 0:
s = 'I\'m not currently ignoring any hostmasks in %r' % channel s = 'I\'m not currently ignoring any hostmasks in %r' % channel
@ -563,9 +525,9 @@ class Channel(callbacks.Privmsg):
else: else:
L = sorted(c.ignores) L = sorted(c.ignores)
irc.reply(utils.commaAndify(imap(repr, L))) irc.reply(utils.commaAndify(imap(repr, L)))
ignores = privmsgs.checkChannelCapability(ignores, 'op') ignores = commands.wrap(ignores, [('channel', 'op')])
def addcapability(self, irc, msg, args, channel): def addcapability(self, irc, msg, args, channel, hostmask, capabilities):
"""[<channel>] <name|hostmask> <capability> [<capability> ...] """[<channel>] <name|hostmask> <capability> [<capability> ...]
If you have the #channel,op capability, this will give the user If you have the #channel,op capability, this will give the user
@ -573,20 +535,21 @@ class Channel(callbacks.Privmsg):
the capability <capability> in the channel. <channel> is only necessary the capability <capability> in the channel. <channel> is only necessary
if the message isn't sent in the channel itself. if the message isn't sent in the channel itself.
""" """
(name, capabilities) = privmsgs.getArgs(args, 2)
try: try:
id = ircdb.users.getUserId(name) id = ircdb.users.getUserId(hostmask)
user = ircdb.users.getUser(id) user = ircdb.users.getUser(id)
except KeyError: except KeyError:
irc.errorNoUser() irc.errorNoUser()
for c in capability.split(): for c in capabilities.split():
c = ircdb.makeChannelCapability(channel, c) c = ircdb.makeChannelCapability(channel, c)
user.addCapability(c) user.addCapability(c)
ircdb.users.setUser(id, user) ircdb.users.setUser(id, user)
irc.replySuccess() irc.replySuccess()
addcapability = privmsgs.checkChannelCapability(addcapability,'op') addcapability = \
commands.wrap(addcapability,
[('channel', 'op'), 'hostmask', 'something'])
def removecapability(self, irc, msg, args, channel): def removecapability(self, irc, msg, args, channel, hostmask, capabilities):
"""[<channel>] <name|hostmask> <capability> [<capability> ...] """[<channel>] <name|hostmask> <capability> [<capability> ...]
If you have the #channel,op capability, this will take from the user If you have the #channel,op capability, this will take from the user
@ -594,9 +557,8 @@ class Channel(callbacks.Privmsg):
the capability <capability> in the channel. <channel> is only necessary the capability <capability> in the channel. <channel> is only necessary
if the message isn't sent in the channel itself. if the message isn't sent in the channel itself.
""" """
(name, capabilities) = privmsgs.getArgs(args, 2)
try: try:
id = ircdb.users.getUserId(name) id = ircdb.users.getUserId(hostmask)
except KeyError: except KeyError:
irc.errorNoUser() irc.errorNoUser()
return return
@ -614,48 +576,44 @@ class Channel(callbacks.Privmsg):
(utils.commaAndify(fail), (utils.commaAndify(fail),
utils.pluralize('capability', len(fail))), Raise=True) utils.pluralize('capability', len(fail))), Raise=True)
irc.replySuccess() irc.replySuccess()
removecapability = privmsgs.checkChannelCapability(removecapability, 'op') removecapability = \
commands.wrap(removecapability,
[('channel', 'op'), 'hostmask', 'something'])
def setdefaultcapability(self, irc, msg, args, channel): def setdefaultcapability(self, irc, msg, args, channel, v):
"""[<channel>] <default response to unknown capabilities> <True|False> """[<channel>] {True|False}
If you have the #channel,op capability, this will set the default If you have the #channel,op capability, this will set the default
response to non-power-related (that is, not {op, halfop, voice} response to non-power-related (that is, not {op, halfop, voice}
capabilities to be the value you give. <channel> is only necessary if capabilities to be the value you give. <channel> is only necessary if
the message isn't sent in the channel itself. the message isn't sent in the channel itself.
""" """
v = privmsgs.getArgs(args)
v = v.capitalize()
c = ircdb.channels.getChannel(channel) c = ircdb.channels.getChannel(channel)
if v == 'True': if v:
c.setDefaultCapability(True) c.setDefaultCapability(True)
elif v == 'False':
c.setDefaultCapability(False)
else: else:
s = 'The default value must be either True or False.' c.setDefaultCapability(False)
irc.error(s)
return
ircdb.channels.setChannel(channel, c) ircdb.channels.setChannel(channel, c)
irc.replySuccess() irc.replySuccess()
setdefaultcapability = \ setdefaultcapability = \
privmsgs.checkChannelCapability(setdefaultcapability, 'op') commands.wrap(setdefaultcapability, [('channel', 'op'), 'boolean'])
def setcapability(self, irc, msg, args, channel): def setcapability(self, irc, msg, args, channel, capabilities):
"""[<channel>] <capability> [<capability> ...] """[<channel>] <capability> [<capability> ...]
If you have the #channel,op capability, this will add the channel If you have the #channel,op capability, this will add the channel
capability <capability> for all users in the channel. <channel> is capability <capability> for all users in the channel. <channel> is
only necessary if the message isn't sent in the channel itself. only necessary if the message isn't sent in the channel itself.
""" """
capabilities = privmsgs.getArgs(args)
chan = ircdb.channels.getChannel(channel) chan = ircdb.channels.getChannel(channel)
for c in capabilities.split(): for c in capabilities.split():
chan.addCapability(c) chan.addCapability(c)
ircdb.channels.setChannel(channel, chan) ircdb.channels.setChannel(channel, chan)
irc.replySuccess() irc.replySuccess()
setcapability = privmsgs.checkChannelCapability(setcapability, 'op') setcapability = \
commands.wrap(setcapability, [('channel', 'op'), 'something'])
def unsetcapability(self, irc, msg, args, channel): def unsetcapability(self, irc, msg, args, channel, capabilities):
"""[<channel>] <capability> [<capability> ...] """[<channel>] <capability> [<capability> ...]
If you have the #channel,op capability, this will unset the channel If you have the #channel,op capability, this will unset the channel
@ -663,7 +621,6 @@ class Channel(callbacks.Privmsg):
channel default capability will take precedence. <channel> is only channel default capability will take precedence. <channel> is only
necessary if the message isn't sent in the channel itself. necessary if the message isn't sent in the channel itself.
""" """
capabilities = privmsgs.getArgs(args)
chan = ircdb.channels.getChannel(channel) chan = ircdb.channels.getChannel(channel)
fail = [] fail = []
for c in capabilities.split(): for c in capabilities.split():
@ -677,18 +634,19 @@ class Channel(callbacks.Privmsg):
(utils.commaAndify(fail), (utils.commaAndify(fail),
utils.pluralize('capability', len(fail))), Raise=True) utils.pluralize('capability', len(fail))), Raise=True)
irc.replySuccess() irc.replySuccess()
unsetcapability = privmsgs.checkChannelCapability(unsetcapability, 'op') unsetcapability = \
commands.wrap(unsetcapability, [('channel', 'op'), 'something'])
def capabilities(self, irc, msg, args): def capabilities(self, irc, msg, args, channel):
"""[<channel>] """[<channel>]
Returns the capabilities present on the <channel>. <channel> is only Returns the capabilities present on the <channel>. <channel> is only
necessary if the message isn't sent in the channel itself. necessary if the message isn't sent in the channel itself.
""" """
channel = privmsgs.getChannel(msg, args)
c = ircdb.channels.getChannel(channel) c = ircdb.channels.getChannel(channel)
L = sorted(c.capabilities) L = sorted(c.capabilities)
irc.reply('[%s]' % '; '.join(L)) irc.reply('[%s]' % '; '.join(L))
capabilities = commands.wrap(capabilities, ['channel'])
def lobotomies(self, irc, msg, args): def lobotomies(self, irc, msg, args):
"""takes no arguments """takes no arguments
@ -706,16 +664,16 @@ class Channel(callbacks.Privmsg):
else: else:
irc.reply('I\'m not currently lobotomized in any channels.') irc.reply('I\'m not currently lobotomized in any channels.')
def nicks(self, irc, msg, args): def nicks(self, irc, msg, args, channel):
"""[<channel>] """[<channel>]
Returns the nicks in <channel>. <channel> is only necessary if the Returns the nicks in <channel>. <channel> is only necessary if the
message isn't sent in the channel itself. message isn't sent in the channel itself.
""" """
channel = privmsgs.getChannel(msg, args)
L = list(irc.state.channels[channel].users) L = list(irc.state.channels[channel].users)
utils.sortBy(str.lower, L) utils.sortBy(str.lower, L)
irc.reply(utils.commaAndify(L)) irc.reply(utils.commaAndify(L))
nicks = commands.wrap(nicks, ['channel'])
def alertOps(self, irc, channel, s, frm=None): def alertOps(self, irc, channel, s, frm=None):
"""Internal message for notifying all the #channel,ops in a channel of """Internal message for notifying all the #channel,ops in a channel of

View File

@ -122,7 +122,7 @@ class SnarfIrc(object):
def reply(self, *args, **kwargs): def reply(self, *args, **kwargs):
_snarfed.enqueue(self.channel, self.url) _snarfed.enqueue(self.channel, self.url)
self.irc.reply(*args, **kwargs) self.irc.reply(*args, **kwargs)
# This lock is used to serialize the calls to snarfers, so # This lock is used to serialize the calls to snarfers, so
# earlier snarfers are guaranteed to beat out later snarfers. # earlier snarfers are guaranteed to beat out later snarfers.
_snarfLock = threading.Lock() _snarfLock = threading.Lock()
@ -178,10 +178,33 @@ def getInt(irc, msg, args, default=None, type='integer'):
return default return default
else: else:
irc.errorInvalid(type, s, Raise=True) irc.errorInvalid(type, s, Raise=True)
def getId(irc, msg, args): def getId(irc, msg, args):
getInt(irc, msg, args, type='id') getInt(irc, msg, args, type='id')
def getExpiry(irc, msg, args, default=None):
s = args.pop(0)
try:
expires = int(float(s))
expires += int(time.time())
except ValueError:
if default is not None:
return default
else:
irc.errorInvalid('number of seconds', s, Raise=True)
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 getChannelDb(irc, msg, args, **kwargs): def getChannelDb(irc, msg, args, **kwargs):
if not conf.supybot.databases.plugins.channelSpecific(): if not conf.supybot.databases.plugins.channelSpecific():
return None return None
@ -205,6 +228,16 @@ def getHostmask(irc, msg, args):
except KeyError: except KeyError:
irc.errorInvalid('nick or hostmask', s, Raise=True) irc.errorInvalid('nick or hostmask', s, Raise=True)
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 getUser(irc, msg, args): def getUser(irc, msg, args):
try: try:
return ircdb.users.getUser(msg.prefix) return ircdb.users.getUser(msg.prefix)
@ -254,6 +287,8 @@ def getNick(irc, msg, args):
def getChannel(irc, msg, args, cap=None): def getChannel(irc, msg, args, cap=None):
if ircutils.isChannel(args[0]): if ircutils.isChannel(args[0]):
channel = args.pop(0) channel = args.pop(0)
print '*** channel? %s' % channel
print '*** args? %s' % args
elif ircutils.isChannel(msg.args[0]): elif ircutils.isChannel(msg.args[0]):
channel = msg.args[0] channel = msg.args[0]
else: else:
@ -283,22 +318,25 @@ def getPlugin(irc, msg, args, requirePresent=False):
if requirePresent and cb is None: if requirePresent and cb is None:
irc.errorInvalid('plugin', s, Raise=True) irc.errorInvalid('plugin', s, Raise=True)
return cb return cb
argWrappers = ircutils.IrcDict({ argWrappers = ircutils.IrcDict({
'id': getId, 'id': getId,
'int': getInt, 'int': getInt,
'expiry': getExpiry,
'nick': getNick, 'nick': getNick,
'channel': getChannel, 'channel': getChannel,
'plugin': getPlugin, 'plugin': getPlugin,
'boolean': getBoolean,
'lowered': getLowered, 'lowered': getLowered,
'something': getSomething, 'something': getSomething,
'channelDb': getChannelDb, 'channelDb': getChannelDb,
'hostmask': getHostmask, 'hostmask': getHostmask,
'banmask': getBanmask,
'user': getUser, 'user': getUser,
'otherUser': getOtherUser, 'otherUser': getOtherUser,
'regexpMatcher': getMatcher, 'regexpMatcher': getMatcher,
'validChannel': validChannel, 'validChannel': validChannel,
'regexpReplacer': getReplacer, 'regexpReplacer': getReplacer,
}) })
def args(irc,msg,args, required=[], optional=[], getopts=None, noExtra=False): def args(irc,msg,args, required=[], optional=[], getopts=None, noExtra=False):
@ -368,14 +406,16 @@ def args(irc,msg,args, required=[], optional=[], getopts=None, noExtra=False):
callConverter(converterName) callConverter(converterName)
except IndexError: except IndexError:
if req: if req:
print '*** commands.args IndexError'
raise callbacks.ArgumentError raise callbacks.ArgumentError
while opt: while opt:
del opt[-1] del opt[-1]
starArgs.append('') starArgs.append('')
if noExtra and args: if noExtra and args:
print '*** commands.args noExtra and args'
raise callbacks.ArgumentError raise callbacks.ArgumentError
return starArgs return starArgs
# These are used below, but we need to rename them so their names aren't # These are used below, but we need to rename them so their names aren't
# shadowed by our locals. # shadowed by our locals.
_args = args _args = args
@ -393,6 +433,6 @@ def wrap(f, required=[], optional=[],
for wrapper in wrappers: for wrapper in wrappers:
newf = wrapper(newf) newf = wrapper(newf)
return utils.changeFunctionName(newf, f.func_name, f.__doc__) return utils.changeFunctionName(newf, f.func_name, f.__doc__)
# vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78: # vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78: