Simple bot to gline or zline IRC spammers.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

85 lines
3.0 KiB

#!/usr/bin/env python3
import irc.bot
import irc.strings
import configparser
from expiringdict import ExpiringDict
configfile = 'spamkicker.ini'
class BotConfig:
def __init__(self, config):
general = config['general']
connections = []
for connection in general['connections'].split():
connections.append((config[connection]['server'], int(config[connection]['port'])))
self.server_list=connections
self.nickname=general['nick']
self.realname=general['real']
self.honeypots=[x.strip() for x in general['honeypots'].split(',')]
self.announce=[x.strip() for x in general['announce'].split(',')]
self.password=general['password']
self.ban_type=general['ban_type']
self.ban_duration=general['ban_duration']
def __repr__(self):
return "BotConfig(server_list={},nickname='{}',realname='{}',honeypots={},announce={},password='{}',ban_type='{}',ban_duration='{}')".format(self.server_list, self.nickname, self.realname, self.honeypots, self.announce, self.password, self.ban_type, self.ban_duration)
class SpamKickerBot(irc.bot.SingleServerIRCBot):
def __init__(self, botconfig):
self.botconfig = botconfig
irc.bot.SingleServerIRCBot.__init__(self, botconfig.server_list, botconfig.nickname, botconfig.realname)
self.connection.set_keepalive(interval=120)
self.spammers = ExpiringDict(max_age_seconds=300, max_len=100)
def on_nicknameinuse(self, c, e):
c.nick(c.get_nickname() + "_")
def on_welcome(self, c, e):
for channel in self.botconfig.honeypots:
c.join(channel)
for channel in self.botconfig.announce:
c.join(channel)
c.send_raw("OPER {} {}".format(c.get_nickname(), self.botconfig.password))
def on_privmsg(self, c, e):
self.flag_spammer(c, e.source)
def on_pubmsg(self, c, e):
if e.target in self.botconfig.honeypots:
self.flag_spammer(c, e.source)
def flag_spammer(self, c, source):
if source in self.spammers:
print("Spammer already flagged")
else:
self.spammers[source] = 1
print("Spammer flagged: {}".format(source.nick))
for target in self.botconfig.announce:
c.privmsg(target, 'Spammer identified: {} ({})'.format(source.nick, source.userhost))
if self.botconfig.ban_type == 'GLINE':
spec = source.userhost
elif self.botconfig.ban_type == 'ZLINE':
spec = source.host
else:
spec = source.userhost # Just in case, right?
command = ' '.join(filter(None, [self.botconfig.ban_type, spec, self.botconfig.ban_duration, ':SpamKicker']))
print(command)
c.send_raw(command)
def main():
config = configparser.ConfigParser()
config.read(configfile)
botconfig = BotConfig(config)
bot = SpamKickerBot(botconfig)
bot.start()
if __name__ == "__main__":
main()