ask chanserv for op when needed

This commit is contained in:
Elián Hanisch 2012-08-18 11:27:50 -03:00
parent 5df52f12f8
commit 5002195005
2 changed files with 77 additions and 21 deletions

View File

@ -497,7 +497,7 @@ class Bantracker(callbacks.Plugin):
See '@list Bantracker' and '@help <command>' for commands"""
noIgnore = True
threaded = True
def __init__(self, irc):
self.__parent = super(Bantracker, self)
self.__parent.__init__(irc)
@ -509,6 +509,8 @@ class Bantracker(callbacks.Plugin):
self.nicks = {}
self.hosts = {}
self.bans = ircutils.IrcDict()
self.opped = defaultdict(lambda: False)
self.pendingBanremoval = {}
self.thread_timer = threading.Timer(10.0, dequeue, args=(self,irc))
self.thread_timer.start()
@ -536,7 +538,6 @@ class Bantracker(callbacks.Plugin):
schedule.addPeriodicEvent(lambda: self.autoRemoveBans(irc), 600,
name=self.name() + '_autoremove')
def get_nicks(self, irc):
self.hosts.clear()
for (channel, c) in irc.state.channels.iteritems():
@ -892,6 +893,21 @@ class Bantracker(callbacks.Plugin):
if not L:
del self.pendingReviews[None]
def getOp(self, irc, channel):
msg = ircmsgs.privmsg('Chanserv', "op %s %s" % (channel, irc.nick))
irc.queueMsg(msg)
def removeBans(self, irc, channel, modes, deop=False):
# send unban messages, with 4 modes max each.
maxModes = 4
if deop:
modes.append(('-o', irc.nick))
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)
def autoRemoveBans(self, irc):
modedict = { 'quiet': '-q', 'ban': '-b' }
unbandict = defaultdict(list)
@ -907,14 +923,12 @@ class Bantracker(callbacks.Plugin):
mask,
channel)
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)
if not self.opped[channel]:
self.pendingBanremoval[channel] = modes
self.getOp(irc, channel)
else:
self.removeBans(irc, channel, modes)
# notify about bans soon to expire
for ban in self.managedBans.getExpired(600):
@ -1076,29 +1090,37 @@ class Bantracker(callbacks.Plugin):
' '.join(msg.args[2:])))
modes = ircutils.separateModes(msg.args[1:])
for param in modes:
realname = ''
mode = param[0]
mask = ''
comment=None
if param[0] not in ("+b", "-b", "+q", "-q"):
# op stuff
if mode[1] == "o":
if ircutils.nickEqual(irc.nick, param[1]):
opped = self.opped[channel] = mode[0] == '+'
if opped == True:
# check if we have bans to remove
if channel in self.pendingBanremoval:
modes = self.pendingBanremoval.pop(channel)
self.removeBans(irc, channel, modes, deop=True)
continue
# channel mask stuff
realname = mask = ''
comment = None
if mode[1] not in "bq":
continue
mask = param[1]
if mask.startswith("$r:"):
mask = mask[3:]
realname = ' (realname)'
if param[0][1] == 'q':
if mode[1] == 'q':
mask = '%' + mask
if param[0] in ('+b', '+q'):
if mode[0] == '+':
comment = self.getHostFromBan(irc, msg, mask)
ban = self.doKickban(irc, channel, msg.prefix, mask + realname,
extra_comment=comment)
if False:
# FIXME ban autoremove should be set with a command, but I'm
# lazy.
self.managedBans.add(BanRemoval(ban, 1))
elif param[0] in ('-b', '-q'):
elif mode[0] == '-':
self.doUnban(irc,channel, msg.nick, mask + realname)
def getHostFromBan(self, irc, msg, mask):

View File

@ -124,6 +124,16 @@ class BantrackerTestCase(ChannelPluginTestCase):
self.irc.feedMsg(ban)
return ban
def op(self):
msg = ircmsgs.mode(self.channel, ('+o', self.irc.nick),
'Chanserv!service@service')
self.irc.feedMsg(msg)
def deop(self):
msg = ircmsgs.mode(self.channel, ('-o', self.irc.nick),
'Chanserv!service@service')
self.irc.feedMsg(msg)
def testComment(self):
self.assertResponse('comment 1', "I don't know any ban with id 1.")
self.feedBan('asd!*@*')
@ -396,6 +406,7 @@ class BantrackerTestCase(ChannelPluginTestCase):
self.assertEqual((1, '#test', 'troll', 'op'), fetch[0])
def testDuration(self):
self.op()
cb = self.getCallback()
self.feedBan('asd!*@*')
cb.autoRemoveBans(self.irc)
@ -418,6 +429,7 @@ class BantrackerTestCase(ChannelPluginTestCase):
self.assertRegexp('duration 1', 'never expires')
def testDurationMergeModes(self):
self.op()
cb = self.getCallback()
self.feedBan('asd!*@*')
self.feedBan('qwe!*@*')
@ -443,8 +455,8 @@ class BantrackerTestCase(ChannelPluginTestCase):
self.assertEqual(msg.args[1],
"test: 1 will be removed after 1 week and 3 days.")
def testDurationQuiet(self):
self.op()
cb = self.getCallback()
self.feedBan('asd!*@*', mode='q')
self.assertNotError('duration 1 1')
@ -556,4 +568,26 @@ class BantrackerTestCase(ChannelPluginTestCase):
self.assertNotError('duration 2 1d')
self.assertResponse('duration', "2 bans set to expire: 1 and 2")
def testOpTrack(self):
cb = self.getCallback()
self.assertEqual(cb.opped['#test'], False)
self.op()
self.assertEqual(cb.opped['#test'], True)
self.deop()
self.assertEqual(cb.opped['#test'], False)
def testOpDuration(self):
cb = self.getCallback()
self.feedBan('asd!*@*')
self.assertResponse('duration 1 1', "1 will be removed soon.")
print 'waiting 2 secs ...'
time.sleep(2)
cb.autoRemoveBans(self.irc)
msg = self.irc.takeMsg() # op msg
self.assertEqual(str(msg).strip(), "PRIVMSG Chanserv :op #test test")
self.op()
msg = self.irc.takeMsg() # unban msg
self.assertEqual(str(msg).strip(), "MODE #test -bo asd!*@* :test")