diff options
Diffstat (limited to 'src/main.py')
-rw-r--r-- | src/main.py | 172 |
1 files changed, 172 insertions, 0 deletions
diff --git a/src/main.py b/src/main.py new file mode 100644 index 0000000..d85b81d --- /dev/null +++ b/src/main.py @@ -0,0 +1,172 @@ +import asyncio +import importlib +import re +import traceback +from string import whitespace + +import discord +import sys +import json +import argparse +import os + +client = discord.Client() + +commands = [] + + +def description(desc): + def wrapper(func): + func.description = desc + return func + + return wrapper + + +def name(name): + def wrapper(func): + func.name = name + return func + + return wrapper + + +@description('Helps you...') +@name('help') +@asyncio.coroutine +def help_cmd(cmd_args, author, channel, message): + embed = discord.Embed() + embed.colour = discord.Colour.gold() + embed.description = 'Helping you...' + for command in commands: + embed.add_field(name=command.name, value=command.description, inline=False) + embed.title = 'Command list' + yield from client.send_message(channel, embed=embed) + return True + + +commands += [help_cmd] + + +class Config(object): + def __init__(self, **kwargs): + self.token = kwargs['token'] + self.postfix = kwargs.get('postfix', '...') + + +def parse_split(content): + def temp(): + buffer = None + inquote = False + escape = False + for c in content: + if escape: + if buffer is None: + buffer = c + else: + buffer += c + if c in "'\"": + inquote = not inquote + if buffer is not None: + yield buffer + buffer = None + elif c in whitespace and not inquote: + if buffer is not None: + yield buffer + buffer = None + elif c == '\\': + escape = True + else: + if buffer is None: + buffer = c + else: + buffer += c + if buffer is not None: + yield buffer + + return list(temp()) + + +@client.event +@asyncio.coroutine +def process_message(message): + content = message.content[:-len(config.postfix)] + cmd_args = list(parse_split(content)) + print(cmd_args) + cmd = cmd_args[-1] + cmd_args = cmd_args[:-1] + author = message.author + for c in commands: + if c.name.lower() == cmd.lower(): + print('Executing command: %s(%s)' % (c.name, str(c))) + yield from c(cmd_args, author, message.channel, message) + return + help_cmd(cmd_args, author, message.channel, message) + + +@client.event +@asyncio.coroutine +def on_message(message: discord.Message): + if message.author.id == client.user.id: + return + if message.content.endswith(config.postfix): + yield from process_message(message) + + +@client.event +@asyncio.coroutine +def on_ready(): + print('Ready') + + +def load_modules(dir='modules', module='modules') -> tuple: + print(flush=True, end='') + loaded_count = 0 + total = 0 + fails = 0 + for file in os.listdir(dir): + newdir = os.path.join(dir, file) + if os.path.isdir(newdir): + add_loaded, add_fails, add_total = load_modules(newdir, module + '.' + file) + loaded_count += add_loaded + fails += add_fails + total += add_total + if file.endswith('.py'): + file = file[:-3] + total += 1 + print('Loading module: %s' % (module + '.' + file), flush=True) + try: + importlib.import_module('%s.%s' % (module, file)).setup(commands, client) + except KeyboardInterrupt: + raise + except Exception as e: + traceback.print_tb(e) + print('Module load failed: %s' % (module + '.' + file), flush=True) + fails += 1 + continue + print('Loaded module: %s' % (module + '.' + file), flush=True) + loaded_count += 1 + return loaded_count, fails, total + + +if __name__ == '__main__': + args = argparse.ArgumentParser() + args.add_argument('config_file', type=open, help='Config file in json format.') + ns = args.parse_args(sys.argv[1:]) + config = json.load(ns.config_file) + print('Config: %s' % str(config)) + print() + print('Loading modules') + loaded, fails, total = load_modules() + print('[' + '#' * loaded + '-' * fails + ']') + if fails == 0: + print('Loaded all modules successfully') + else: + print('Some modules failed to load.') + line = "" + while line.lower() not in ["y", "n"]: + line = input("Start anyway? (Y/N)") + if line.lower() == 'n': + sys.exit(1) + config = Config(**config) + client.run(config.token, bot=True) |