From 87f61b1654c85c7525eab53c081fdea55f3ce1f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eli=C3=A1n=20Hanisch?= Date: Wed, 4 Jul 2012 21:35:07 -0300 Subject: [PATCH] send notifications when ban are about to expire (notification channel hardcoded to #test) --- Bantracker/plugin.py | 35 +++++++++++++++++++++++++++-------- Bantracker/test.py | 12 ++++++++++++ 2 files changed, 39 insertions(+), 8 deletions(-) diff --git a/Bantracker/plugin.py b/Bantracker/plugin.py index 52edca4..b158a03 100644 --- a/Bantracker/plugin.py +++ b/Bantracker/plugin.py @@ -321,10 +321,11 @@ class BanRemoval(object): assert isinstance(expires, int), "expire time isn't an integer" self.ban = ban self.expires = expires + self.notified = False - def expired(self): + def expired(self, offset=0): """Check if the ban did expire.""" - if nowSeconds() > (self.ban.when + self.expires): + if (nowSeconds() + offset) > (self.ban.when + self.expires): return True return False @@ -350,7 +351,7 @@ class BanStore(object): self.shelf.sort(key=key, reverse=True) - def popExpired(self): + def popExpired(self, time=0): """Pops a list of expired bans""" def enumerateReversed(L): """enumerate in reverse order""" @@ -359,11 +360,18 @@ class BanStore(object): L = [] for i, ban in enumerateReversed(self.shelf): - if ban.expired(): + if ban.expired(offset=time): L.append(ban) del self.shelf[i] return L + def getExpired(self, time=0): + def generator(): + for ban in self.shelf: + if ban.expired(offset=time): + yield ban + return generator() + class Bantracker(callbacks.Plugin): """Plugin to manage bans. @@ -763,17 +771,28 @@ class Bantracker(callbacks.Plugin): if not L: del self.pendingReviews[None] - def autoRemoveBans(self, irc=None): + def autoRemoveBans(self, irc): modedict = { 'quiet': '-q', 'ban': '-b' } for ban in self.managedBans.popExpired(): channel, mask, type = ban.ban.channel, ban.ban.mask, ban.ban.type - self.log.info("%s '%s' in %s expired", type, - mask, - channel) + self.log.info("%s [%s] %s in %s expired", type, + ban.ban.id, + mask, + channel) # send unban msg unban = ircmsgs.mode(channel, (modedict[type], mask)) irc.queueMsg(unban) + # notify about bans soon to expire + for ban in self.managedBans.getExpired(600): + if ban.notified: + continue + id, channel, mask, type = ban.ban.id, ban.ban.channel, ban.ban.mask, ban.ban.type + notice = ircmsgs.notice('#test', "%s [%s] %s in %s will expire in a few minutes." \ + % (type, id, mask, channel)) + irc.queueMsg(notice) + ban.notified = True + def doLog(self, irc, channel, s): if not self.registryValue('enabled', channel): return diff --git a/Bantracker/test.py b/Bantracker/test.py index a8596b7..7631f82 100644 --- a/Bantracker/test.py +++ b/Bantracker/test.py @@ -390,5 +390,17 @@ class BantrackerTestCase(ChannelPluginTestCase): def testBanremoveTimeFormatBad(self): self.assertError('banremove 1 10 apples') + def testBanremoveNotice(self): + cb = self.getCallback() + self.feedBan('asd!*@*') + self.assertNotError('banremove 1 300') + cb.autoRemoveBans(self.irc) + msg = self.irc.takeMsg() + self.assertEqual(str(msg).strip(), + "NOTICE #test :ban [1] asd!*@* in #test will expire in a few minutes.") + # don't send the notice again. + cb.autoRemoveBans(self.irc) + self.assertFalse(self.irc.takeMsg()) +