From 5df52f12f82c1102dd15d39ac947f87f4962bd0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eli=C3=A1n=20Hanisch?= Date: Fri, 3 Aug 2012 11:46:17 -0300 Subject: [PATCH] when using zero or a negative , don't autoremove ban. --- Bantracker/plugin.py | 35 ++++++++++++++++++++++++++--------- Bantracker/test.py | 40 ++++++++++++++++++++++++++++++---------- 2 files changed, 56 insertions(+), 19 deletions(-) diff --git a/Bantracker/plugin.py b/Bantracker/plugin.py index 313c8e7..6d579b9 100644 --- a/Bantracker/plugin.py +++ b/Bantracker/plugin.py @@ -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 time, if 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): """[, ...] [][, ] @@ -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')]) diff --git a/Bantracker/test.py b/Bantracker/test.py index 615b409..0b3d32d 100644 --- a/Bantracker/test.py +++ b/Bantracker/test.py @@ -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):