From 0aa2f987056ebc7e8f2c1ff39943126cdb5380b5 Mon Sep 17 00:00:00 2001 From: James Lu Date: Thu, 16 Jul 2015 21:30:25 -0700 Subject: [PATCH] Move client spawning, command / KILL / KICK handling outside the protocol module New plugin 'coreplugin' takes care of command/KILL/KICK handling, while client spawning is moved into Irc.spawnMain() and is used by the former. Closes #33. --- coreplugin.py | 39 +++++++++++++++++++++++++++++++++++++++ main.py | 11 +++++++++++ protocols/inspircd.py | 26 -------------------------- 3 files changed, 50 insertions(+), 26 deletions(-) create mode 100644 coreplugin.py diff --git a/coreplugin.py b/coreplugin.py new file mode 100644 index 0000000..b6c0712 --- /dev/null +++ b/coreplugin.py @@ -0,0 +1,39 @@ +## coreplugin.py - Core PyLink plugin + +import traceback + +import utils +from log import log + +# Handle KILLs sent to the PyLink client and respawn +def handle_kill(irc, source, command, args): + if args['target'] == irc.pseudoclient.uid: + irc.spawnMain() +utils.add_hook(handle_kill, 'KILL') + +# Handle KICKs to the PyLink client, rejoining the channels +def handle_kick(irc, source, command, args): + kicked = args['target'] + channel = args['channel'] + if kicked == irc.pseudoclient.uid: + irc.proto.joinClient(irc, irc.pseudoclient.uid, channel) +utils.add_hook(handle_kick, 'KICK') + +# Handle commands sent to the PyLink client (PRIVMSG) +def handle_commands(irc, source, command, args): + if args['target'] == irc.pseudoclient.uid: + cmd_args = args['text'].split(' ') + cmd = cmd_args[0].lower() + cmd_args = cmd_args[1:] + try: + func = utils.bot_commands[cmd] + except KeyError: + utils.msg(irc, source, 'Unknown command %r.' % cmd) + return + try: + func(irc, source, cmd_args) + except Exception as e: + traceback.print_exc() + utils.msg(irc, source, 'Uncaught exception in command %r: %s: %s' % (cmd, type(e).__name__, str(e))) + return +utils.add_hook(handle_commands, 'PRIVMSG') diff --git a/main.py b/main.py index e00df49..6cb5209 100755 --- a/main.py +++ b/main.py @@ -12,6 +12,7 @@ from log import log import conf import classes import utils +import coreplugin class Irc(): def __init__(self, netname, proto, conf): @@ -69,6 +70,7 @@ class Irc(): self.name, type(e).__name__, str(e)) self.disconnect() else: + self.spawnMain() self.run() def disconnect(self): @@ -115,6 +117,14 @@ class Irc(): self.name, type(e).__name__, str(e)) self.disconnect() + def spawnMain(self): + nick = self.botdata.get('nick') or 'PyLink' + ident = self.botdata.get('ident') or 'pylink' + host = self.serverdata["hostname"] + self.pseudoclient = self.proto.spawnClient(self, nick, ident, host, modes={("o", None)}) + for chan in self.serverdata['channels']: + self.proto.joinClient(self, self.pseudoclient.uid, chan) + if __name__ == '__main__': log.info('PyLink starting...') if conf.conf['login']['password'] == 'changeme': @@ -124,6 +134,7 @@ if __name__ == '__main__': # Import plugins first globally, because they can listen for events # that happen before the connection phase. + utils.plugins.append(coreplugin) to_load = conf.conf['plugins'] plugins_folder = [os.path.join(os.getcwd(), 'plugins')] # Here, we override the module lookup and import the plugins diff --git a/protocols/inspircd.py b/protocols/inspircd.py index 41a861b..c602daf 100644 --- a/protocols/inspircd.py +++ b/protocols/inspircd.py @@ -299,12 +299,7 @@ def connect(irc): f('SERVER {host} {Pass} 0 {sid} :PyLink Service'.format(host=host, Pass=irc.serverdata["sendpass"], sid=irc.sid)) f(':%s BURST %s' % (irc.sid, ts)) - nick = irc.botdata.get('nick') or 'PyLink' - ident = irc.botdata.get('ident') or 'pylink' - irc.pseudoclient = spawnClient(irc, nick, ident, host, modes={("o", None)}) f(':%s ENDBURST' % (irc.sid)) - for chan in irc.serverdata['channels']: - joinClient(irc, irc.pseudoclient.uid, chan) def handle_ping(irc, source, command, args): # <- :70M PING 70M 0AL @@ -313,31 +308,12 @@ def handle_ping(irc, source, command, args): _send(irc, args[1], 'PONG %s %s' % (args[1], source)) def handle_privmsg(irc, source, command, args): - if args[0] == irc.pseudoclient.uid: - cmd_args = args[1].split(' ') - cmd = cmd_args[0].lower() - cmd_args = cmd_args[1:] - try: - func = utils.bot_commands[cmd] - except KeyError: - utils.msg(irc, source, 'Unknown command %r.' % cmd) - return - try: - func(irc, source, cmd_args) - except Exception as e: - traceback.print_exc() - utils.msg(irc, source, 'Uncaught exception in command %r: %s: %s' % (cmd, type(e).__name__, str(e))) - return return {'target': args[0], 'text': args[1]} def handle_kill(irc, source, command, args): killed = args[0] data = irc.users[killed] removeClient(irc, killed) - if killed == irc.pseudoclient.uid: - irc.pseudoclient = spawnClient(irc, 'PyLink', 'pylink', irc.serverdata["hostname"]) - for chan in irc.serverdata['channels']: - joinClient(irc, irc.pseudoclient.uid, chan) return {'target': killed, 'text': args[1], 'userdata': data} def handle_kick(irc, source, command, args): @@ -345,8 +321,6 @@ def handle_kick(irc, source, command, args): channel = args[0].lower() kicked = args[1] handle_part(irc, kicked, 'KICK', [channel, args[2]]) - if kicked == irc.pseudoclient.uid: - joinClient(irc, irc.pseudoclient.uid, channel) return {'channel': channel, 'target': kicked, 'text': args[2]} def handle_part(irc, source, command, args):