From 18159024c72681c7e692e061e812a10979bd54b5 Mon Sep 17 00:00:00 2001 From: Ryan Hitchman Date: Wed, 30 Apr 2014 13:16:16 -0700 Subject: [PATCH] reload connection configurations, make admin setting per-connection --- bot.py | 32 +++++++++++--------------------- core/config.py | 8 ++++++++ core/irc.py | 45 +++++++++++++++------------------------------ plugins/misc.py | 4 ++-- plugins/sieve.py | 7 ++++--- 5 files changed, 40 insertions(+), 56 deletions(-) diff --git a/bot.py b/bot.py index 2d41b9a..cc4be13 100755 --- a/bot.py +++ b/bot.py @@ -3,6 +3,7 @@ import os import Queue import sys +import traceback import time sys.path += ['plugins'] # so 'import hook' works without duplication @@ -11,8 +12,11 @@ os.chdir(sys.path[0] or '.') # do stuff relative to the install directory class Bot(object): - pass - + def __init__(self): + self.conns = {} + self.persist_dir = os.path.abspath('persist') + if not os.path.exists(self.persist_dir): + os.mkdir(bot.persist_dir) bot = Bot() @@ -23,31 +27,17 @@ eval(compile(open(os.path.join('core', 'reload.py'), 'U').read(), os.path.join('core', 'reload.py'), 'exec')) reload(init=True) -config() -if not hasattr(bot, 'config'): - exit() - print 'Connecting to IRC' -bot.conns = {} - try: - for name, conf in bot.config['connections'].iteritems(): - if conf.get('ssl'): - bot.conns[name] = SSLIRC(conf['server'], conf['nick'], conf=conf, - port=conf.get('port', 6667), channels=conf['channels'], - ignore_certificate_errors=conf.get('ignore_cert', True)) - else: - bot.conns[name] = IRC(conf['server'], conf['nick'], conf=conf, - port=conf.get('port', 6667), channels=conf['channels']) + config() + if not hasattr(bot, 'config'): + exit() except Exception, e: - print 'ERROR: malformed config file', e + print 'ERROR: malformed config file:', e + traceback.print_exc() sys.exit() -bot.persist_dir = os.path.abspath('persist') -if not os.path.exists(bot.persist_dir): - os.mkdir(bot.persist_dir) - print 'Running main loop' while True: diff --git a/core/config.py b/core/config.py index 1b2cacb..ac8ebca 100644 --- a/core/config.py +++ b/core/config.py @@ -45,6 +45,14 @@ def config(): try: bot.config = json.load(open('config')) bot._config_mtime = config_mtime + for name, conf in bot.config['connections'].iteritems(): + if name in bot.conns: + bot.conns[name].set_conf(conf) + else: + if conf.get('ssl'): + bot.conns[name] = SSLIRC(conf) + else: + bot.conns[name] = IRC(conf) except ValueError, e: print 'ERROR: malformed config!', e diff --git a/core/irc.py b/core/irc.py index b9f898f..8278504 100644 --- a/core/irc.py +++ b/core/irc.py @@ -130,12 +130,8 @@ class IRC(object): "handles the IRC protocol" # see the docs/ folder for more information on the protocol - def __init__(self, server, nick, port=6667, channels=[], conf={}): - self.channels = channels - self.conf = conf - self.server = server - self.port = port - self.nick = nick + def __init__(self, conf): + self.set_conf(conf) self.out = Queue.Queue() # responses from the server are placed here # format: [rawline, prefix, command, params, @@ -144,17 +140,23 @@ class IRC(object): thread.start_new_thread(self.parse_loop, ()) + def set_conf(self, conf): + self.conf = conf + self.nick = self.conf['nick'] + self.server = self.conf['server'] + def create_connection(self): - return crlf_tcp(self.server, self.port) + return crlf_tcp(self.server, self.conf.get('port', 6667)) def connect(self): self.conn = self.create_connection() thread.start_new_thread(self.conn.run, ()) - self.set_pass(self.conf.get('server_password')) - self.set_nick(self.nick) + self.cmd("NICK", [self.nick]) self.cmd("USER", - [conf.get('user', 'skybot'), "3", "*", conf.get('realname', + [self.conf.get('user', 'skybot'), "3", "*", self.conf.get('realname', 'Python bot - http://github.com/rmmh/skybot')]) + if 'server_password' in self.conf: + self.cmd("PASS", [self.conf['server_password']]) def parse_loop(self): while True: @@ -180,13 +182,6 @@ class IRC(object): if command == "PING": self.cmd("PONG", paramlist) - def set_pass(self, password): - if password: - self.cmd("PASS", [password]) - - def set_nick(self, nick): - self.cmd("NICK", [nick]) - def join(self, channel): self.cmd("JOIN", channel.split(" ")) # [chan, password] @@ -206,13 +201,8 @@ class IRC(object): class FakeIRC(IRC): - def __init__(self, server, nick, port=6667, channels=[], conf={}, fn=""): - self.channels = channels - self.conf = conf - self.server = server - self.port = port - self.nick = nick - + def __init__(self, conf): + self.set_conf(conf) self.out = Queue.Queue() # responses from the server are placed here self.f = open(fn, 'rb') @@ -249,10 +239,5 @@ class FakeIRC(IRC): class SSLIRC(IRC): - def __init__(self, server, nick, port=6667, channels=[], conf={}, - ignore_certificate_errors=True): - self.ignore_cert_errors = ignore_certificate_errors - IRC.__init__(self, server, nick, port, channels, conf) - def create_connection(self): - return crlf_ssl_tcp(self.server, self.port, self.ignore_cert_errors) + return crlf_ssl_tcp(self.server, self.conf.get('port', 6697), self.conf.get('ignore_cert', True)) diff --git a/plugins/misc.py b/plugins/misc.py index e1981fa..da0924b 100644 --- a/plugins/misc.py +++ b/plugins/misc.py @@ -26,7 +26,7 @@ def get_version(): @hook.event('KICK') def rejoin(paraml, conn=None): if paraml[1] == conn.nick: - if paraml[0].lower() in conn.channels: + if paraml[0].lower() in conn.conf.get("channels", []): conn.join(paraml[0]) @@ -52,7 +52,7 @@ def onjoin(paraml, conn=None): conn.cmd('MODE', [conn.nick, mode]) # join channels - for channel in conn.channels: + for channel in conn.conf.get("channels", []): conn.join(channel) time.sleep(1) # don't flood JOINs diff --git a/plugins/sieve.py b/plugins/sieve.py index 5685298..b47fed9 100644 --- a/plugins/sieve.py +++ b/plugins/sieve.py @@ -44,10 +44,11 @@ def sieve_suite(bot, input, func, kind, args): if input.nick.lower() in acl['blacklist-nicks']: return None - if args.get('adminonly', False): - admins = bot.config.get('admins', []) + admins = input.conn.conf.get('admins', []) + input.admin = input.host in admins or input.nick in admins - if input.host not in admins and input.nick not in admins: + if args.get('adminonly', False): + if not input.admin: return None return input