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.ircdb as ircdb
import supybot.schedule as schedule import supybot.schedule as schedule
import supybot.utils as utils import supybot.utils as utils
from supybot.utils.str import format as Format
from fnmatch import fnmatch from fnmatch import fnmatch
from collections import defaultdict from collections import defaultdict
import sqlite import sqlite
@ -116,7 +117,7 @@ def readTimeDelta(s):
if c == ' ': if c == ' ':
continue continue
if c.isdigit(): if c in '+-0123456789':
if string is None: if string is None:
# start # start
digit, string = True, '' digit, string = True, ''
@ -146,9 +147,9 @@ def readTimeDelta(s):
if string is None: if string is None:
raise ValueError(s) raise ValueError(s)
if string.isdigit(): try:
seconds += int(string) seconds += int(string)
else: except ValueError:
string = string.strip() string = string.strip()
if string: if string:
try: try:
@ -1498,6 +1499,9 @@ class Bantracker(callbacks.Plugin):
return L[0] return L[0]
def _setBanDuration(self, id, duration): 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 # check if ban has already a duration time
for idx, br in enumerate(self.managedBans): for idx, br in enumerate(self.managedBans):
if id == br.ban.id: if id == br.ban.id:
@ -1505,6 +1509,10 @@ class Bantracker(callbacks.Plugin):
del self.managedBans.shelf[idx] del self.managedBans.shelf[idx]
break break
else: else:
if duration < 1:
# nothing to do.
raise Exception("ban isn't marked for removal")
# ban obj ins't in self.managedBans # ban obj ins't in self.managedBans
try: try:
mask, channel, removal = self._getBan(id) mask, channel, removal = self._getBan(id)
@ -1527,8 +1535,9 @@ class Bantracker(callbacks.Plugin):
# ban not in sync it seems, shouldn't happen normally. # ban not in sync it seems, shouldn't happen normally.
raise Exception("bans not in sync") raise Exception("bans not in sync")
# add ban duration # add ban duration if is positive and non-zero
self.managedBans.add(BanRemoval(ban, duration)) if duration > 0:
self.managedBans.add(BanRemoval(ban, duration))
def comment(self, irc, msg, args, ids, kickmsg): def comment(self, irc, msg, args, ids, kickmsg):
"""<id>[,<id> ...] [<comment>][, <duration>] """<id>[,<id> ...] [<comment>][, <duration>]
@ -1581,12 +1590,16 @@ class Bantracker(callbacks.Plugin):
# success reply. If duration time used, say which ones were set. # success reply. If duration time used, say which ones were set.
if kickmsg: if kickmsg:
if banset: if banset:
if duration < 1:
irc.reply(Format("Comment added. %L won't expire.", banset))
return
try: try:
time = 'after ' + timeElapsed(duration) time = 'after ' + timeElapsed(duration)
except ValueError: except ValueError:
time = 'soon' time = 'soon'
irc.reply("Comment added. %s will be removed %s." \ irc.reply(Format("Comment added. %L will be removed %s.",
% (utils.str.format('%L', banset), time)) banset, time))
else: else:
# only a comment # only a comment
irc.reply("Comment added.") irc.reply("Comment added.")
@ -1601,7 +1614,7 @@ class Bantracker(callbacks.Plugin):
if ids is None: if ids is None:
count = len(self.managedBans) count = len(self.managedBans)
L = [ str(item.ban.id) for item in 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 return
if duration is not None: if duration is not None:
@ -1662,11 +1675,15 @@ class Bantracker(callbacks.Plugin):
# reply with the bans ids that were correctly set. # reply with the bans ids that were correctly set.
if banset: if banset:
if duration < 1:
irc.reply(Format("%L won't expire.", banset))
return
try: try:
time = 'after ' + timeElapsed(duration) time = 'after ' + timeElapsed(duration)
except ValueError: except ValueError:
time = 'soon' 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')]) 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('comment 1', 'test: this is a test, 1 week 10$')
self.assertRegexp('duration 1', 'expires in 1 week$') 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): def testCommentRequest(self):
pluginConf.request.setValue(True) pluginConf.request.setValue(True)
# test bans # test bans
@ -397,6 +409,14 @@ class BantrackerTestCase(ChannelPluginTestCase):
msg = self.irc.takeMsg() # unban msg msg = self.irc.takeMsg() # unban msg
self.assertEqual(str(msg).strip(), "MODE #test -b :asd!*@*") 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): def testDurationMergeModes(self):
cb = self.getCallback() cb = self.getCallback()
self.feedBan('asd!*@*') self.feedBan('asd!*@*')
@ -405,9 +425,9 @@ class BantrackerTestCase(ChannelPluginTestCase):
self.feedBan('asd!*@*', mode='q') self.feedBan('asd!*@*', mode='q')
self.feedBan('qwe!*@*', mode='q') self.feedBan('qwe!*@*', mode='q')
self.feedBan('zxc!*@*', mode='q') self.feedBan('zxc!*@*', mode='q')
self.assertNotError('duration 1,2,3,4,5,6 0') self.assertNotError('duration 1,2,3,4,5,6 1')
print 'waiting 1 secs ...' print 'waiting 2 secs ...'
time.sleep(1) time.sleep(2)
cb.autoRemoveBans(self.irc) cb.autoRemoveBans(self.irc)
msg = self.irc.takeMsg() # unban msg msg = self.irc.takeMsg() # unban msg
self.assertEqual(str(msg).strip(), self.assertEqual(str(msg).strip(),
@ -427,29 +447,29 @@ class BantrackerTestCase(ChannelPluginTestCase):
def testDurationQuiet(self): def testDurationQuiet(self):
cb = self.getCallback() cb = self.getCallback()
self.feedBan('asd!*@*', mode='q') self.feedBan('asd!*@*', mode='q')
self.assertNotError('duration 1 0') self.assertNotError('duration 1 1')
print 'waiting 1 sec ...' print 'waiting 2 sec ...'
time.sleep(1) time.sleep(2)
cb.autoRemoveBans(self.irc) cb.autoRemoveBans(self.irc)
msg = self.irc.takeMsg() # unban msg msg = self.irc.takeMsg() # unban msg
self.assertEqual(str(msg).strip(), "MODE #test -q :asd!*@*") self.assertEqual(str(msg).strip(), "MODE #test -q :asd!*@*")
def testDurationBadType(self): def testDurationBadType(self):
self.feedBan('nick', mode='k') 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)") "Failed to set duration time on 1 (not a ban or quiet)")
self.feedBan('$a:nick') 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): def testDurationBadId(self):
self.assertResponse('duration 1 0', self.assertResponse('duration 1 1',
"Failed to set duration time on 1 (unknow id)") "Failed to set duration time on 1 (unknow id)")
def testDurationInactiveBan(self): def testDurationInactiveBan(self):
self.feedBan('asd!*@*') self.feedBan('asd!*@*')
self.irc.feedMsg(ircmsgs.unban(self.channel, 'asd!*@*', self.irc.feedMsg(ircmsgs.unban(self.channel, 'asd!*@*',
'op!user@host.net')) 'op!user@host.net'))
self.assertResponse('duration 1 0', self.assertResponse('duration 1 1',
"Failed to set duration time on 1 (ban was removed)") "Failed to set duration time on 1 (ban was removed)")
def testDurationTimeFormat(self): def testDurationTimeFormat(self):