mirror of
https://github.com/ncoevoet/ChanTracker.git
synced 2025-04-27 21:41:09 -05:00
added remove command ( fpart ), fixed ( i guess ) few bugs related to unability to match affected users by a mode
This commit is contained in:
parent
455d955aa7
commit
30ac32bc61
93
plugin.py
93
plugin.py
@ -47,6 +47,10 @@ import re
|
|||||||
import sqlite3
|
import sqlite3
|
||||||
import collections
|
import collections
|
||||||
|
|
||||||
|
#due to more kind of pattern checked, increase size
|
||||||
|
|
||||||
|
ircutils._hostmaskPatternEqualCache = utils.structures.CacheDict(4000)
|
||||||
|
|
||||||
def matchHostmask (pattern,n):
|
def matchHostmask (pattern,n):
|
||||||
# return the machted pattern for Nick
|
# return the machted pattern for Nick
|
||||||
if n.prefix == None or not ircutils.isUserHostmask(n.prefix):
|
if n.prefix == None or not ircutils.isUserHostmask(n.prefix):
|
||||||
@ -204,7 +208,9 @@ def getBestPattern (n):
|
|||||||
ident = ircutils.userFromHostmask(n.prefix)
|
ident = ircutils.userFromHostmask(n.prefix)
|
||||||
if host.find('gateway/') != -1 and host.find('/x-') != -1:
|
if host.find('gateway/') != -1 and host.find('/x-') != -1:
|
||||||
host = '%s/*' % host.split('/x-')[0]
|
host = '%s/*' % host.split('/x-')[0]
|
||||||
results.append('*!%s@%s' % (ident,host))
|
k = '*!%s@%s' % (ident,host)
|
||||||
|
if not k in results:
|
||||||
|
results.append(k)
|
||||||
if n.account:
|
if n.account:
|
||||||
results.append('$a:%s' % n.account)
|
results.append('$a:%s' % n.account)
|
||||||
if n.realname:
|
if n.realname:
|
||||||
@ -299,9 +305,9 @@ class Ircd (object):
|
|||||||
object.__init__(self)
|
object.__init__(self)
|
||||||
self.irc = irc
|
self.irc = irc
|
||||||
self.name = irc.network
|
self.name = irc.network
|
||||||
self.channels = {}
|
self.channels = ircutils.IrcDict()
|
||||||
self.nicks = {}
|
self.nicks = ircutils.IrcDict()
|
||||||
self.caps = {}
|
self.caps = ircutils.IrcDict()
|
||||||
# contains IrcMsg, kicks, modes, etc
|
# contains IrcMsg, kicks, modes, etc
|
||||||
self.queue = utils.structures.smallqueue()
|
self.queue = utils.structures.smallqueue()
|
||||||
# contains less important IrcMsgs ( sync, logChannel )
|
# contains less important IrcMsgs ( sync, logChannel )
|
||||||
@ -750,13 +756,13 @@ class Chan (object):
|
|||||||
object.__init__(self)
|
object.__init__(self)
|
||||||
self.ircd = ircd
|
self.ircd = ircd
|
||||||
self.name = name
|
self.name = name
|
||||||
self._lists = {}
|
self._lists = ircutils.IrcDict()
|
||||||
# queue contains (mode,valueOrNone) - ircutils.joinModes
|
# queue contains (mode,valueOrNone) - ircutils.joinModes
|
||||||
self.queue = utils.structures.smallqueue()
|
self.queue = utils.structures.smallqueue()
|
||||||
# contains [modevalue] = [mode,value,seconds,prefix]
|
# contains [modevalue] = [mode,value,seconds,prefix]
|
||||||
self.update = {}
|
self.update = ircutils.IrcDict()
|
||||||
# contains [modevalue] = [mode,value,message,prefix]
|
# contains [modevalue] = [mode,value,message,prefix]
|
||||||
self.mark = {}
|
self.mark = ircutils.IrcDict()
|
||||||
# contains IrcMsg ( mostly kick / fpart )
|
# contains IrcMsg ( mostly kick / fpart )
|
||||||
self.action = utils.structures.smallqueue()
|
self.action = utils.structures.smallqueue()
|
||||||
# looking for eqIb list ends
|
# looking for eqIb list ends
|
||||||
@ -766,9 +772,9 @@ class Chan (object):
|
|||||||
self.deopAsked = False
|
self.deopAsked = False
|
||||||
self.deopPending = False
|
self.deopPending = False
|
||||||
# now stuff here is related to protection
|
# now stuff here is related to protection
|
||||||
self.spam = {}
|
self.spam = ircutils.IrcDict()
|
||||||
self.repeatLogs = {}
|
self.repeatLogs = ircutils.IrcDict()
|
||||||
self.massPattern = {}
|
self.massPattern = ircutils.IrcDict()
|
||||||
|
|
||||||
def isWrong (self,pattern):
|
def isWrong (self,pattern):
|
||||||
if 'bad' in self.spam:
|
if 'bad' in self.spam:
|
||||||
@ -782,7 +788,7 @@ class Chan (object):
|
|||||||
|
|
||||||
def getItemsFor (self,mode):
|
def getItemsFor (self,mode):
|
||||||
if not mode in self._lists:
|
if not mode in self._lists:
|
||||||
self._lists[mode] = {}
|
self._lists[mode] = ircutils.IrcDict()
|
||||||
return self._lists[mode]
|
return self._lists[mode]
|
||||||
|
|
||||||
def addItem (self,mode,value,by,when,db):
|
def addItem (self,mode,value,by,when,db):
|
||||||
@ -911,11 +917,11 @@ class Nick (object):
|
|||||||
# [float(timestamp),target,message]
|
# [float(timestamp),target,message]
|
||||||
|
|
||||||
def setPrefix (self,prefix):
|
def setPrefix (self,prefix):
|
||||||
if not prefix == self.prefix:
|
if prefix != None and not prefix == self.prefix:
|
||||||
self.prefix = prefix
|
self.prefix = prefix
|
||||||
if self.prefix:
|
if self.prefix:
|
||||||
|
# compute ip
|
||||||
matchHostmask(self.prefix,self)
|
matchHostmask(self.prefix,self)
|
||||||
getBestPattern(self)
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def setIp (self,ip):
|
def setIp (self,ip):
|
||||||
@ -939,13 +945,13 @@ class Nick (object):
|
|||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
ip = self.ip
|
ip = self.ip
|
||||||
if ip == None:
|
if ip is None:
|
||||||
ip = ''
|
ip = ''
|
||||||
account = self.account
|
account = self.account
|
||||||
if account == None:
|
if account is None:
|
||||||
account = ''
|
account = ''
|
||||||
realname = self.realname
|
realname = self.realname
|
||||||
if realname == None:
|
if realname is None:
|
||||||
realname = ''
|
realname = ''
|
||||||
return '%s ip:%s $a:%s $r:%s' % (self.prefix,ip,account,realname)
|
return '%s ip:%s $a:%s $r:%s' % (self.prefix,ip,account,realname)
|
||||||
|
|
||||||
@ -1019,7 +1025,7 @@ class ChanTracker(callbacks.Plugin,plugins.ChannelDBHandler):
|
|||||||
plugins.ChannelDBHandler.__init__(self)
|
plugins.ChannelDBHandler.__init__(self)
|
||||||
self.lastTickle = time.time()-self.registryValue('pool')
|
self.lastTickle = time.time()-self.registryValue('pool')
|
||||||
self.forceTickle = True
|
self.forceTickle = True
|
||||||
self._ircs = {}
|
self._ircs = ircutils.IrcDict()
|
||||||
self.getIrc(irc)
|
self.getIrc(irc)
|
||||||
self.recaps = re.compile("[A-Z]")
|
self.recaps = re.compile("[A-Z]")
|
||||||
|
|
||||||
@ -1142,7 +1148,7 @@ class ChanTracker(callbacks.Plugin,plugins.ChannelDBHandler):
|
|||||||
else:
|
else:
|
||||||
results = i.pending(irc,channel,mode,msg.prefix,pattern,self.getDb(irc.network))
|
results = i.pending(irc,channel,mode,msg.prefix,pattern,self.getDb(irc.network))
|
||||||
if len(results):
|
if len(results):
|
||||||
irc.reply(', '.join(results), private=True)
|
irc.reply(' '.join(results), private=True)
|
||||||
else:
|
else:
|
||||||
irc.error('no results')
|
irc.error('no results')
|
||||||
pending = wrap(pending,['op',additional('letter'),optional('hostmask')])
|
pending = wrap(pending,['op',additional('letter'),optional('hostmask')])
|
||||||
@ -1271,6 +1277,19 @@ class ChanTracker(callbacks.Plugin,plugins.ChannelDBHandler):
|
|||||||
irc.error('unknown patterns, already removed or unsupported mode')
|
irc.error('unknown patterns, already removed or unsupported mode')
|
||||||
ue = wrap(ue,['op',many('something')])
|
ue = wrap(ue,['op',many('something')])
|
||||||
|
|
||||||
|
def remove (self,irc,msg,args,channel,nick,reason):
|
||||||
|
"""[<channel>] <nick> [<reason>]
|
||||||
|
|
||||||
|
force a part on <nick> with <reason> if provided"""
|
||||||
|
chan = self.getChan(irc,channel)
|
||||||
|
if not reason:
|
||||||
|
reason = msg.nick
|
||||||
|
chan.action.enqueue(ircmsgs.IrcMsg('REMOVE %s %s :%s' % (channel,nick,reason)))
|
||||||
|
irc.replySuccess()
|
||||||
|
self.forceTickle = True
|
||||||
|
self._tickle(irc)
|
||||||
|
remove = wrap(remove,['op','nickInChannel',additional('text')])
|
||||||
|
|
||||||
def check (self,irc,msg,args,channel,pattern):
|
def check (self,irc,msg,args,channel,pattern):
|
||||||
"""[<channel>] <pattern>
|
"""[<channel>] <pattern>
|
||||||
|
|
||||||
@ -1283,9 +1302,11 @@ class ChanTracker(callbacks.Plugin,plugins.ChannelDBHandler):
|
|||||||
n = self.getNick(irc,nick)
|
n = self.getNick(irc,nick)
|
||||||
m = match(pattern,n)
|
m = match(pattern,n)
|
||||||
if m:
|
if m:
|
||||||
results.append(nick)
|
results.append('[%s - %s]' % (nick,m))
|
||||||
|
else:
|
||||||
|
log.debug('ChanServ.check unknown %s' % nick)
|
||||||
if len(results):
|
if len(results):
|
||||||
irc.reply(', '.join(results))
|
irc.reply(' '.join(results))
|
||||||
else:
|
else:
|
||||||
irc.error('nobody will be affected')
|
irc.error('nobody will be affected')
|
||||||
else:
|
else:
|
||||||
@ -1296,10 +1317,9 @@ class ChanTracker(callbacks.Plugin,plugins.ChannelDBHandler):
|
|||||||
"""<nick|hostmask>
|
"""<nick|hostmask>
|
||||||
|
|
||||||
returns a list of hostmask's pattern, best first, mostly used for debug"""
|
returns a list of hostmask's pattern, best first, mostly used for debug"""
|
||||||
# returns patterns for a given nick
|
|
||||||
i = self.getIrc(irc)
|
i = self.getIrc(irc)
|
||||||
if prefix in i.nicks:
|
if prefix in i.nicks:
|
||||||
irc.reply(', '.join(getBestPattern(self.getNick(irc,prefix))))
|
irc.reply(' '.join(getBestPattern(self.getNick(irc,prefix))))
|
||||||
else:
|
else:
|
||||||
n = Nick(0)
|
n = Nick(0)
|
||||||
if prefix.find('#') != -1:
|
if prefix.find('#') != -1:
|
||||||
@ -1311,7 +1331,7 @@ class ChanTracker(callbacks.Plugin,plugins.ChannelDBHandler):
|
|||||||
else:
|
else:
|
||||||
n.setPrefix(prefix)
|
n.setPrefix(prefix)
|
||||||
if ircutils.isUserHostmask(prefix):
|
if ircutils.isUserHostmask(prefix):
|
||||||
irc.reply(', '.join(getBestPattern(n)))
|
irc.reply(' '.join(getBestPattern(n)))
|
||||||
return
|
return
|
||||||
irc.error('nick not found or wrong hostmask given')
|
irc.error('nick not found or wrong hostmask given')
|
||||||
getmask = wrap(getmask,['owner','text'])
|
getmask = wrap(getmask,['owner','text'])
|
||||||
@ -1412,12 +1432,12 @@ class ChanTracker(callbacks.Plugin,plugins.ChannelDBHandler):
|
|||||||
|
|
||||||
def getIrc (self,irc):
|
def getIrc (self,irc):
|
||||||
# init irc db
|
# init irc db
|
||||||
if not irc in self._ircs:
|
if not irc.network in self._ircs:
|
||||||
i = self._ircs[irc] = Ircd (irc,self.registryValue('logsSize'))
|
i = self._ircs[irc.network] = Ircd (irc,self.registryValue('logsSize'))
|
||||||
# restore CAP, if needed, needed to track account (account-notify) ang gecos (extended-join)
|
# restore CAP, if needed, needed to track account (account-notify) ang gecos (extended-join)
|
||||||
# see config of this plugin
|
# see config of this plugin
|
||||||
irc.queueMsg(ircmsgs.IrcMsg('CAP LS'))
|
irc.queueMsg(ircmsgs.IrcMsg('CAP LS'))
|
||||||
return self._ircs[irc]
|
return self._ircs[irc.network]
|
||||||
|
|
||||||
def getChan (self,irc,channel):
|
def getChan (self,irc,channel):
|
||||||
i = self.getIrc(irc)
|
i = self.getIrc(irc)
|
||||||
@ -1434,15 +1454,12 @@ class ChanTracker(callbacks.Plugin,plugins.ChannelDBHandler):
|
|||||||
elif len(modesToAsk):
|
elif len(modesToAsk):
|
||||||
i.lowQueue.enqueue(ircmsgs.IrcMsg('MODE %s %s' % (channel,modesToAsk)))
|
i.lowQueue.enqueue(ircmsgs.IrcMsg('MODE %s %s' % (channel,modesToAsk)))
|
||||||
# schedule that for later
|
# schedule that for later
|
||||||
def doLater():
|
|
||||||
# prevent the bot to disconnect itself is server takes too much time to answer
|
# prevent the bot to disconnect itself is server takes too much time to answer
|
||||||
i.lowQueue.enqueue(ircmsgs.ping(channel))
|
i.lowQueue.enqueue(ircmsgs.ping(channel))
|
||||||
# loads extended who
|
# loads extended who
|
||||||
i.lowQueue.enqueue(ircmsgs.IrcMsg('WHO ' + channel +' %tnuhiar,42')) # some ircd may not like this
|
i.lowQueue.enqueue(ircmsgs.IrcMsg('WHO ' + channel +' %tnuhiar,42')) # some ircd may not like this
|
||||||
# fallback, TODO maybe uneeded as supybot do it by itself on join, but necessary on plugin reload ...
|
# fallback, TODO maybe uneeded as supybot do it by itself on join, but necessary on plugin reload ...
|
||||||
i.lowQueue.enqueue(ircmsgs.IrcMsg('WHO %s' % channel))
|
i.lowQueue.enqueue(ircmsgs.IrcMsg('WHO %s' % channel))
|
||||||
schedule.addEvent(doLater,time.time()+30)
|
|
||||||
|
|
||||||
return i.getChan (irc,channel)
|
return i.getChan (irc,channel)
|
||||||
|
|
||||||
def getNick (self,irc,nick):
|
def getNick (self,irc,nick):
|
||||||
@ -1501,9 +1518,6 @@ class ChanTracker(callbacks.Plugin,plugins.ChannelDBHandler):
|
|||||||
def doPing (self,irc,msg):
|
def doPing (self,irc,msg):
|
||||||
self._tickle(irc)
|
self._tickle(irc)
|
||||||
|
|
||||||
def die(self):
|
|
||||||
self._ircs = {}
|
|
||||||
|
|
||||||
def _sendModes (self, irc, modes, f):
|
def _sendModes (self, irc, modes, f):
|
||||||
numModes = irc.state.supported.get('modes', 1)
|
numModes = irc.state.supported.get('modes', 1)
|
||||||
ircd = self.getIrc(irc)
|
ircd = self.getIrc(irc)
|
||||||
@ -1613,7 +1627,7 @@ class ChanTracker(callbacks.Plugin,plugins.ChannelDBHandler):
|
|||||||
index = 0
|
index = 0
|
||||||
for k in L:
|
for k in L:
|
||||||
(m,value,expire,prefix) = L[index]
|
(m,value,expire,prefix) = L[index]
|
||||||
if expire == -1 or expire == None:
|
if expire == -1 or expire is None:
|
||||||
if overexpire != expire:
|
if overexpire != expire:
|
||||||
chan.update['%s%s' % (m,value)] = [m,value,overexpire,irc.prefix]
|
chan.update['%s%s' % (m,value)] = [m,value,overexpire,irc.prefix]
|
||||||
index = index + 1
|
index = index + 1
|
||||||
@ -2079,6 +2093,7 @@ class ChanTracker(callbacks.Plugin,plugins.ChannelDBHandler):
|
|||||||
return
|
return
|
||||||
if targets == irc.nick:
|
if targets == irc.nick:
|
||||||
b = False
|
b = False
|
||||||
|
# todo keep this code commented until request to implement it
|
||||||
#b = False
|
#b = False
|
||||||
#if text == 'You are not authorized to perform this operation.':
|
#if text == 'You are not authorized to perform this operation.':
|
||||||
#b = True
|
#b = True
|
||||||
@ -2499,7 +2514,7 @@ class ChanTracker(callbacks.Plugin,plugins.ChannelDBHandler):
|
|||||||
L = []
|
L = []
|
||||||
for user in irc.state.channels[self.registryValue('logChannel',channel=channel)].users:
|
for user in irc.state.channels[self.registryValue('logChannel',channel=channel)].users:
|
||||||
L.append(user)
|
L.append(user)
|
||||||
self._logChan(irc,channel,'[%s] %s : %s' % (channel,info,', '.join(L)))
|
self._logChan(irc,channel,'[%s] %s : %s' % (channel,info,' '.join(L)))
|
||||||
self._tickle(irc)
|
self._tickle(irc)
|
||||||
|
|
||||||
# protection features
|
# protection features
|
||||||
@ -2620,8 +2635,16 @@ class ChanTracker(callbacks.Plugin,plugins.ChannelDBHandler):
|
|||||||
jacc = n / float(len(sa) + len(sb) - n)
|
jacc = n / float(len(sa) + len(sb) - n)
|
||||||
return jacc
|
return jacc
|
||||||
|
|
||||||
|
def die(self):
|
||||||
|
log.debug('ChanTracker die')
|
||||||
|
self._ircs = ircutils.IrcDict()
|
||||||
|
|
||||||
def doError (self,irc,msg):
|
def doError (self,irc,msg):
|
||||||
self._ircs = {}
|
log.debug('ChanTracker doError: %s' % irc.network)
|
||||||
|
if irc.network in self._ircs:
|
||||||
|
del self._ircs[irc]
|
||||||
|
else:
|
||||||
|
self._ircs = ircutils.IrcDict()
|
||||||
|
|
||||||
|
|
||||||
Class = ChanTracker
|
Class = ChanTracker
|
||||||
|
Loading…
x
Reference in New Issue
Block a user