def get_commands(self, include_self_parameter: bool = False): def wrap(f): # Note how a default argument used, so that the error propagates properly async def wrapped(self, ctx, *, arg: ParsedArguments = None): return await f(ctx, arg=arg) return wrapped help_text = self.get_help_text() for cs in self.command_sources: if include_self_parameter: if args := cs.command_args: yield commands.command( **{ **args, 'description': args.get('description', 'No Description') + '\n\n' + help_text })(wrap(self.get_primary_command_function(cs))) if args := cs.list_command_args: yield commands.command( **{ **args, 'description': args.get('description', 'No Description') + '\n\n' + help_text })(wrap(self.get_list_command_function(cs)))
def test_slash_command_patches_adapt_name_to_parent_as_given_value(): parent = command()(func) cmd = command(parent=parent)(func) slash_command(root="root", name="name", discordpy_include_subcommand_name=False)(cmd) assert parent._discordpy_include_subcommand_name == {"name": False}
async def about(self, ctx): embed = discord.Embed( color=discord.Color.blurple(), title="About Doombot", description='\n'.join([ ":heart: [Paypal](https://paypal.me/KashTheKlub) Donate :flex:!", ).set_thumbnail( url="https://pics.paypal.com/00/s/NzIyWDc4M1hQTkc/p/YjJjZjY4NmMtNGNhMy00MTVkLWIwZTQtNTQxZWU0OGIyYTYz/image_58.jpg" ) return await ctx.send(embed=embed) @commands.command() async def support(self, ctx): s = Settings.get_for(ctx.guild.id) return await ctx.send(s.get_text('support')) @commands.command() async def help(self, ctx, *args): s = Settings.get_for(ctx.guild.id) filtered_commands = [] for arg in args: for c in self.bot.commands: if (c.name == arg or arg in c.aliases) and c not in filtered_commands: filtered_commands.append(c) if len(filtered_commands) > 0: embed = discord.Embed( color=discord.Color.blurple(), title=s.get_text('help') ) for command in filtered_commands: text = s.get_text('_commands')[command.name] embed.add_field( name="**{}** {} `{}`".format(text['_name'], s.get_text('alias'), "`, `".join(text['_aliases'])), value='\n'.join(text['_help']), inline=False ) return await ctx.send(embed=embed) embeds = [] for cog_name, cog in self.bot.cogs.items(): cog_text = s.get_text('_cog') embed = discord.Embed( color=cog.color, title=s.get_text('help'), description='**{}**'.format(cog_text[cog_name]) ) for command in sorted(cog.get_commands(), key=lambda c:c.name): text = s.get_text('_commands')[command.name] embed.add_field( name="**{}** {} `{}`".format(text['_name'], s.get_text('alias'), "`, `".join(text['_aliases'])), value='\n'.join(text['_help']), inline=False ) embeds.append(embed) timed_out_embed = discord.Embed( color=discord.Color.blurple(), title=s.get_text('help') ) await EmbedPagesEmbed(ctx, embeds, timed_out_embed).send() def setup(bot): load_cog(bot, General(bot))
def test_slash_command_patches_adapt_name_to_parent_multiple(): parent = command()(func) cmd1 = command(parent=parent)(func) cmd2 = command(parent=parent)(func) slash_command(root="root", name="name1")(cmd1) slash_command(root="root", name="name2")(cmd2) assert parent._discordpy_include_subcommand_name == { "name1": True, "name2": True }
def __init__(self): # Might be nicer to also have "@botuser get invite" as a command if # "@botuser add me" is not intuitive enough for me to remember. self.add_group.command(name='me', brief='Gets an invite URL.')(self.add_guild) self.get_group.command(name='invite', brief='Gets an invite URL.')(self.add_guild) self.remove_group.command(name='guild', aliases=['guilds', 'server', 'servers'], brief='Makes me leave a given server.')( self.remove_guild) commands.command(name='leave', brief='Makes me leave a given server.')( self.remove_guild)
def normal_command(name, *args, aliases=None): des = short_des(name) usage = mkhelpstr(name, *args, aliases=aliases) if aliases is not None: cmd = commands.command(name, aliases=aliases, description=des, usage=usage) else: cmd = commands.command(name, description=des, usage=usage) def inner(func): return cmd(func) return inner
async def _build_commands(self): for key in self.owoe.types: # Avoid duplicate commands by removing them. if key in self.bot.all_commands.keys(): self.bot.remove_command(key) helptext = f"{key.capitalize()}!" async def callback(self, ctx, *tags): tags = list(tags) for tag in tags: if tag not in self.owoe.tags: tags.remove(tag) url_image = await self.owoe.random_image(type_=ctx.command.name, tags=tags) if isinstance(url_image, str): embed = discord.Embed() embed.set_image(url=url_image) embed.set_footer(text="Powered by weeb.sh") await ctx.send(embed=embed) return await ctx.send("No image matching your criteria was found.") # Ew, gross. command = commands.command(name=key, help=helptext)(callback) command = commands.cooldown(6, 12, commands.BucketType.channel)(command) command.instance = self setattr(self, key, command) self.bot.add_command(command)
def inner(f): @wraps(f) async def wrapper(self, ctx, *args, **kwargs): async with ctx.typing(): await f(self, ctx, *args, **kwargs) return commands.command(*cargs, **ckwargs)(wrapper)
def safe_command(func): @functools.wraps(func) async def wrapper(self, *args): try: return await func(self, *args) except Exception as ex: self.logger.error(f'Fatal error inside {func.__name__}!!!!') self.logger.error(traceback.format_exc()) self.logger.error(str(ex)) await self.bot.say(f''' *BOOOOOOOM* Unfortunately, this bot crashed while running your command. After the flames and screaming, this info was left behind: Function where the error occurred: `{func.__name__}` ``` {traceback.format_exc()} ``` Sorry! :( '''.strip()) pass_context = 'ctx' in inspect.getfullargspec(func).args return commands.command(name=func.__name__, pass_context=pass_context)(wrapper)
def __new__(cls, name, bases, attrs): module = importlib.import_module(f".{name.lower()}", "slashtilities") def init(self, bot: commands.Bot) -> None: self.bot = bot new_attrs = attrs.copy() for func_name, options in attrs.items(): if not func_name[0] == "_": base_func = getattr(module, func_name) assert base_func.__name__ == func_name if isinstance(options, str): options = {"description": options} elif options is None: assert base_func.__doc__ is not None options = {"description": base_func.__doc__} new_attrs[f"slash_{func_name}"] = cog_ext.cog_slash( **{"name": func_name, "description": base_func.__doc__, **options} )(base_func) print(f"{name}.{func_name}") new_attrs[func_name] = commands.command(name=func_name)(base_func) new_attrs["__init__"] = init new_class = type(name, bases + (_Cog,), new_attrs) return new_class
def add_command(self, func, *, name=None): """ Adds a handler to a command. The ``name`` keyword argument can be used to override the function name. Args: func: (:class:`function`): The command handler itself, it can be a coroutine or not. name: (:class:`str`): The optional replacement name for your command. If :const:`None` is passed, the function name will be used. Returns: The function provided by argument ``func``. Examples: :: def hi(ctx): print('hi') bot.add_command(hi) """ func = _check_coro(func, self.severity) name = func.__name__ if name is None else name command = _cmd.command(name=name, cls=Command)(func) self.all_commands[name] = command self.bot.add_command(command) self.print("Command {} is registered".format(name)) return command
def group(**kwargs): """ Like the discord.ext.commands one... except it defaults to the KatCommand class instead. """ kwargs.setdefault('cls', KatGroup) return commands.command(**kwargs)
def decorator(func): result = commands.command(cls=EvieeCommand, *args, **kwargs)(func) try: self.add_command(result) except Exception as e: print(e) return result
def __init__(self, bot, names, regexes, channel_whitelist, message,): self.bot = bot self.names = names self.command = commands.command(names[0], aliases=names[1:])(self.send) # create the command to be later added to the bot self.message = message self.regexes = [re.compile(reg) for reg in regexes] self.channel_whitelist = channel_whitelist
def command(name=None, cls=Command, **attrs): """A decorator which transforms an async function into a `Command`. Same interface as `discord.ext.commands.command`. """ attrs["help_override"] = attrs.pop("help", None) return commands.command(name, cls, **attrs)
def decorator(func): result = commands.command(cls=Command, *args, **kwargs)(func) try: self.add_command(result) except Exception as e: logger.error(e) return result
def _faq_command_add(self, name, content, description=None): if description is None: description = content # We skip registering the command under this cog since it doesn't # play nicely if it doesn't happen at class intiialization (especially # for its interaction with the help menus). Thus it's unbounded. command = commands.command(name=name)(self._faq_command(content, description)) return self.client.add_command(command)
async def equalizer(self, ctx): player = self.bot.wavelink.get_player(ctx.guild.id) if not player.is_connected: return await ctx.send("대충 노래 안틀음") await ctx.send("멋진 부스트 이퀄라이져") await player.set_eq(wavelink.Equalizer.boost()) @ commands.command( aliases=["ㅔㅣ묘", "재생"] )
def create_commands(self, user: TwitterUser) -> None: username = user.user.lower() aliases = user.aliases # Make command that fetches random tweet URL _u_cmd = asyncio.coroutine( partial(self._twitter_url_cmd, user=username)) url_cmd = commands.command(name=f"{username}", aliases=aliases)(_u_cmd) # Make command that generates tweet using markov chain _m_cmd = asyncio.coroutine( partial(self._twitter_markov_cmd, user=username)) markov_cmd = commands.command( name=f"{username}_markov", aliases=[f"{alias}m" for alias in aliases] or [f"{username}m"])(_m_cmd) self.bot.add_command(url_cmd) self.bot.add_command(markov_cmd)
def test_slash_command_slash_options_subcommand(): options = [Option(name="opt", description="desc")] slash = slash_command(root="root", name="name", options=options)(command()(func)) assert slash.slash_ext.options == [ SubCommand(name="name", description=None, type=OptionType.SUB_COMMAND, options=options) ]
def command(name: str = None, cls=Command, **kwargs): """The command decorator. Works exactly like :func:`discord.ext.commands.command`. You can pass the ``typing`` keyword argument to wrap the entire command invocation in a :meth:`discord.ext.commands.Context.typing`, making the bot type for the duration the command runs. """ return commands.command(name, cls, **kwargs)
def custom_dec(func, name, **kwargs): if name is None: name = func.__name__ usage = name + ' ' + args decorator = commands.command(aliases=aliases, name=name, **kwargs) R = decorator(func) # call decorator # only store an object storing command metadata, don't store discord Command instance, # because that needs to be accessed from the bot (with __get__ and instance) this.all[func.__name__] = CommandMeta(name, description, usage, aliases) return R
def __init__(self, bot, names, regexes, channel_whitelist, message, is_persistent): self.bot = bot self.names = names self.command = commands.command(names[0], aliases=names[1:])( self.command_method ) # create the command to be later added to the bot TODO: move to on_ready to fix help message and cog specific command? self.message = message self.regexes = [re.compile(reg) for reg in regexes] self.channel_whitelist = channel_whitelist self.is_persistent = is_persistent
class Times(commands.Cog): def __init__(self, bot): self.bot = bot @commands.cooldown(1, 60, commands.BucketType.user) @in_bot_commands() @commands.command(name="when", help_command="!when", description="Check when the hackathon starts or ends", help="Check when the hackathon starts or ends" )
def add_generic(self, doc): async def func(self, ctx): await ctx.send(random.choice(doc['urls'])) func.__name__ = doc['name'] func.__doc__ = doc['doc'] aliases = doc.get('aliases') func = commands.command(name=doc['name'], aliases=aliases if aliases else [])(func) func.instance = self self.__cog_commands__ += (func, )
def wrapper(f): def check(ctx): return get_module(f.__module__).cog.check_once(ctx) if "checks" in kwargs: checks = kwargs.pop("checks").copy() checks.append(check) else: checks = [check] cmd = commands.command(*args, **kwargs)(f) cmd.checks += checks return cmd
def command(**kwargs) -> typing.Callable[[typing.Any], commands.Command]: """ Decorates a coroutine to make it into a command. name: str The name of the command. callback: coroutine The coroutine that is executed when the command is called. help: str The long help text for the command. brief: str The short help text for the command. If this is not specified then the first line of the long help text is used instead. usage: str A replacement for arguments in the default help text. aliases: list The list of aliases the command can be invoked under. enabled: bool A boolean that indicates if the command is currently enabled. If the command is invoked while it is disabled, then :exc:`.DisabledCommand` is raised to the :func:`.on_command_error` event. Defaults to ``True``. parent: Optional[command] The parent command that this command belongs to. ``None`` is there isn't one. checks A list of predicates that verifies if the command could be executed with the given :class:`.Context` as the sole parameter. If an exception is necessary to be thrown to signal failure, then one derived from :exc:`.CommandError` should be used. Note that if the checks fail then :exc:`.CheckFailure` exception is raised to the :func:`.on_command_error` event. description: str The message prefixed into the default help command. hidden: bool If ``True``\, the default help command does not show this in the help output. rest_is_raw: bool If ``False`` and a keyword-only argument is provided then the keyword only argument is stripped and handled as if it was a regular argument that handles :exc:`.MissingRequiredArgument` and default values in a regular matter rather than passing the rest completely raw. If ``True`` then the keyword-only argument will pass in the rest of the arguments in a completely raw matter. Defaults to ``False``. ignore_extra: bool If ``True``\, ignores extraneous strings passed to a command if all its requirements are met (e.g. ``?foo a b c`` when only expecting ``a`` and ``b``). Otherwise :func:`.on_command_error` and local error handlers are called with :exc:`.TooManyArguments`. Defaults to ``True``. """ kwargs.setdefault('cls', NekoCommand) return commands.command(**kwargs)
def c_command(**kwargs): """ Decorator for commands Parameters ---------- kwargs Returns ------- Decorator that transform command into a class Command """ return commands.command(cls=CustomCommand, **kwargs)
class Example(commands.Cog): def __init__(self, client): self.client = client #Events @commands.Cog.listener() async def on_ready(self): print("Bot is ready.") #Commands commands.command() async def ping(self, ctx): await ctx.send("Pong!")
def _words(title, param, cmd=False, aliases=None, description=None): async def newfunc(self, ctx, *, word): async with ctx.channel.typing(): lewords = await q(self.api.words, **{param: word}) await ctx.send( embed=self.join_words_embed(ctx, 'words/' + title + '-title', lewords, word)) if cmd: return command( name=cmd, aliases=aliases or [title], description=(description or 'words/' + cmd + '-description'))(newfunc) return newfunc