diff options
-rwxr-xr-x | fot.py | 74 | ||||
-rw-r--r-- | modules/anidb.py | 24 | ||||
-rw-r--r-- | modules/google_search.py | 26 | ||||
-rw-r--r-- | modules/quotes.py | 7 | ||||
-rw-r--r-- | modules/tracking.py | 14 | ||||
-rw-r--r-- | modules/url_titles.py | 3 |
6 files changed, 95 insertions, 53 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'): diff --git a/modules/anidb.py b/modules/anidb.py index 7a5a761..fbc9e11 100644 --- a/modules/anidb.py +++ b/modules/anidb.py @@ -21,6 +21,7 @@ class Module: def __init__(self, bot): self.irc = bot self.db = PgSQL.connect(database = 'fot') + self.irc.register_keyword('!anidb', self) def get_aid(self, msg, short = False): if msg.isdigit(): @@ -85,9 +86,11 @@ class Module: aid) def get_anime(self, msg): - short = msg.startswith('-s ') + short = msg.startswith('-s') if short: msg = ' '.join(msg.split()[1:]) + if not len(msg): + return 'Usage: !anidb [-s] search|aid' aid = self.get_aid(msg, short) if len(aid) == 1: return self.get_info(aid[0][0]) @@ -97,16 +100,15 @@ class Module: else: return 'anidb: %s%s' % ('%d/%d results: ' % (5, len(aid)) if len(aid) > 5 else '', ', '.join(['%s (%d)' % (x[1], x[0]) for x in aid[:5]])) - def __call__(self, nick, channel, msg): - if msg.startswith('!anidb'): - target = channel if not channel == self.irc.nickname else nick.split('!')[0] - args = msg.split() - if len(args) == 1: - self.irc.msg(target, 'Usage: !anidb [-s] search|aid') - return - info = self.get_anime(' '.join(args[1:])) - if info: - self.irc.msg(target, info) + def keyword(self, nick, channel, kw, msg): + target = channel if not channel == self.irc.nickname else nick.split('!')[0] + args = msg.split() + if len(args) == 0: + self.irc.msg(target, 'Usage: !anidb [-s] search|aid') + return + info = self.get_anime(' '.join(args)) + if info: + self.irc.msg(target, info) if __name__ == '__main__': import sys diff --git a/modules/google_search.py b/modules/google_search.py index 625cdf2..8af2c62 100644 --- a/modules/google_search.py +++ b/modules/google_search.py @@ -9,6 +9,7 @@ import urllib, urllib2, simplejson class Module: def __init__(self, bot): self.irc = bot + self.irc.register_keyword('!g', self) def search(self, s): try: @@ -24,19 +25,18 @@ class Module: return return (response['results'][0]['titleNoFormatting'], response['results'][0]['url']) - def __call__(self, nick, channel, msg): - if msg.startswith('!g'): - target = channel if not channel == self.irc.nickname else nick.split('!')[0] - args = msg.split() - if len(args) == 1: - self.irc.msg(target, 'Usage: !g search') - return - results = self.search(' '.join(args[1:])) - if results: - results = '\002%s\002 %s' % results - self.irc.msg(target, results.encode('utf-8')) - else: - self.irc.msg(target, 'No results.') + def keyword(self, nick, channel, kw, msg): + target = channel if not channel == self.irc.nickname else nick.split('!')[0] + args = msg.split() + if len(args) == 0: + self.irc.msg(target, 'Usage: !g search') + return + results = self.search(' '.join(args)) + if results: + results = '\002%s\002 %s' % results + self.irc.msg(target, results.encode('utf-8')) + else: + self.irc.msg(target, 'No results.') if __name__ == '__main__': import sys diff --git a/modules/quotes.py b/modules/quotes.py index a5060cd..772701c 100644 --- a/modules/quotes.py +++ b/modules/quotes.py @@ -201,13 +201,10 @@ quote_handler = IRCHandler() class Module: def __init__(self, bot): self.irc = bot + self.irc.register_keyword('!quote', self) - def __call__(self, nick, channel, msg): - if not msg.startswith('!quote'): - return + def keyword(self, nick, channel, kw, msg): args = msg.split(' ') - if msg.startswith('!quote'): - args = args[1:] cmd = args[0] if len(args) and len(args[0].strip()) else 'random' args = args[1:] diff --git a/modules/tracking.py b/modules/tracking.py index 94b8d86..aa33980 100644 --- a/modules/tracking.py +++ b/modules/tracking.py @@ -54,6 +54,7 @@ class Module: def __init__(self, bot): self.setup_db() self.irc = bot + self.irc.register_keyword('!track', self) self.tracking = [] self.lc = LoopingCall(self.lc_callback) if bot: @@ -200,21 +201,18 @@ class Module: session.close() return msg - def __call__(self, nick, channel, msg): - if not msg.startswith('!track'): - return - + def keyword(self, nick, channel, kw, msg): args = msg.split() - if len(args) < 2: + if len(args) < 1: self.irc.msg(channel if not channel == self.irc.nickname else nick.split('!')[0], 'Usage: !track (start|stop|status TRACKINGNO)|list') return - mode = args[1] + mode = args[0] if mode.lower() in ('start', 'stop', 'status'): - if len(args) != 3 and mode.lower() != 'status': + if len(args) != 2 and mode.lower() != 'status': self.irc.msg(channel if not channel == self.irc.nickname else nick.split('!')[0], 'Usage: !track (start|stop|status TRACKINGNO)|list') return - code = args[2] if len(args) == 3 else '' + code = args[1] if len(args) == 2 else '' msg = None if mode.lower() == 'start': diff --git a/modules/url_titles.py b/modules/url_titles.py index d5408ce..3172fac 100644 --- a/modules/url_titles.py +++ b/modules/url_titles.py @@ -15,6 +15,7 @@ class Module: def __init__(self, bot): self.irc = bot + self.irc.register_callback(self) def spotify(self, s): try: @@ -137,7 +138,7 @@ class Module: s += '\002[%d]\002 %s ' % (i+1, format_text(titles[i])) return s.strip() - def __call__(self, nick, channel, msg): + def privmsg(self, nick, channel, msg): titles = self.get_titles(msg) if titles: self.irc.msg(channel if not channel == self.irc.nickname else nick.split('!')[0], titles) |