diff --git a/Bantracker/plugin.py b/Bantracker/plugin.py index 9b8de36..fb4bd1b 100644 --- a/Bantracker/plugin.py +++ b/Bantracker/plugin.py @@ -55,6 +55,7 @@ import supybot.ircdb as ircdb import supybot.schedule as schedule import supybot.utils as utils from fnmatch import fnmatch +from collections import defaultdict import sqlite import pytz import cPickle @@ -869,6 +870,7 @@ class Bantracker(callbacks.Plugin): def autoRemoveBans(self, irc): modedict = { 'quiet': '-q', 'ban': '-b' } + unbandict = defaultdict(list) for ban in self.managedBans.popExpired(): channel, mask, type = ban.ban.channel, ban.ban.mask, ban.ban.type if not self.registryValue('autoremove', channel): @@ -880,9 +882,15 @@ class Bantracker(callbacks.Plugin): ban.ban.id, mask, channel) - # send unban msg - unban = ircmsgs.mode(channel, (modedict[type], mask)) - irc.queueMsg(unban) + unbandict[channel].append((modedict[type], mask)) + # send unban messages, with 4 modes max each. + maxModes = 4 + for channel, modes in unbandict.iteritems(): + for i in range(len(modes) / maxModes + 1): + L = modes[i * maxModes : (i + 1) * maxModes] + if L: + msg = ircmsgs.mode(channel, ircutils.joinModes(L)) + irc.queueMsg(msg) # notify about bans soon to expire for ban in self.managedBans.getExpired(600): diff --git a/Bantracker/test.py b/Bantracker/test.py index bbbeb11..4dcf164 100644 --- a/Bantracker/test.py +++ b/Bantracker/test.py @@ -361,6 +361,29 @@ class BantrackerTestCase(ChannelPluginTestCase): msg = self.irc.takeMsg() # unban msg self.assertEqual(str(msg).strip(), "MODE #test -b :asd!*@*") + def testBanremoveMergeModes(self): + cb = self.getCallback() + self.feedBan('asd!*@*') + self.feedBan('qwe!*@*') + self.feedBan('zxc!*@*') + self.feedBan('asd!*@*', mode='q') + self.feedBan('qwe!*@*', mode='q') + self.feedBan('zxc!*@*', mode='q') + self.assertNotError('banremove 1 0') + self.assertNotError('banremove 2 0') + self.assertNotError('banremove 3 0') + self.assertNotError('banremove 4 0') + self.assertNotError('banremove 5 0') + self.assertNotError('banremove 6 0') + print 'waiting 1 secs ...' + time.sleep(1) + cb.autoRemoveBans(self.irc) + msg = self.irc.takeMsg() # unban msg + self.assertEqual(str(msg).strip(), + "MODE #test -qqqb zxc!*@* qwe!*@* asd!*@* :zxc!*@*") + msg = self.irc.takeMsg() + self.assertEqual(str(msg).strip(), "MODE #test -bb qwe!*@* :asd!*@*") + def testBanremoveQuiet(self): cb = self.getCallback() self.feedBan('asd!*@*', mode='q')