diff --git a/src/bot.py b/src/bot.py index fcbc0af15..7a26e0596 100755 --- a/src/bot.py +++ b/src/bot.py @@ -38,74 +38,57 @@ from fix import * import sys import time import getopt -#import pprint import conf +import debug import world +import irclib +import drivers +import ircmsgs +import privmsgs +import schedule sys.path.append(conf.pluginDir) world.startedAt = time.time() -class ConfigurationDict(dict): - def __init__(self, L=None): - if L is not None: - L = [(key.lower(), value) for (key, value) in L] - dict.__init__(self, L) +class ConfigAfter376(irclib.IrcCallback): + public = False + def __init__(self, commands): + self.commands = commands - def __setitem__(self, key, value): - dict.__setitem__(self, key.lower(), value) + def do376(self, irc, msg): + #debug.printf('Firing ConfigAfter376 messages') + for command in self.commands: + #debug.printf(irc.nick) + #debug.printf(command) + msg = ircmsgs.privmsg(irc.nick, command, prefix=irc.prefix) + irc.queueMsg(msg) - def __getitem__(self, key): - try: - return dict.__getitem__(self, key.lower()) - except KeyError: - return '' + do377 = do376 - def __contains__(self, key): - return dict.__contains__(self, key.lower()) - - - -def handleConfigFile(filename): - import debug - import irclib - import ircmsgs - import drivers - import ircutils - import privmsgs - class ConfigAfter376(irclib.IrcCallback): - public = False - def __init__(self, commands): - self.commands = commands - - def do376(self, irc, msg): - #debug.printf('Firing ConfigAfter376 messages') - for command in self.commands: - #debug.printf(irc.nick) - #debug.printf(command) - msg = ircmsgs.privmsg(irc.nick, command, prefix=irc.prefix) - irc.queueMsg(msg) - - do377 = do376 +def handleConfigFile(): nick = conf.config['nick'] user = conf.config['user'] ident = conf.config['ident'] - prefix = ircutils.joinHostmask(nick, ident, 'host') password = conf.config['password'] irc = irclib.Irc(nick, user, ident, password) for Class in privmsgs.standardPrivmsgModules: - irc.addCallback(Class()) - world.startup = True - for line in conf.config['onStart']: - irc.feedMsg(ircmsgs.privmsg(irc.nick, line, prefix=prefix)) - irc.reset() - world.startup = False + callback = Class() + if hasattr(callback, 'configure'): + fakeIrc = callback.configure() + # This is mostly a hack to make sure the load command works. + for cb in fakeIrc.callbacks: # Should most always be empty. + irc.addCallback(cb) + irc.addCallback(callback) irc.addCallback(ConfigAfter376(conf.config['afterConnect'])) - driver = drivers.newDriver(conf.config['server'], irc) + drivers.newDriver(conf.config['server'], irc) def main(): (optlist, filenames) = getopt.getopt(sys.argv[1:], 'Opc:') + if len(filenames) != 1: + conf.reportConfigError('Command line', 'No configuration file given.') + for (option, argument) in optlist: if option == '-c': myLocals = {} @@ -117,12 +100,9 @@ def main(): setattr(conf, key, value) else: print 'Unexpected argument %s; ignoring.' % option - import debug - import drivers - import schedule - for filename in filenames: - conf.processConfig(filename) - handleConfigFile(filename) + filename = filenames[0] + conf.processConfig(filename) + handleConfigFile() schedule.addPeriodicEvent(world.upkeep, 300) try: while world.ircs: diff --git a/src/callbacks.py b/src/callbacks.py index a9d6266dd..2cbcdd6e1 100644 --- a/src/callbacks.py +++ b/src/callbacks.py @@ -51,6 +51,7 @@ import sre_constants from cStringIO import StringIO import conf +import utils import world import ircdb import irclib @@ -366,6 +367,29 @@ class Privmsg(irclib.IrcCallback): self.rateLimiter = RateLimiter() self.Proxy = IrcObjectProxy + def configure(self): + nick = conf.config['nick'] + user = conf.config['user'] + ident = conf.config['ident'] + fakeIrc = irclib.Irc(nick, user, ident) + fakeIrc.error = lambda _, s: None #debug.printf(s) + fakeIrc.reply = lambda _, s: None #debug.printf(s) + fakeIrc.findCallback = lambda *args: None + for args in conf.config['onStart']: + args = args[:] + command = args.pop(0) + if self.isCommand(command): + #debug.printf('%s: %r' % (command, args)) + method = getattr(self, command) + line = ' '.join(map(utils.dqrepr, args)) + msg = ircmsgs.privmsg(fakeIrc.nick, line, fakeIrc.prefix) + try: + world.startup = True + method(fakeIrc, msg, args) + finally: + world.startup = False + return fakeIrc + def __call__(self, irc, msg): irclib.IrcCallback.__call__(self, irc, msg) # Now, if there's anything in the rateLimiter... @@ -395,7 +419,7 @@ class Privmsg(irclib.IrcCallback): if self.threaded: thread = CommandThread(f, irc, msg, args) thread.start() - debug.printf('Spawned new thread: %s' % thread) + #debug.printf('Spawned new thread: %s' % thread) else: # Exceptions aren't caught here because IrcObjectProxy.finalEval # catches them and does The Right Thing. @@ -412,7 +436,7 @@ class Privmsg(irclib.IrcCallback): if s: recipient = msg.args[0] if ircdb.checkIgnored(msg.prefix, recipient): - debug.printf('Privmsg.doPrivmsg: ignoringi %s.' % recipient) + debug.printf('Privmsg.doPrivmsg: ignoring %s.' % recipient) return m = self._r.match(s) if m and self.isCommand(canonicalName(m.group(1))): @@ -462,6 +486,7 @@ class PrivmsgRegexp(Privmsg): """ threaded = False # Again, like Privmsg... flags = re.I + onlyFirstMatch = False def __init__(self): Privmsg.__init__(self) self.Proxy = IrcObjectProxyRegexp @@ -479,6 +504,7 @@ class PrivmsgRegexp(Privmsg): (self.__class__.__name__, name, value.__doc__, debug.exnToString(e)) debug.msg(s) + self.res.sort(lambda (r1, m1), (r2, m2): cmp(m1.__name__, m2.__name__)) def doPrivmsg(self, irc, msg): if ircdb.checkIgnored(msg.prefix, msg.args[0]): @@ -492,6 +518,8 @@ class PrivmsgRegexp(Privmsg): if msg: irc = IrcObjectProxyRegexp(irc) self.callCommand(method, irc, msg, m) + if self.onlyFirstMatch: + return class PrivmsgCommandAndRegexp(Privmsg): diff --git a/src/conf.py b/src/conf.py index 489b89ca0..7e634d5aa 100644 --- a/src/conf.py +++ b/src/conf.py @@ -187,6 +187,8 @@ driverModule = 'asyncoreDrivers' ############################### ############################### ############################### +import debug + class ConfigurationDict(dict): def __init__(self, L=()): L = [(key.lower(), value) for (key, value) in L] @@ -205,12 +207,13 @@ class ConfigurationDict(dict): return dict.__contains__(self, key.lower()) config = ConfigurationDict() + +def reportConfigError(filename, msg): + debug.unrecoverableError('%s: %s' % (filename, msg)) def processConfig(filename): - import debug import email - def reportConfigError(filename, msg): - debug.unrecoverableError('%s: %s' % (filename, msg)) + from callbacks import tokenize try: fd = file(filename) m = email.message_from_file(fd) @@ -247,7 +250,7 @@ def processConfig(filename): # from the commands to be run after connecting. This separates them # based on those newlines. (onStart, afterConnect) = tuple(itersplit(lines,lambda s: not s,True)) - config['onStart'] = [s for s in onStart if s and s[0] != '#'] + config['onStart'] = [tokenize(s) for s in onStart if s and s[0] != '#'] config['afterConnect'] = [s for s in afterConnect if s and s[0] != '#'] except IOError, e: diff --git a/src/irclib.py b/src/irclib.py index d9995b413..7475aabee 100644 --- a/src/irclib.py +++ b/src/irclib.py @@ -519,4 +519,5 @@ class Irc(object): def __eq__(self, other): return id(self) == id(other) + # vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78: diff --git a/src/privmsgs.py b/src/privmsgs.py index 45e282c62..e2a0e836c 100644 --- a/src/privmsgs.py +++ b/src/privmsgs.py @@ -266,6 +266,8 @@ class OwnerCommands(CapabilityCheckingPrivmsg): module = imp.load_module(name, *moduleInfo) linecache.checkcache() callback = module.Class() + if hasattr(callback, 'configure'): + callback.configure() irc.addCallback(callback) irc.reply(msg, conf.replySuccess) @@ -299,6 +301,8 @@ class OwnerCommands(CapabilityCheckingPrivmsg): module = imp.load_module(name, *moduleInfo) linecache.checkcache() callback = module.Class() + if hasattr(callback, 'configure'): + callback.configure() irc.addCallback(callback) irc.reply(msg, conf.replySuccess) except ImportError: