async def can_run(self, ctx: commands.Context): original = ctx.command ctx.command = self try: if not (await ctx.bot.can_run(ctx)): raise commands.CheckFailure( f'The global check functions for {self.qualified_name} failed.' ) cog = self.instance if cog is not None: try: local_check = getattr( cog, f'_{cog.__class__.__name__}__local_check') except AttributeError: pass else: ret = await discord.utils.maybe_coroutine(local_check, ctx) if not ret: return False if ctx.author.id in ctx.bot.owners: return True predicates = self.checks if not predicates: return True return await discord.utils.async_all( predicate(ctx) for predicate in predicates) finally: ctx.command = original
async def can_run(self, ctx: commands.Context) -> bool: if not self.enabled: raise DisabledCommand(f"{self.name} command is disabled") original = ctx.command ctx.command = self try: if not await ctx.bot.can_run(ctx): raise CheckFailure(f"The global check functions for command {self.qualified_name} failed.") cog = self.cog if cog is not None: local_check = Cog._get_overridden_method(cog.cog_check) if local_check is not None: ret = await discord.utils.maybe_coroutine(local_check, ctx) if not ret: return False predicates = self.checks if not predicates: # since we have no checks, then we just return True. return True return await discord.utils.async_all(predicate(ctx) for predicate in predicates) # type: ignore finally: ctx.command = original
async def reinvoke(self, ctx: commands.Context, *, call_hooks=False): early_invoke = not self.invoke_without_command if early_invoke: ctx.command = self await self._parse_arguments(ctx) if call_hooks: await self.call_before_hooks(ctx) view = ctx.view previous = view.index view.skip_ws() trigger = view.get_word() if trigger: ctx.subcommand_passed = trigger ctx.invoked_subcommand = self.all_commands.get(trigger) if early_invoke: try: await self.callback(*ctx.args, **ctx.kwargs) except Exception: ctx.command_failed = True raise finally: if call_hooks: await self.call_after_hooks(ctx) if trigger and ctx.invoked_subcommand: ctx.invoked_with = trigger await ctx.invoked_subcommand.reinvoke(ctx, call_hooks=call_hooks) elif not early_invoke: view.index = previous view.previous = previous await super().reinvoke(ctx, call_hooks=call_hooks)
async def can_run(self, ctx: commands.Context, cmd: Union[RainCommand, RainGroup]) -> bool: ctx.command = cmd can_run = True if cmd.checks: try: can_run = (await discord.utils.async_all(predicate(ctx) for predicate in cmd.checks)) except commands.CheckFailure: can_run = False return can_run
async def on_command_error(self, ctx: commands.Context, error): """only for CommandNotFound""" error = getattr(error, "original", error) if isinstance(error, commands.CommandNotFound ) and ctx.message.content.startswith(f"{ctx.prefix}!"): ctx.timer = time() ctx.iscallback = True ctx.command = self.bot.get_command("!") await ctx.command.callback(self, ctx)
async def warn(self, ctx: commands.Context, member: Union[MemberOrID, str]=None, *, reason: str=None) -> None: """Manage warns""" if isinstance(member, (discord.User, discord.Member)): if reason: ctx.command = self.add_ await ctx.invoke(self.add_, member=member, reason=reason) else: await ctx.invoke(self.bot.get_command('help'), command_or_cog='warn add') else: await ctx.invoke(self.bot.get_command('help'), command_or_cog='warn')
async def do_test_command(self, ctx: commands.Context, cmd: commands.Command, *args, **kwargs) -> None: if isinstance(cmd, str): cmd = self.bot.get_command(cmd) ctx.command = cmd if not cmd: raise TypeError( "Command must be name of command or discord.ext.commands.Command object!" ) return await self._do_test(cmd, *args, **kwargs, ctx=ctx)
async def get_context(client: Client, msg: Message) -> Context: view = StringView(msg.content) ctx = Context(prefix=None, view=view, bot=client, message=msg) if client._skip_check(msg.author.id, client.user.id): return ctx prefix = await client._get_prefix(msg) invoked_prefix = prefix if isinstance(prefix, str): if not view.skip_string(prefix): return ctx else: invoked_prefix = discord.utils.find(view.skip_string, prefix) if invoked_prefix is None: return ctx invoker = view.get_word() ctx.invoked_with = invoker ctx.prefix = invoked_prefix ctx.command = client.all_commands.get(invoker) return ctx
async def on_command_error(ctx: Context, error: Exception): "Suppress command check failures and invalid commands." if isinstance(error, CheckFailure): return if isinstance(error, CommandNotFound): if isinstance(ctx.channel, DMChannel): return cog = ctx.bot.get_cog('alias') if cog is None: return guild = str(ctx.guild.id) aliases = cog.aliases[guild] if guild in cog.aliases else None if aliases is None: return name = ctx.message.content \ .replace(ctx.prefix, '').split(' ')[0].strip() if name not in aliases: return cmd = ctx.bot.get_command(aliases[name]) if cmd is None: return ctx.command = cmd return await ctx.bot.invoke(ctx) raise error
async def add_(self, ctx: commands.Context, member: MemberOrID, *, reason: str) -> None: """Warn a user Can also be used as `warn <member> [reason]`""" if get_perm_level(member, await self.bot.db.get_guild_config( ctx.guild.id))[0] >= get_perm_level( ctx.author, await self.bot.db.get_guild_config(ctx.guild.id ))[0]: await ctx.send('User has insufficient permissions') else: guild_config = await self.bot.db.get_guild_config(ctx.guild.id) guild_warns = guild_config.warns warn_punishments = guild_config.warn_punishments warn_punishment_limits = [i.warn_number for i in warn_punishments] warns = list( filter(lambda w: w['member_id'] == str(member.id), guild_warns)) cmd = None punish = False num_warns = len(warns) + 1 fmt = f'You have been warned in **{ctx.guild.name}**, reason: {reason}. This is warning #{num_warns}.' if warn_punishments: punishments = list( filter(lambda x: int(x) == num_warns, warn_punishment_limits)) if not punishments: punish = False above = list( filter(lambda x: int(x) > num_warns, warn_punishment_limits)) if above: closest = min(map(int, above)) cmd = warn_punishments.get_kv('warn_number', closest).punishment if cmd == 'ban': cmd = 'bann' fmt += f' You will be {cmd}ed on warning {closest}.' else: punish = True cmd = warn_punishments.get_kv( 'warn_number', max(map(int, punishments))).punishment if cmd == 'ban': cmd = 'bann' fmt += f' You have been {cmd}ed from the server.' try: await member.send(fmt) except discord.Forbidden: if ctx.author != ctx.guild.me: await ctx.send( 'The user has PMs disabled or blocked the bot.') finally: guild_config = await self.bot.db.get_guild_config(ctx.guild.id) current_date = (ctx.message.created_at + timedelta( hours=guild_config.time_offset)).strftime('%Y-%m-%d') if len(guild_warns) == 0: case_number = 1 else: case_number = guild_warns[-1]['case_number'] + 1 push = { 'case_number': case_number, 'date': current_date, 'member_id': str(member.id), 'moderator_id': str(ctx.author.id), 'reason': reason } await self.bot.db.update_guild_config( ctx.guild.id, {'$push': { 'warns': push }}) if ctx.author != ctx.guild.me: await ctx.send(self.bot.accept) await self.send_log(ctx, member, reason, case_number) # apply punishment if punish: if cmd == 'bann': cmd = 'ban' ctx.command = self.bot.get_command(cmd) ctx.author = ctx.guild.me await ctx.invoke(ctx.command, member, reason=f'Hit warn limit {num_warns}')