From ae7c9d75c44c1e0ec71a5c0eb30b08ca523cb0dc Mon Sep 17 00:00:00 2001 From: Zeroji Date: Thu, 17 Nov 2016 22:08:38 +0100 Subject: [PATCH] Added help command! --- CHANGELOG.md | 3 ++- TODO.md | 3 +-- cogs/base.py | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++ gearbox.py | 4 ++- 4 files changed, 75 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cb756a1..a7b307a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ ## Change Log All notable changes to this project will be documented in this file. -### [Unreleased] +### [v0.1.2] #### Added @@ -11,6 +11,7 @@ All notable changes to this project will be documented in this file. + Possibility to to regex checks on arguments + Added basic support for argument documentation (you can add it without errors, but it's not used yet) + Added reaction support via `@cog.on_reaction` (more in doc) ++ `help` command, finally! #### Changed diff --git a/TODO.md b/TODO.md index a8d304a..af53d33 100644 --- a/TODO.md +++ b/TODO.md @@ -7,8 +7,7 @@ which may or may not be implemented in future versions. ##### Next things I'll work on -1. Integrate `;base.help` function -0. Possibly tweak other base functions +1. Possibly tweak other base functions 0. Refine all examples / commands annotations 3. Update documentation accordingly diff --git a/cogs/base.py b/cogs/base.py index 0ffac62..0abaa56 100644 --- a/cogs/base.py +++ b/cogs/base.py @@ -27,6 +27,75 @@ def disable(server_ex, cog_name): return f'Disabled {cog_name}' +HELP_WIDTH = 29 + + +@cog.command +@cog.rename('help') +def halp(__cogs, server_ex, name: 'Cog or command name'=None): + active_cogs = [cog for cog in __cogs.COGS if cog not in server_ex.blacklist] + commands = __cogs.command(name, server_ex.blacklist) + if '.' in name: + cog, cname = name.split('.', 2) + if cog in active_cogs and __cogs.COGS[cog].cog.get(cname): + commands = [(cog, __cogs.COGS[cog].cog.get(cname))] + if name is None: + return "Hi, I'm `;;` :no_mouth: I'm split into several cogs, type `;help ` for more information\n" \ + f"The following cog{'s are' if len(active_cogs)>1 else ' is'} currently enabled: " \ + f"{gearbox.pretty(active_cogs, '`%s`')}" + elif name in active_cogs: + cog = __cogs.COGS[name] + output = f'`{name}` - ' + cog.__doc__.replace('\n\n', '\n') + for cname, command in cog.cog.commands.items(): + line = cname; + for i, arg in enumerate(command.normal): + line += (' <%s>' if i < command.min_arg else ' [%s]') % arg + output += f'\n`{line:{HELP_WIDTH}.{HELP_WIDTH}}|` {command.func.__doc__.splitlines()[0]}' + if commands: + output += f"\nThe following command{'s' if len(commands) > 1 else ''} " \ + f"also exist{'s' if len(commands) == 1 else ''}: " +\ + gearbox.pretty([f'{cog}.{command.func.__name__}' for cog, command in commands], '`%s`') + return output + elif commands: + if len(commands) > 1: + return 'There are commands in multiple cogs with that name:\n' +\ + '\n'.join([f'`{cog + "." + command.func.__name__:{HELP_WIDTH}.{HELP_WIDTH}}|` ' + + command.func.__doc__.splitlines()[0] for cog, command in commands]) + cog, command = commands[0] + complete_name = cog + '.' + command.func.__name__ + output = f'`{complete_name}` - {command.func.__doc__.splitlines()[0]}' + output += '\nUsage: `' + complete_name + (' -flags' if command.flags else '') + for i, arg in enumerate(command.normal): + output += (' <%s>' if i < command.min_arg else ' [%s]') % arg + output += '`' + if command.flags: + output += '\nFlags: ' + keys = list(command.flags) + keys.sort() + output += gearbox.pretty([f'`-{flag}`' + (f' ({command.flags[flag]})' if command.flags[flag] else '') + for flag in keys]) + if any([arg[0] is not None or len(arg[1]) > 0 for arg in command.annotations.values()]): + output += '\nArguments: ' + arguments = [] + for arg in command.normal: + anno = command.annotations[arg] + temp = f'`{arg}`' + if anno[0] is not None: + if type(anno[0]) is not type: + temp += f' (must match `{anno[0].pattern}`' + else: + temp += f' ({anno[0].__name__})' + if len(anno[1]) > 0: + temp += f' ({anno[1]})' + arguments.append(temp) + output += gearbox.pretty(arguments) + if '\n' in command.func.__doc__: + output += '\n' + '\n'.join([line.strip() for line in command.func.__doc__.splitlines()[1:] if line]) + return output + return 'Nah sorry mate dunno about that' + # return f'I has halp! But no wit {name} :(' + str(dir(__cogs)) + + @cog.command(permissions='manage_server') def prefix(server_ex, command='get', *args): """Display or modify prefix settings for server.""" diff --git a/gearbox.py b/gearbox.py index 5c12138..9ad1752 100644 --- a/gearbox.py +++ b/gearbox.py @@ -71,12 +71,14 @@ def __init__(self, func, flags='', fulltext=False, delete_message=False, permiss if type(item) is str: self.annotations[key] = (None, item) elif type(item) in type_types: - self.annotations[key] = (item, None) + self.annotations[key] = (item, '') elif type(item) is tuple: if type(item[0]) is str and type(item[1]) in type_types: self.annotations[key] = (item[1], item[0]) elif type(item[0]) in type_types and type(item[1]) is str: self.annotations[key] = item + if not func.__doc__: + func.__doc__ = ' ' async def call(self, client, message, arguments, _cogs=None): """Call a command."""