diff options
Diffstat (limited to 'fot.py')
-rwxr-xr-x | fot.py | 74 |
1 files changed, 59 insertions, 15 deletions
@@ -5,7 +5,7 @@ from twisted.internet import reactor, protocol from twisted.python import log from twisted.protocols.basic import LineReceiver -import os +import os, re from ConfigParser import ConfigParser @@ -24,8 +24,11 @@ modules = {} def load_modules(): print 'Loading modules...' - for m in config.options('modules'): - if config.getboolean('modules', m): + for s in config.sections(): + if not s.startswith('module/'): + continue + m = s[7:] + if not config.has_option(s, 'load') or config.getboolean(s, 'load'): try: if modules.has_key(m): reload(modules[m]) @@ -56,19 +59,48 @@ class Bot(irc.IRCClient): def __init__(self): bots.append(self) self.modules = {} + self.keywords = {} + self.msg_callbacks = [] + self.module_channels = None def __repr__(self): return '<Bot %s@%s>' % (self.nickname, self.factory.server) + def register_keyword(self, kw, mod): + if kw in self.keywords and self.keywords[kw] != mod: + raise Exception('Keyword "%s" already in use' % kw) + self.keywords[kw] = mod + + def register_callback(self, mod): + if not mod in self.msg_callbacks: + self.msg_callbacks.append(mod) + def apply_modules(self): # Call stop() for each module if neccessary (can't rely on __del__ here) for m in self.modules.itervalues(): if hasattr(m, 'stop'): m.stop() self.modules = {} + + server = self.factory.server.split('/', 1)[1] + channel_list = config.get(self.factory.server, 'channels').split() + self.module_channels = dict([(x, []) for x in channel_list]) 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) + if config.has_option('module/' + m, 'filter'): + mod_re = re.compile(config.get('module/' + m, 'filter')) + else: + mod_re = None + + mod = None # the module instance + + for channel in channel_list: + if not mod_re or mod_re.match('%s/%s' % (server, x)) != None: + if not mod: + mod = modules[m].Module(self) + self.module_channels[channel].append(mod) + + if mod: + self.modules[m] = mod def connectionMade(self): self.apply_modules() @@ -80,9 +112,27 @@ class Bot(irc.IRCClient): 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) + priv = channel == self.nickname + # filter out server stuff + if not priv and not '!' in nick: + return + + for mod in self.msg_callbacks: + if priv or mod in self.module_channels[channel]: + mod.privmsg(nick, channel, msg) + + msg = msg.split(None, 1) + if not len(msg): + return + elif len(msg) == 1: + kw, msg = msg[0], '' + else: + kw, msg = msg + + if kw in self.keywords: + mod = self.keywords[kw] + if priv or mod in self.module_channels[channel]: + mod.keyword(nick, channel, kw, msg) def kickedFrom(self, channel, kicker, message): self.join(channel) @@ -125,13 +175,7 @@ def start_server(server): or not config.has_option(server, 'channels') or config.has_option(server, 'disabled'): return - channels = [] - server_modules = [(m, config.get(server, m).split()) for m in modules.keys() if config.has_option(server, m)] - for channel in config.get(server, 'channels').split(): - channel_modules = [x[0] for x in server_modules if channel in x[1]] - channels.append('%s (%s)' % (channel, ' '.join(channel_modules) if len(channel_modules) else 'No modules')) - - print '%s: %s' % (server, ' '.join(channels) if len(channels) else 'No channels') + print '%s' % server factory = BotFactory(server, config.get(server, 'nickname')) if config.has_option(server, 'host6'): |