Skip to content

Instantly share code, notes, and snippets.

@EJH2
Last active November 1, 2019 00:26
Show Gist options
  • Save EJH2/5d8b85a15ce778c30e6b86927963a256 to your computer and use it in GitHub Desktop.
Save EJH2/5d8b85a15ce778c30e6b86927963a256 to your computer and use it in GitHub Desktop.
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