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.
83 lines
2.9 KiB
83 lines
2.9 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.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()
|
|
|