From f40cb7954a065144fb07225ad85c83cc9cde08ba Mon Sep 17 00:00:00 2001 From: James Lu Date: Tue, 16 Jun 2015 20:05:41 -0700 Subject: [PATCH] Allow dynamic protocol loading again, and make proto an attribute of Irc() This should remove the need for plugins, etc. to import proto directly, which wouldn't work because of dynamic naming. --- config.yml.example | 1 + main.py | 27 +++++++++++++++++++-------- plugins/admin.py | 30 +++++++++++++++++++++++------- plugins/commands.py | 17 ----------------- proto.py => protocols/inspircd.py | 2 ++ utils.py | 3 +-- 6 files changed, 46 insertions(+), 34 deletions(-) rename proto.py => protocols/inspircd.py (99%) diff --git a/config.yml.example b/config.yml.example index 1718760..5654323 100644 --- a/config.yml.example +++ b/config.yml.example @@ -24,6 +24,7 @@ server: sid: "0AL" # Autojoin channels channels: ["#pylink"] + protocol: "inspircd" # Plugins to load (omit the .py extension) plugins: diff --git a/main.py b/main.py index 4714806..1192e00 100755 --- a/main.py +++ b/main.py @@ -7,14 +7,9 @@ import time import sys from conf import conf -import proto - -if conf['login']['password'] == 'changeme': - print("You have not set the login details correctly! Exiting...") - sys.exit(2) class Irc(): - def __init__(self): + def __init__(self, proto): # Initialize some variables self.socket = socket.socket() self.connected = False @@ -32,6 +27,7 @@ class Irc(): self.socket = socket.socket() self.socket.connect((ip, port)) + self.proto = proto proto.connect(self) self.loaded = [] self.load_plugins() @@ -74,9 +70,24 @@ class Irc(): if str(e).startswith('No module named'): print('Failed to load plugin %r: the plugin could not be found.' % plugin) else: - print('Failed to load plugin %r: import error %s' (plugin, str(e))) + print('Failed to load plugin %r: import error %s' % (plugin, str(e))) print("loaded plugins: %s" % self.loaded) if __name__ == '__main__': print('PyLink starting...') - irc_obj = Irc() + if conf['login']['password'] == 'changeme': + print("You have not set the login details correctly! Exiting...") + sys.exit(2) + + protoname = conf['server']['protocol'] + protocols_folder = [os.path.join(os.getcwd(), 'protocols')] + try: + moduleinfo = imp.find_module(protoname, protocols_folder) + proto = imp.load_source(protoname, moduleinfo[1]) + except ImportError as e: + if str(e).startswith('No module named'): + print('Failed to load protocol module %r: the file could not be found.' % protoname) + else: + print('Failed to load protocol module: import error %s' % (protoname, str(e))) + else: + irc_obj = Irc(proto) diff --git a/plugins/admin.py b/plugins/admin.py index e4edd18..6791dca 100644 --- a/plugins/admin.py +++ b/plugins/admin.py @@ -1,7 +1,6 @@ # admin.py: PyLink administrative commands import sys, os sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) -import proto import utils class NotAuthenticatedError(Exception): @@ -28,7 +27,7 @@ def spawnclient(irc, source, args): except ValueError: utils.msg(irc, source, "Error: not enough arguments. Needs 3: nick, user, host.") return - proto.spawnClient(irc, nick, ident, host) + irc.proto.spawnClient(irc, nick, ident, host) @utils.add_cmd def quitclient(irc, source, args): @@ -43,7 +42,7 @@ def quitclient(irc, source, args): return u = utils.nickToUid(irc, nick) quitmsg = ' '.join(args[1:]) or 'Client quit' - proto.quitClient(irc, u, quitmsg) + irc.proto.quitClient(irc, u, quitmsg) @utils.add_cmd def joinclient(irc, source, args): @@ -61,7 +60,7 @@ def joinclient(irc, source, args): if not channel.startswith('#'): utils.msg(irc, source, "Error: channel names must start with #.") return - proto.joinClient(irc, u, channel) + irc.proto.joinClient(irc, u, channel) @utils.add_cmd def nickclient(irc, source, args): @@ -73,7 +72,7 @@ def nickclient(irc, source, args): utils.msg(irc, source, "Error: not enough arguments. Needs 2: nick, newnick.") return u = utils.nickToUid(irc, nick) - proto.nickClient(irc, u, newnick) + irc.proto.nickClient(irc, u, newnick) @utils.add_cmd def partclient(irc, source, args): @@ -90,7 +89,7 @@ def partclient(irc, source, args): if not channel.startswith('#'): utils.msg(irc, source, "Error: channel names must start with #.") return - proto.partClient(irc, u, channel, reason) + irc.proto.partClient(irc, u, channel, reason) @utils.add_cmd def kickclient(irc, source, args): @@ -108,4 +107,21 @@ def kickclient(irc, source, args): if not channel.startswith('#'): utils.msg(irc, source, "Error: channel names must start with #.") return - proto.kickClient(irc, u, channel, targetu, reason) + irc.proto.kickClient(irc, u, channel, targetu, reason) + +@utils.add_cmd +def tell(irc, source, args): + checkauthenticated(irc, source) + try: + source, target, text = args[0], args[1], ' '.join(args[2:]) + except IndexError: + utils.msg(irc, source, 'Error: not enough arguments.') + return + targetuid = utils.nickToUid(irc, target) + if targetuid is None: + utils.msg(irc, source, 'Error: unknown user %r' % target) + return + if not text: + utils.msg(irc, source, "Error: can't send an empty message!") + return + utils.msg(irc, target, text, notice=True) diff --git a/plugins/commands.py b/plugins/commands.py index edda62d..018f019 100644 --- a/plugins/commands.py +++ b/plugins/commands.py @@ -1,26 +1,9 @@ # commands.py: base PyLink commands import sys, os sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) -import proto import utils from conf import conf -@utils.add_cmd -def tell(irc, source, args): - try: - target, text = args[0], ' '.join(args[1:]) - except IndexError: - utils.msg(irc, source, 'Error: not enough arguments.') - return - targetuid = utils.nickToUid(irc, target) - if targetuid is None: - utils.msg(irc, source, 'Error: unknown user %r' % target) - return - if not text: - utils.msg(irc, source, "Error: can't send an empty message!") - return - utils.msg(irc, target, text, notice=True) - @utils.add_cmd def debug(irc, source, args): print('user index: %s' % irc.users) diff --git a/proto.py b/protocols/inspircd.py similarity index 99% rename from proto.py rename to protocols/inspircd.py index 1950184..4fb7c65 100644 --- a/proto.py +++ b/protocols/inspircd.py @@ -1,6 +1,8 @@ import socket import time import sys +import os +sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) from utils import * from copy import copy import traceback diff --git a/utils.py b/utils.py index 10bdbee..7a15b72 100644 --- a/utils.py +++ b/utils.py @@ -1,5 +1,4 @@ import string -import proto global bot_commands # This should be a mapping of command names to functions @@ -19,7 +18,7 @@ def next_uid(sid, level=-1): def msg(irc, target, text, notice=False): command = 'NOTICE' if notice else 'PRIVMSG' - proto._sendFromUser(irc, irc.pseudoclient.uid, '%s %s :%s' % (command, target, text)) + irc.proto._sendFromUser(irc, irc.pseudoclient.uid, '%s %s :%s' % (command, target, text)) def add_cmd(func, name=None): if name is None: