diff --git a/plugins/Channel/plugin.py b/plugins/Channel/plugin.py index 746a4aa47..aa1084eb0 100644 --- a/plugins/Channel/plugin.py +++ b/plugins/Channel/plugin.py @@ -575,8 +575,8 @@ class Channel(callbacks.Plugin): hostmask = wrap(hostmask, ['op', ('haveHalfop+', _('ban someone')), 'text']) @internationalizeDocstring - def add(self, irc, msg, args, channel, banmask, expires): - """[] [] + def add(self, irc, msg, args, channel, banmask, expires, description): + """[] [] [] If you have the #channel,op capability, this will effect a persistent ban from interacting with the bot on the given @@ -589,10 +589,11 @@ class Channel(callbacks.Plugin): channel itself. """ c = ircdb.channels.getChannel(channel) - c.addBan(banmask, expires) + c.addBan(banmask, expires or 0, description) ircdb.channels.setChannel(channel, c) irc.replySuccess() - add = wrap(add, ['op', first('hostmask', 'banmask'), additional('expiry', 0)]) + add = wrap(add, ['op', first('hostmask', 'banmask'), + optional('expiry'), optional('text')]) @internationalizeDocstring def remove(self, irc, msg, args, channel, banmask): @@ -630,12 +631,16 @@ class Channel(callbacks.Plugin): if filtered_bans: bans = [] for ban in filtered_bans: - if all_bans[ban]: - bans.append(format(_('%q (expires %t)'), - ban, all_bans[ban])) + (expiration, description) = all_bans[ban] + if expiration: + bans.append(format(_('%q (%s, expires %t)'), + ban, + description or _('no description'), + expiration)) else: - bans.append(format(_('%q (never expires)'), - ban, all_bans[ban])) + bans.append(format(_('%q (%s, never expires)'), + ban, + description or _('no description'))) irc.reply(format('%L', bans)) else: irc.reply(format(_('There are no persistent bans on %s.'), diff --git a/plugins/Channel/test.py b/plugins/Channel/test.py index 5addfd925..4ff4d1d94 100644 --- a/plugins/Channel/test.py +++ b/plugins/Channel/test.py @@ -234,7 +234,15 @@ class ChannelTestCase(ChannelPluginTestCase): self.assertRegexp('ban list foobar!*@baz', r'.*foobar!\*@baz.*') self.assertRegexp('ban list foobar!*@baz', r'.*foobar!qux@baz.*') self.assertResponse('ban list foobar!\*@baz', - '"foobar!*@baz" (never expires)') + '"foobar!*@baz" (no description, never expires)') + + self.assertNotError('ban add foobarbaz!qux@baz foo') + self.assertResponse('ban list foobarbaz!*@baz', + '"foobarbaz!qux@baz" (foo, never expires)') + + self.assertNotError('ban add foobarbazqux!qux@baz 5 bar') + self.assertRegexp('ban list foobarbazqux!*@baz', + r'"foobarbazqux!qux@baz" \(bar, expires [^ ]+\)') def testIgnore(self): orig = conf.supybot.protocols.irc.banmask() diff --git a/src/ircdb.py b/src/ircdb.py index ba8ae9075..03dcd4bb4 100644 --- a/src/ircdb.py +++ b/src/ircdb.py @@ -389,11 +389,11 @@ class IrcChannel(object): self.capabilities, self.lobotomized, self.defaultAllow, self.silences, self.exceptions) - def addBan(self, hostmask, expiration=0): + def addBan(self, hostmask, expiration=0, description=None): """Adds a ban to the channel banlist.""" assert not conf.supybot.protocols.irc.strictRfc() or \ ircutils.isUserHostmask(hostmask), 'got %s' % hostmask - self.bans[hostmask] = int(expiration) + self.bans[hostmask] = (int(expiration), description) def removeBan(self, hostmask): """Removes a ban from the channel banlist.""" @@ -405,7 +405,7 @@ class IrcChannel(object): """Checks whether a given hostmask is banned by the channel banlist.""" assert ircutils.isUserHostmask(hostmask), 'got %s' % hostmask now = time.time() - for (pattern, expiration) in self.bans.items(): + for (pattern, (expiration, description)) in self.bans.items(): if now < expiration or not expiration: if ircutils.hostmaskPatternEqual(pattern, hostmask): return True @@ -478,9 +478,9 @@ class IrcChannel(object): for capability in self.capabilities: write('capability ' + capability) bans = self.bans.items() - utils.sortBy(operator.itemgetter(1), bans) - for (ban, expiration) in bans: - write('ban %s %d' % (ban, expiration)) + utils.sortBy(lambda x:x[1][0], bans) + for (ban, (expiration, description)) in bans: + write('ban %s %d %s' % (ban, expiration, description)) ignores = self.ignores.items() utils.sortBy(operator.itemgetter(1), ignores) for (ignore, expiration) in ignores: