2 changed files with 86 additions and 0 deletions
@ -0,0 +1,83 @@
|
||||
#!/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() |
Loading…
Reference in new issue