summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xfot.py74
-rw-r--r--modules/anidb.py24
-rw-r--r--modules/google_search.py26
-rw-r--r--modules/quotes.py7
-rw-r--r--modules/tracking.py14
-rw-r--r--modules/url_titles.py3
6 files changed, 95 insertions, 53 deletions
diff --git a/fot.py b/fot.py
index 021061a..c6e3e6c 100755
--- a/fot.py
+++ b/fot.py
@@ -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)