Last active
November 1, 2019 00:26
-
-
Save EJH2/5d8b85a15ce778c30e6b86927963a256 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from argparse import Namespace, ArgumentParser as AP | |
import contextlib | |
import io | |
from discord.ext.commands import Converter | |
class ArgumentException(BaseException): | |
pass | |
class Default(Namespace): | |
def __repr__(self): | |
return f"'{' '.join(f'--{k}={v}'for k, v in self._get_kwargs())}'" | |
class Argument: | |
""" Class to hold arguments to be passed to add_argument """ | |
def __init__(self, *args, **kwargs): | |
self.args = args | |
self.kwargs = kwargs | |
def register(self, parser): | |
parser.add_argument(*self.args, **self.kwargs) | |
class ArgumentParser(AP): | |
""" Custom parser class to redirect errors to the current channel """ | |
def __init__(self, *args, **kwargs): | |
super().__init__(*args, add_help=False, **kwargs) | |
def error(self, exc): | |
coro = self.ctx.send(f"Error: `{exc}`") | |
self.ctx.bot.loop.create_task(coro) | |
raise ArgumentException("Invalid arguments") | |
def set_ctx(self, ctx): | |
self.ctx = ctx | |
class ArgParseConverter(Converter): | |
""" Custom command class for argparse """ | |
def __init__(self, arguments, *args, **kwargs): | |
self.arguments = arguments | |
# Create the parser | |
self.parser = ArgumentParser(*args, **kwargs) | |
# Register all arguments | |
for argument in arguments: | |
argument.register(self.parser) | |
self.do_help = True | |
async def convert(self, ctx, arg): | |
sio = io.StringIO() | |
with contextlib.redirect_stdout(sio): | |
self.parser.print_help() | |
sio.seek(0) | |
ctx.command.usage = sio.read()[7:] | |
self.parser.set_ctx(ctx) | |
return self.parser.parse_args(arg.split()) | |
# Example command: | |
@commands.command(aliases=["words", "wc"]) | |
async def wordcloud(self, ctx, *, args: ArgParseConverter( | |
[Argument("--mask", help="Mask to use", default="mask"), | |
Argument("--font", help="Font to use", default="random"), | |
Argument("--color", help="Background color"), | |
Argument( | |
"--count", default=1000, type=int, | |
help="Number of messages to use")])=Default( | |
count=1000, | |
font="random")): | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment