#!/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.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()