async def cmd_disable(command: Command, commands_str: str): if not command.guild_id(): await command.respond_err("Cannot change permissions in DM channels.") return command_wrappers = get_command_wrappers(commands_str) for command_wrapper in command_wrappers: permissions.set_permission_filter(guild_id=command.guild_id(), command_wrapper=command_wrapper, permission_filter=None) await command.respond(response="✓ Command permissions changed.", embed=permissions_embed( guild_id=command.guild_id(), command_wrappers=command_wrappers))
async def receive_command(command: Command) -> bool: """Returns whether the received command was recognized and executed.""" if command.name not in registered_aliases: return False name = registered_aliases[command.name] func_wrapper = registered_commands[name] # Let the user know the command was recognized, and that a response should follow. await command.trigger_typing() if not permissions.can_execute(command): await command.respond( response = f"✗ Lacking permission.", embed = permissions_embed( # Can only lack permission in a guild. guild_id = command.guild_id(), command_wrappers = [func_wrapper] ) ) return False if len(func_wrapper.required_args) > len(command.args): missing_args = func_wrapper.required_args[len(command.args):] missing_arg_str = "`<" + "`>, <`".join(missing_args) + ">`" await command.respond_err(f"Missing required argument(s) {missing_arg_str}.") return False parsed_args = parse_args(command.args, arg_count=len(func_wrapper.required_args) + len(func_wrapper.optional_args)) await func_wrapper.execute(command, *parsed_args) return True
async def cmd_prefix(command: Command, symbol: str): if not command.guild_id(): await command.respond_err("Cannot change prefix in DM channels.") return if " " in symbol: await command.respond_err("`<symbol>` cannot include whitespace.") return # The discord message character limit is 2000. # Need enough characters to write `{prefix}prefix +` to reset it. len_limit = 2000 - len("prefix +") if len(symbol) > len_limit: await command.respond_err(f"`<symbol>` cannot exceed {len_limit} characters.") return old_prefix = command.prefix() set_prefix(command.guild_id(), symbol) await command.respond(f"✓ Command prefix changed from `{old_prefix}` to `{command.prefix()}`.")
def can_execute(command: Command) -> bool: """Returns whether the given command has permissions to execute within its current context (channel/author/roles of that guild). Administrators bypass any permission.""" command_wrapper = commands.get_wrapper(command.name) perm_filter = get_permission_filter(command.guild_id(), command_wrapper) has_permission = filter_context.test( perm_filter, command.context) if perm_filter else False caller = command.context.author # The `guild_permissions` attribute is only available in guilds, for DM channels we skip this. is_admin_or_dm = not hasattr( caller, "guild_permissions") or caller.guild_permissions.administrator return has_permission or is_admin_or_dm
async def cmd_enable(command: Command, commands_str: str, perms_filter: Optional[str]=None): if not command.guild_id(): await command.respond_err("Cannot change permissions in DM channels.") return if perms_filter and not await validate_filter(command, perms_filter, filter_context): # `validate_filter` responds for us. return command_wrappers = get_command_wrappers(commands_str) for command_wrapper in command_wrappers: permissions.set_permission_filter( guild_id = command.guild_id(), command_wrapper = command_wrapper, permission_filter = perms_filter or f"role:<@&{command.context.guild.default_role.id}>" ) await command.respond( response = "✓ Command permissions changed.", embed = permissions_embed( guild_id = command.guild_id(), command_wrappers = command_wrappers ) )
def test_guild_id_dm_channel(): command = Command("test", context=MockMessage(channel=MockDMChannel())) assert command.guild_id() is None
def test_guild_id(): command = Command("test", context=MockMessage( channel=MockChannel(_id=6, guild=MockGuild(_id=7)))) assert command.guild_id() == 7