Added a fallback: if for some reason we don't have op's full hostmask,

revert to match by nick for send the review. This may be needed in the
future as operator's full hostmask aren't stored in the db.
This commit is contained in:
Elián Hanisch 2010-04-03 13:20:15 -03:00
parent 75bf9e209c
commit 44b2133f1c
2 changed files with 60 additions and 12 deletions

View File

@ -471,9 +471,14 @@ class Bantracker(callbacks.Plugin):
op = ircutils.nickFromHostmask(ban.who)
host = ircutils.hostFromHostmask(ban.who)
except:
# probably a ban restored by IRC server in a netsplit
# XXX see if something can be done about this
continue
if ircutils.isNick(ban.who, strictRfc=True):
# ok, op's nick, use it
op = ban.who
host = None
else:
# probably a ban restored by IRC server in a netsplit
# XXX see if something can be done about this
continue
if nickMatch(op, ignore):
# in the ignore list
continue
@ -505,10 +510,22 @@ class Bantracker(callbacks.Plugin):
if host in self.pendingReviews:
op = msg.nick
for nick, msg in self.pendingReviews[host]:
if op != nick:
if op != nick and not irc.isChannel(nick): # be extra careful
# correct nick in msg
msg = ircmsgs.privmsg(op, msg.args[1])
irc.queueMsg(msg)
del self.pendingReviews[host]
# check if we have any reviews by nick to send
if None in self.pendingReviews:
op = msg.nick
L = self.pendingReviews[None]
for i, v in enumerate(L):
nick, msg = v
if nickMatch(op, nick):
irc.queueMsg(msg)
del L[i]
if not L:
del self.pendingReviews[None]
def doLog(self, irc, channel, s):
if not self.registryValue('enabled', channel):
@ -1085,11 +1102,15 @@ class Bantracker(callbacks.Plugin):
def banReview(self, irc, msg, args):
"""Lists pending ban reviews."""
count = []
count = {}
for reviews in self.pendingReviews.itervalues():
count.append((reviews[0][0], len(reviews)))
total = sum([ x[1] for x in count ])
s = ' '.join([ '%s:%s' %pair for pair in count ])
for nick, msg in reviews:
try:
count[nick] += 1
except KeyError:
count[nick] = 1
total = sum(count.itervalues())
s = ' '.join([ '%s:%s' %pair for pair in count.iteritems() ])
s = 'Pending ban reviews (%s): %s' %(total, s)
irc.reply(s)

View File

@ -23,6 +23,7 @@ class BantrackerTestCase(ChannelPluginTestCase):
self.setDb()
pluginConf.request.ignore.set('*') # disable comments
pluginConf.request.forward.set('')
pluginConf.request.review.setValue(1.0/86400) # one second
def setDb(self):
import sqlite, os
@ -136,7 +137,6 @@ class BantrackerTestCase(ChannelPluginTestCase):
cb = self.getCallback()
self.feedBan('asd!*@*')
self.irc.takeMsg() # ignore comment request comment
pluginConf.request.review.setValue(1.0/86400) # one second
cb.reviewBans()
self.assertFalse(cb.pendingReviews)
print 'waiting 4 secs..'
@ -186,7 +186,6 @@ class BantrackerTestCase(ChannelPluginTestCase):
cb = self.getCallback()
self.feedBan('asd!*@*', prefix='bot!user@host.net')
self.irc.takeMsg() # ignore comment request comment
pluginConf.request.review.setValue(1.0/86400) # one second
cb.reviewBans(self.irc)
self.assertFalse(cb.pendingReviews)
print 'waiting 2 secs..'
@ -199,7 +198,35 @@ class BantrackerTestCase(ChannelPluginTestCase):
"NOTICE #channel :Hi, please somebody review the ban 'asd!*@*' set by bot on %s in #test, link: "\
"%s/bans.cgi?log=1" %(cb.bans['#test'][0].ascwhen, pluginConf.bansite()))
def testReviewNickFallback(self):
"""If for some reason we don't have ops full hostmask, revert to nick match. This may be
needed in the future as hostmasks aren't stored in the db."""
pluginConf.request.ignore.set('')
cb = self.getCallback()
self.feedBan('asd!*@*')
self.irc.takeMsg() # ignore comment request comment
cb.bans['#test'][0].who = 'op' # replace hostmask by nick
print 'waiting 2 secs..'
time.sleep(2)
cb.reviewBans()
# check is pending
self.assertTrue(cb.pendingReviews)
self.assertResponse('banreview', 'Pending ban reviews (1): op:1')
# send msg if a user with a matching nick says something
self.feedMsg('Hi!', frm='op_!user@host.net')
msg = self.irc.takeMsg()
self.assertEqual(msg, None)
self.feedMsg('Hi!', frm='op!user@host.net')
msg = self.irc.takeMsg()
self.assertEqual(str(msg).strip(),
"PRIVMSG op :Hi, please review the ban 'asd!*@*' that you set on %s in #test, link: "\
"%s/bans.cgi?log=1" %(cb.bans['#test'][0].ascwhen, pluginConf.bansite()))
# check not pending anymore
self.assertFalse(cb.pendingReviews)
def testPersistentCache(self):
"""Save pending reviews and when bans were last checked. This is needed for plugin
reloads"""
msg1 = ircmsgs.privmsg('nick', 'Hello World')
msg2 = ircmsgs.privmsg('nick', 'Hello World')
msg3 = ircmsgs.notice('#chan', 'Hello World')
@ -208,11 +235,11 @@ class BantrackerTestCase(ChannelPluginTestCase):
pr = cb.pendingReviews
pr['host.net'] = [('op', msg1), ('op', msg2), ('op_', msg3)]
pr['home.net'] = [('dude', msg4)]
self.assertResponse('banreview', 'Pending ban reviews (4): dude:1 op:3')
self.assertResponse('banreview', 'Pending ban reviews (4): op_:1 dude:1 op:2')
pr.close()
pr.clear()
pr.open()
self.assertResponse('banreview', 'Pending ban reviews (4): dude:1 op:3')
self.assertResponse('banreview', 'Pending ban reviews (4): op_:1 dude:1 op:2')
items = pr['host.net']
self.assertTrue(items[0][0] == 'op' and items[0][1] == msg1)
self.assertTrue(items[1][0] == 'op' and items[1][1] == msg2)