when using zero or a negative <duration>, don't autoremove ban.

This commit is contained in:
Elián Hanisch 2012-08-03 11:46:17 -03:00
parent 0e92619987
commit 5df52f12f8
2 changed files with 56 additions and 19 deletions

View File

@ -54,6 +54,7 @@ import supybot.conf as conf
import supybot.ircdb as ircdb
import supybot.schedule as schedule
import supybot.utils as utils
from supybot.utils.str import format as Format
from fnmatch import fnmatch
from collections import defaultdict
import sqlite
@ -116,7 +117,7 @@ def readTimeDelta(s):
if c == ' ':
continue
if c.isdigit():
if c in '+-0123456789':
if string is None:
# start
digit, string = True, ''
@ -146,9 +147,9 @@ def readTimeDelta(s):
if string is None:
raise ValueError(s)
if string.isdigit():
try:
seconds += int(string)
else:
except ValueError:
string = string.strip()
if string:
try:
@ -1498,6 +1499,9 @@ class Bantracker(callbacks.Plugin):
return L[0]
def _setBanDuration(self, id, duration):
"""Set ban for remove after <duration> time, if <duration> is negative
or zero, never remove the ban.
"""
# check if ban has already a duration time
for idx, br in enumerate(self.managedBans):
if id == br.ban.id:
@ -1505,6 +1509,10 @@ class Bantracker(callbacks.Plugin):
del self.managedBans.shelf[idx]
break
else:
if duration < 1:
# nothing to do.
raise Exception("ban isn't marked for removal")
# ban obj ins't in self.managedBans
try:
mask, channel, removal = self._getBan(id)
@ -1527,8 +1535,9 @@ class Bantracker(callbacks.Plugin):
# ban not in sync it seems, shouldn't happen normally.
raise Exception("bans not in sync")
# add ban duration
self.managedBans.add(BanRemoval(ban, duration))
# add ban duration if is positive and non-zero
if duration > 0:
self.managedBans.add(BanRemoval(ban, duration))
def comment(self, irc, msg, args, ids, kickmsg):
"""<id>[,<id> ...] [<comment>][, <duration>]
@ -1581,12 +1590,16 @@ class Bantracker(callbacks.Plugin):
# success reply. If duration time used, say which ones were set.
if kickmsg:
if banset:
if duration < 1:
irc.reply(Format("Comment added. %L won't expire.", banset))
return
try:
time = 'after ' + timeElapsed(duration)
except ValueError:
time = 'soon'
irc.reply("Comment added. %s will be removed %s." \
% (utils.str.format('%L', banset), time))
irc.reply(Format("Comment added. %L will be removed %s.",
banset, time))
else:
# only a comment
irc.reply("Comment added.")
@ -1601,7 +1614,7 @@ class Bantracker(callbacks.Plugin):
if ids is None:
count = len(self.managedBans)
L = [ str(item.ban.id) for item in self.managedBans ]
irc.reply(utils.str.format("%n set to expire: %L", (count, 'ban'), L))
irc.reply(Format("%n set to expire: %L", (count, 'ban'), L))
return
if duration is not None:
@ -1662,11 +1675,15 @@ class Bantracker(callbacks.Plugin):
# reply with the bans ids that were correctly set.
if banset:
if duration < 1:
irc.reply(Format("%L won't expire.", banset))
return
try:
time = 'after ' + timeElapsed(duration)
except ValueError:
time = 'soon'
irc.reply("%s will be removed %s." % (utils.str.format('%L', banset), time))
irc.reply(Format("%L will be removed %s.", banset, time))
duration = wrap(duration, [optional('something'), optional('text')])

View File

@ -160,6 +160,18 @@ class BantrackerTestCase(ChannelPluginTestCase):
self.assertRegexp('comment 1', 'test: this is a test, 1 week 10$')
self.assertRegexp('duration 1', 'expires in 1 week$')
def testCommentDurationRemove(self):
self.feedBan('asd!*@*')
self.assertResponse('comment 1 this is a test, -10',
"Failed to set duration time on 1 (ban isn't marked for removal)")
msg = self.irc.takeMsg()
self.assertEqual(msg.args[1], 'test: Comment added.')
self.assertResponse('comment 1 this is a test, 10',
'Comment added. 1 will be removed soon.')
self.assertResponse('comment 1 this is a test, -10',
"Comment added. 1 won't expire.")
self.assertRegexp('duration 1', 'never expires$')
def testCommentRequest(self):
pluginConf.request.setValue(True)
# test bans
@ -397,6 +409,14 @@ class BantrackerTestCase(ChannelPluginTestCase):
msg = self.irc.takeMsg() # unban msg
self.assertEqual(str(msg).strip(), "MODE #test -b :asd!*@*")
def testDurationRemove(self):
self.feedBan('asd!*@*')
self.assertResponse('duration 1 -1',
"Failed to set duration time on 1 (ban isn't marked for removal)")
self.assertResponse('duration 1 10', '1 will be removed soon.')
self.assertResponse('duration 1 -1', "1 won't expire.")
self.assertRegexp('duration 1', 'never expires')
def testDurationMergeModes(self):
cb = self.getCallback()
self.feedBan('asd!*@*')
@ -405,9 +425,9 @@ class BantrackerTestCase(ChannelPluginTestCase):
self.feedBan('asd!*@*', mode='q')
self.feedBan('qwe!*@*', mode='q')
self.feedBan('zxc!*@*', mode='q')
self.assertNotError('duration 1,2,3,4,5,6 0')
print 'waiting 1 secs ...'
time.sleep(1)
self.assertNotError('duration 1,2,3,4,5,6 1')
print 'waiting 2 secs ...'
time.sleep(2)
cb.autoRemoveBans(self.irc)
msg = self.irc.takeMsg() # unban msg
self.assertEqual(str(msg).strip(),
@ -427,29 +447,29 @@ class BantrackerTestCase(ChannelPluginTestCase):
def testDurationQuiet(self):
cb = self.getCallback()
self.feedBan('asd!*@*', mode='q')
self.assertNotError('duration 1 0')
print 'waiting 1 sec ...'
time.sleep(1)
self.assertNotError('duration 1 1')
print 'waiting 2 sec ...'
time.sleep(2)
cb.autoRemoveBans(self.irc)
msg = self.irc.takeMsg() # unban msg
self.assertEqual(str(msg).strip(), "MODE #test -q :asd!*@*")
def testDurationBadType(self):
self.feedBan('nick', mode='k')
self.assertResponse('duration 1 0',
self.assertResponse('duration 1 1',
"Failed to set duration time on 1 (not a ban or quiet)")
self.feedBan('$a:nick')
self.assertResponse('duration 2 0', '2 will be removed soon.')
self.assertResponse('duration 2 1', '2 will be removed soon.')
def testDurationBadId(self):
self.assertResponse('duration 1 0',
self.assertResponse('duration 1 1',
"Failed to set duration time on 1 (unknow id)")
def testDurationInactiveBan(self):
self.feedBan('asd!*@*')
self.irc.feedMsg(ircmsgs.unban(self.channel, 'asd!*@*',
'op!user@host.net'))
self.assertResponse('duration 1 0',
self.assertResponse('duration 1 1',
"Failed to set duration time on 1 (ban was removed)")
def testDurationTimeFormat(self):