#!/usr/bin/env python from twisted.words.protocols import irc from twisted.internet import reactor, protocol from twisted.python import log from twisted.protocols.basic import LineReceiver from twisted.manhole.telnet import Shell import sys, os, traceback, StringIO, md5 from ConfigParser import ConfigParser import login config = ConfigParser() def load_config(): print 'Loading config...' config.read([os.path.expanduser('~/.fot')]) print 'Done!' load_config() modules = {} def load_modules(): print 'Loading modules...' for m in config.options('modules'): if config.getboolean('modules', m): try: if modules.has_key(m): reload(modules[m]) else: modules[m] = __import__('modules.' + m, globals(), locals(), ['Module']) mod = modules[m] print '%s by %s' % (mod.info['title'], mod.info['author']) del mod except: print 'Failed to load', m raise else: print 'Not loading', m print 'Done!' load_modules() bots = [] def refresh_modules(): print 'Re-applying modules to bots...' for bot in bots: bot.apply_modules() print 'Done!' class Bot(irc.IRCClient): def __init__(self): bots.append(self) def __del__(self): bots.remove(self) def __repr__(self): return '' % (self.nickname, self.factory.server) def apply_modules(self): self.modules = {} for m in modules.keys(): if config.has_option(self.factory.server, m) and config.get(self.factory.server, m).strip(): self.modules[m] = modules[m].Module(self) def connectionMade(self): self.apply_modules() self.nickname = config.get(self.factory.server, 'nickname') irc.IRCClient.connectionMade(self) def signedOn(self): for chan in config.get(self.factory.server, 'channels').split(' '): self.join(chan) def privmsg(self, nick, channel, msg): for m in self.modules.keys(): if (config.has_option(self.factory.server, m) and channel in config.get(self.factory.server, m)) or (channel == self.nickname and nick.split('!')[0] != self.nickname): self.modules[m](nick, channel, msg) def kickedFrom(self, channel, kicker, message): self.join(channel) class BotFactory(protocol.ReconnectingClientFactory): protocol = Bot def __init__(self, server, nickname): self.server = server self.nickname = nickname def buildProtocol(self, addr): self.resetDelay() return protocol.ReconnectingClientFactory.buildProtocol(self, addr) def clientConnectionFailed(self, connector, reason): print 'Connection failed: ', reason protocol.ReconnectingClientFactory.clientConnectionFailed(self, connector, reason) def clientConnectionLost(self, connector, reason): print 'Connection lost: ', reason protocol.ReconnectingClientFactory.clientConnectionLost(self, connector, reason) print 'Starting per-network instances...' for server in config.sections(): if not config.has_option(server,'host') or not config.has_option(server, 'port') or not config.has_option(server, 'channels') or config.has_option(server, 'disabled'): continue channels = [] ms = [(m, config.get(server, m)) for m in modules.keys() if config.has_option(server, m)] for c in config.get(server, 'channels').split(' '): ch = [x[0] for x in ms if c in x[1]] channels.append('%s (%s)' % (c, ' '.join(ch))) print '%s: %s' % (server, ' '.join(channels)) del channels, ms, c, ch, x factory = BotFactory(server, config.get(server, 'nickname')) reactor.connectTCP(config.get(server, 'host'), config.getint(server, 'port'), factory) # TODO: Fix user/pass loginfactory = login.getManholeFactory(globals(), user = 'pass') reactor.listenTCP(3333, loginfactory) reactor.run()