예제 #1
0
    async def convert(self, ctx: commands.Context,
                      argument: str) -> discord.Role:
        try:
            basic_role = await super().convert(ctx, argument)
        except commands.BadArgument:
            pass
        else:
            return basic_role
        guild = ctx.guild
        result = [(r[2], r[1]) for r in process.extract(
            argument,
            {r: unidecode(r.name)
             for r in guild.roles},
            limit=None,
            score_cutoff=75,
        )]
        if not result:
            raise commands.BadArgument(
                f'Role "{argument}" not found.' if self.response else None)

        sorted_result = sorted(result, key=lambda r: r[1], reverse=True)
        return sorted_result[0][0]
예제 #2
0
 async def search(cls, ctx, argument, globally, _):
     is_owner = await ctx.bot.is_owner(ctx.author)
     config = ctx.cog.config
     guilds = ctx.bot.guilds.copy() if is_owner or globally else [ctx.guild]
     result = set()
     for guild in guilds:
         if not await cls.guild_filter(ctx, is_owner, guild):
             continue
         for channel in guild.text_channels.copy():
             if cls.channel_filter(ctx, is_owner, channel, argument):
                 if not await config.channel(channel).blacklisted():
                     result.add(channel)
         for member in guild.members.copy():
             if member not in result and cls.user_filter(
                     ctx, is_owner, member, argument):
                 if not await config.user(member).blacklisted():
                     result.add(member)
     if not result:
         raise commands.BadArgument(
             _("Destination {!r} not found. Either I don't have access or it has been blacklisted."
               ).format(argument))
     return list(result)
예제 #3
0
    async def convert(cls, ctx: commands.Context, arg: str):
        """Find best match for member from recent messages."""
        if not ctx.guild:
            return

        # Handle special 'me' user:
        if arg.lower() == "me":
            return cls(ctx.author)

        # Prefer exact match:
        try:
            match = await commands.MemberConverter().convert(ctx, arg)
            return cls(match)
        except commands.BadArgument:
            match = None

        pat = re.escape(arg)

        # Try partial match on name or nick from recent messages for this guild.
        cached_members = {
            str(msg.author.name): msg.author
            for msg in ctx.bot.cached_messages if not msg.author.bot
            and ctx.guild == msg.guild and ctx.guild.get_member(msg.author.id)
        }
        matches = [
            cached_members[name] for name in cached_members
            if re.match(pat, name, re.I) or (
                cached_members[name].nick
                and re.match(pat, cached_members[name].nick, re.I))
        ]
        # First match is considered the best match (i.e. more recently active)
        match = ctx.guild.get_member(matches[0].id) if matches else None
        if match:
            return cls(match)

        # Otherwise no partial match from context, & no exact match
        raise commands.BadArgument(
            "No recently active member found. Try exact username or nickname.")
예제 #4
0
    async def blocklist_channel(
        self, ctx: commands.Context, *, channel: discord.TextChannel = None
    ):
        """
        Blocklists the current channel or the specified channel.

        Can also blocklist DM channels.
        """
        if channel and not ctx.guild:
            raise commands.BadArgument(_("You cannot blocklist a channel in DMs."))
        if not ctx.guild:
            channel = ctx.author
            group = self.config.user(channel)
        else:
            channel = channel or ctx.channel
            group = self.config.channel(channel)
        blacklisted = not await group.blacklisted()
        await group.blacklisted.set(blacklisted)
        await ctx.send(
            _("Channel is {} blocklisted.").format("now" if blacklisted else "no longer")
        )
        if blacklisted:
            await self.close_rifts(ctx.author, channel)
예제 #5
0
    async def convert(self, ctx: commands.Context, argument: str):
        guild_raw = argument
        target_guild = None

        if guild_raw.isnumeric():
            guild_raw = int(guild_raw)
            try:
                target_guild = ctx.bot.get_guild(guild_raw)
            except Exception:
                target_guild = None
            guild_raw = str(guild_raw)
        if target_guild is None:
            try:
                target_guild = await commands.GuildConverter.convert(ctx, guild_raw)
            except Exception:
                target_guild = None
        if target_guild is None:
            try:
                target_guild = await ctx.bot.fetch_guild(guild_raw)
            except Exception:
                target_guild = None
        if target_guild is None:
            raise commands.BadArgument(f"Invalid Guild: {argument}")
        return target_guild
예제 #6
0
def is_all(argument):
    if argument.lower() == "all":
        return True
    raise commands.BadArgument()
예제 #7
0
 async def convert(cls, _ctx: commands.Context, arg: str) -> DomainsMode:
     try:
         return DomainsMode(int(arg))
     except ValueError:
         raise commands.BadArgument(
             f"{inline(arg)} is not a valid domains list mode.")
예제 #8
0
 async def convert(self, ctx: GuildContext, argument: str) -> str:
     if (match := URL_RE.search(argument)) is not None:
         raise commands.BadArgument(
             f"It looks like you're trying to add a full URL (<{argument}>)"
             f" rather than just the domain name ({match.group(2)}).\n"
             "Please try again with just the domain name.")
예제 #9
0
def nonnegative_int(argument):
    i = int(argument)
    if i < 0:
        raise commands.BadArgument("Argument must not be negative.")
    return i
예제 #10
0
 async def convert(self, ctx: commands.Context, argument: str) -> str:
     try:
         await ctx.cog.validate_tagscript(ctx, argument)
     except SlashTagException as e:
         raise commands.BadArgument(str(e))
     return argument
예제 #11
0
    async def convert(
        self, ctx: commands.Context, argument: str
    ) -> Tuple[Optional[str], discord.User, Optional[discord.Guild], bool]:

        target_scope: Optional[str] = None
        target_user: Optional[Union[discord.Member, discord.User]] = None
        target_guild: Optional[discord.Guild] = None
        specified_user = False

        argument = argument.replace("—", "--")

        command, *arguments = argument.split(" -- ")
        if arguments:
            argument = " -- ".join(arguments)
        else:
            command = ""

        parser = NoExitParser(description="Playlist Scope Parsing.",
                              add_help=False)
        parser.add_argument("--scope", nargs="*", dest="scope", default=[])
        parser.add_argument("--guild", nargs="*", dest="guild", default=[])
        parser.add_argument("--server", nargs="*", dest="guild", default=[])
        parser.add_argument("--author", nargs="*", dest="author", default=[])
        parser.add_argument("--user", nargs="*", dest="author", default=[])
        parser.add_argument("--member", nargs="*", dest="author", default=[])

        if not command:
            parser.add_argument("command", nargs="*")

        try:
            vals = vars(parser.parse_args(argument.split()))
        except Exception as exc:
            raise commands.BadArgument() from exc

        if vals["scope"]:
            scope_raw = " ".join(vals["scope"]).strip()
            scope = scope_raw.upper().strip()
            valid_scopes = PlaylistScope.list() + [
                "GLOBAL",
                "GUILD",
                "AUTHOR",
                "USER",
                "SERVER",
                "MEMBER",
                "BOT",
            ]
            if scope not in valid_scopes:
                raise commands.ArgParserFailure("--scope",
                                                scope_raw,
                                                custom_help=_(_SCOPE_HELP))
            target_scope = standardize_scope(scope)
        elif "--scope" in argument and not vals["scope"]:
            raise commands.ArgParserFailure("--scope",
                                            _("Nothing"),
                                            custom_help=_(_SCOPE_HELP))

        is_owner = await ctx.bot.is_owner(ctx.author)
        guild = vals.get("guild", None) or vals.get("server", None)
        if is_owner and guild:
            server_error = ""
            target_guild = None
            guild_raw = " ".join(guild).strip()
            try:
                target_guild = await global_unique_guild_finder(ctx, guild_raw)
            except TooManyMatches as err:
                server_error = f"{err}\n"
            except NoMatchesFound as err:
                server_error = f"{err}\n"
            if target_guild is None:
                raise commands.ArgParserFailure(
                    "--guild",
                    guild_raw,
                    custom_help=f"{server_error}{_(_GUILD_HELP)}")

        elif not is_owner and (guild or any(x in argument
                                            for x in ["--guild", "--server"])):
            raise commands.BadArgument(_("You cannot use `--guild`"))
        elif any(x in argument for x in ["--guild", "--server"]):
            raise commands.ArgParserFailure("--guild",
                                            _("Nothing"),
                                            custom_help=_(_GUILD_HELP))

        author = vals.get("author", None) or vals.get(
            "user", None) or vals.get("member", None)
        if author:
            user_error = ""
            target_user = None
            user_raw = " ".join(author).strip()
            try:
                target_user = await global_unique_user_finder(
                    ctx, user_raw, guild=target_guild)
                specified_user = True
            except TooManyMatches as err:
                user_error = f"{err}\n"
            except NoMatchesFound as err:
                user_error = f"{err}\n"

            if target_user is None:
                raise commands.ArgParserFailure(
                    "--author",
                    user_raw,
                    custom_help=f"{user_error}{_(_USER_HELP)}")
        elif any(x in argument for x in ["--author", "--user", "--member"]):
            raise commands.ArgParserFailure("--scope",
                                            _("Nothing"),
                                            custom_help=_(_USER_HELP))

        target_scope: Optional[str] = target_scope or None
        target_user: Union[discord.Member,
                           discord.User] = target_user or ctx.author
        target_guild: discord.Guild = target_guild or ctx.guild

        return target_scope, target_user, target_guild, specified_user
예제 #12
0
 async def convert(cls, ctx: commands.Context, arg: str) -> discord.Role:
     role: discord.Role = await _role_converter.convert(ctx, arg)
     if role.is_default():
         raise commands.BadArgument(
             "You can't set this for the everyone role")
     return role
예제 #13
0
 def check_data_type(self, ctx: commands.Context, data, *, data_type=dict):
     if not isinstance(data, data_type):
         raise commands.BadArgument(
             f"This doesn't seem to be properly formatted embed {self.conversion_type.upper()}. "
             f"Refer to the link on `{ctx.clean_prefix}help {ctx.command.qualified_name}`."
         )
예제 #14
0

class CogOrCOmmand(NamedTuple):
    stype: str
    obj: str

    @classmethod
    async def convert(cls, ctx: commands.Context, arg: str):
        # mypy doesn't do type narrowing for the walrus yet
        if com := ctx.bot.get_command(arg):
            assert com, "mypy"  # nosec
            return cls("command", com.qualified_name)
        if cog := ctx.bot.get_cog(arg):
            assert cog, "mypy"  # nosec
            return cls("cog", cog.__class__.__name__)
        raise commands.BadArgument(
            'Cog or Command "{arg}" not found.'.format(arg=arg))


class TrinaryBool(NamedTuple):
    state: Union[bool, None]

    @classmethod
    async def convert(cls, ctx: commands.Context, arg: str):
        try:
            ret = {"allow": True, "deny": False, "clear": None}[arg.lower()]
        except KeyError:
            raise commands.BadArgument(
                "Was expecting one of `allow`, `deny`, or `clear`, got {arg}".
                format(arg=arg))
        else:
            return cls(ret)
예제 #15
0
 async def convert(cls, ctx: commands.Context, arg: str):
     ret = ctx.bot.get_command(arg)
     if ret:
         return cls(ret)
     raise commands.BadArgument(
         'Command "{arg}" not found.'.format(arg=arg))
예제 #16
0
    async def user(self,
                   ctx: commands.Context,
                   user: str,
                   number: positive_int,
                   delete_pinned: bool = False):
        """Delete the last X messages from a specified user.

        Examples:
            - `[p]cleanup user @Twentysix 2`
            - `[p]cleanup user Red 6`

        **Arguments:**

        - `<user>` The user whose messages are to be cleaned up.
        - `<number>` The max number of messages to cleanup. Must be a positive integer.
        - `<delete_pinned>` Whether to delete pinned messages or not. Defaults to False
        """
        channel = ctx.channel

        member = None
        try:
            member = await commands.MemberConverter().convert(ctx, user)
        except commands.BadArgument:
            try:
                _id = int(user)
            except ValueError:
                raise commands.BadArgument()
        else:
            _id = member.id

        author = ctx.author

        if number > 100:
            cont = await self.check_100_plus(ctx, number)
            if not cont:
                return

        def check(m):
            if m.author.id == _id:
                return True
            else:
                return False

        to_delete = await self.get_messages_for_deletion(
            channel=channel,
            number=number,
            check=check,
            before=ctx.message,
            delete_pinned=delete_pinned,
        )
        to_delete.append(ctx.message)

        reason = ("{}({}) deleted {} messages "
                  " made by {}({}) in channel {}."
                  "".format(
                      author.name,
                      author.id,
                      humanize_number(len(to_delete), override_locale="en_US"),
                      member or "???",
                      _id,
                      channel.name,
                  ))
        log.info(reason)

        await mass_purge(to_delete, channel)
예제 #17
0
 async def convert(self, ctx, argument):
     if argument.title() not in all_timezones:
         raise commands.BadArgument(
             "Couldn't find that timezone. Look for it in "
             "https://en.wikipedia.org/wiki/List_of_tz_database_time_zones")
     return argument
예제 #18
0
 async def convert(self, ctx: commands.Context, argument: str) -> str:
     if len(argument) > MAX_PREFIX_LENGTH and not await ctx.bot.is_owner(
             ctx.author):
         raise commands.BadArgument(
             f"Prefixes cannot be above {MAX_PREFIX_LENGTH} in length.")
     return argument
예제 #19
0
 def get_content(self, data: dict, *, content: str = None) -> Optional[str]:
     content = data.pop("content", content)
     if content is not None and not self.allow_content:
         raise commands.BadArgument(
             "The `content` field is not supported for this command.")
     return content
예제 #20
0
 async def convert(cls, ctx, argument: str) -> "Options":
     argument = argument.upper().rstrip("S")
     try:
         return cls[argument]
     except KeyError as ke:
         raise commands.BadArgument() from ke
예제 #21
0
class StringToEmbed(commands.Converter):
    def __init__(self,
                 *,
                 conversion_type: str = "json",
                 validate: bool = True,
                 content: bool = False):
        self.CONVERSION_TYPES = {
            "json": self.load_from_json,
            "yaml": self.load_from_yaml,
        }

        self.validate = validate
        self.conversion_type = conversion_type.lower()
        self.allow_content = content
        try:
            self.converter = self.CONVERSION_TYPES[self.conversion_type]
        except KeyError as exc:
            raise ValueError(
                f"{conversion_type} is not a valid conversion type for Embed conversion."
            ) from exc

    async def convert(self, ctx: commands.Context,
                      argument: str) -> discord.Embed:
        data = argument.strip("`")
        data = await self.converter(ctx, data)
        content = self.get_content(data)

        if data.get("embed"):
            data = data["embed"]
        elif data.get("embeds"):
            data = data.get("embeds")[0]
        self.check_data_type(ctx, data)

        fields = await self.create_embed(ctx, data, content=content)
        content = fields["content"]
        embed = fields["embed"]
        if self.validate:
            await self.validate_embed(ctx, embed, content=content)
        return embed

    def check_data_type(self, ctx: commands.Context, data, *, data_type=dict):
        if not isinstance(data, data_type):
            raise commands.BadArgument(
                f"This doesn't seem to be properly formatted embed {self.conversion_type.upper()}. "
                f"Refer to the link on `{ctx.clean_prefix}help {ctx.command.qualified_name}`."
            )

    async def load_from_json(self, ctx: commands.Context, data: str,
                             **kwargs) -> dict:
        try:
            data = json.loads(data)
        except json.decoder.JSONDecodeError as error:
            await self.embed_convert_error(ctx, "JSON Parse Error", error)
        self.check_data_type(ctx, data, **kwargs)
        return data

    async def load_from_yaml(self, ctx: commands.Context, data: str,
                             **kwargs) -> dict:
        try:
            data = yaml.safe_load(data)
        except Exception as error:
            await self.embed_convert_error(ctx, "YAML Parse Error", error)
        self.check_data_type(ctx, data, **kwargs)
        return data

    def get_content(self, data: dict, *, content: str = None) -> Optional[str]:
        content = data.pop("content", content)
        if content is not None and not self.allow_content:
            raise commands.BadArgument(
                "The `content` field is not supported for this command.")
        return content

    async def create_embed(self,
                           ctx: commands.Context,
                           data: dict,
                           *,
                           content: str = None
                           ) -> Dict[str, Union[discord.Embed, str]]:
        content = self.get_content(data, content=content)

        if timestamp := data.get("timestamp"):
            data["timestamp"] = timestamp.strip("Z")
        try:
            e = discord.Embed.from_dict(data)
            length = len(e)
        except Exception as error:
            await self.embed_convert_error(ctx, "Embed Parse Error", error)

        # Embed.__len__ may error which is why it is included in the try/except
        if length > 6000:
            raise commands.BadArgument(
                f"Embed size exceeds Discord limit of 6000 characters ({length})."
            )
        return {"embed": e, "content": content}
예제 #22
0
 async def convert(self, ctx, value):
     if value.lower() == "all":
         return "all"
     raise commands.BadArgument('Input was not "all".')
예제 #23
0
 async def convert(self, ctx: commands.Context, argument: str) -> SlashTag:
     tag = self.get_tag(ctx, argument)
     if not tag:
         raise commands.BadArgument(
             f'Slash tag "{escape_mentions(argument)}" not found.')
     return tag
예제 #24
0
    async def convert(cls, ctx, arg):
        if arg[:3].lower() == "moo":
            return cls()

        raise commands.BadArgument()
예제 #25
0
 def error(self, message):
     raise commands.BadArgument()
예제 #26
0
 def __getattr__(self, arg):
     raise commands.BadArgument(arg)
예제 #27
0
    async def convert(
        self, ctx: commands.Context, argument: str
    ) -> Tuple[str, discord.User, Optional[discord.Guild], bool, str,
               discord.User, Optional[discord.Guild], bool, ]:

        target_scope: Optional[str] = None
        target_user: Optional[Union[discord.Member, discord.User]] = None
        target_guild: Optional[discord.Guild] = None
        specified_target_user = False

        source_scope: Optional[str] = None
        source_user: Optional[Union[discord.Member, discord.User]] = None
        source_guild: Optional[discord.Guild] = None
        specified_source_user = False

        argument = argument.replace("—", "--")

        command, *arguments = argument.split(" -- ")
        if arguments:
            argument = " -- ".join(arguments)
        else:
            command = ""

        parser = NoExitParser(description="Playlist Scope Parsing.",
                              add_help=False)

        parser.add_argument("--to-scope",
                            nargs="*",
                            dest="to_scope",
                            default=[])
        parser.add_argument("--to-guild",
                            nargs="*",
                            dest="to_guild",
                            default=[])
        parser.add_argument("--to-server",
                            nargs="*",
                            dest="to_server",
                            default=[])
        parser.add_argument("--to-author",
                            nargs="*",
                            dest="to_author",
                            default=[])
        parser.add_argument("--to-user", nargs="*", dest="to_user", default=[])
        parser.add_argument("--to-member",
                            nargs="*",
                            dest="to_member",
                            default=[])

        parser.add_argument("--from-scope",
                            nargs="*",
                            dest="from_scope",
                            default=[])
        parser.add_argument("--from-guild",
                            nargs="*",
                            dest="from_guild",
                            default=[])
        parser.add_argument("--from-server",
                            nargs="*",
                            dest="from_server",
                            default=[])
        parser.add_argument("--from-author",
                            nargs="*",
                            dest="from_author",
                            default=[])
        parser.add_argument("--from-user",
                            nargs="*",
                            dest="from_user",
                            default=[])
        parser.add_argument("--from-member",
                            nargs="*",
                            dest="from_member",
                            default=[])

        if not command:
            parser.add_argument("command", nargs="*")

        try:
            vals = vars(parser.parse_args(argument.split()))
        except Exception as exc:
            raise commands.BadArgument() from exc

        is_owner = await ctx.bot.is_owner(ctx.author)
        valid_scopes = PlaylistScope.list() + [
            "GLOBAL",
            "GUILD",
            "AUTHOR",
            "USER",
            "SERVER",
            "MEMBER",
            "BOT",
        ]

        if vals["to_scope"]:
            to_scope_raw = " ".join(vals["to_scope"]).strip()
            to_scope = to_scope_raw.upper().strip()
            if to_scope not in valid_scopes:
                raise commands.ArgParserFailure("--to-scope",
                                                to_scope_raw,
                                                custom_help=_SCOPE_HELP)
            target_scope = standardize_scope(to_scope)
        elif "--to-scope" in argument and not vals["to_scope"]:
            raise commands.ArgParserFailure("--to-scope",
                                            _("Nothing"),
                                            custom_help=_(_SCOPE_HELP))

        if vals["from_scope"]:
            from_scope_raw = " ".join(vals["from_scope"]).strip()
            from_scope = from_scope_raw.upper().strip()

            if from_scope not in valid_scopes:
                raise commands.ArgParserFailure("--from-scope",
                                                from_scope_raw,
                                                custom_help=_SCOPE_HELP)
            source_scope = standardize_scope(from_scope)
        elif "--from-scope" in argument and not vals["to_scope"]:
            raise commands.ArgParserFailure("--to-scope",
                                            _("Nothing"),
                                            custom_help=_(_SCOPE_HELP))

        to_guild = vals.get("to_guild", None) or vals.get("to_server", None)
        if is_owner and to_guild:
            target_server_error = ""
            target_guild = None
            to_guild_raw = " ".join(to_guild).strip()
            try:
                target_guild = await global_unique_guild_finder(
                    ctx, to_guild_raw)
            except TooManyMatches as err:
                target_server_error = f"{err}\n"
            except NoMatchesFound as err:
                target_server_error = f"{err}\n"
            if target_guild is None:
                raise commands.ArgParserFailure(
                    "--to-guild",
                    to_guild_raw,
                    custom_help=f"{target_server_error}{_(_GUILD_HELP)}",
                )
        elif not is_owner and (to_guild
                               or any(x in argument
                                      for x in ["--to-guild", "--to-server"])):
            raise commands.BadArgument(_("You cannot use `--to-server`"))
        elif any(x in argument for x in ["--to-guild", "--to-server"]):
            raise commands.ArgParserFailure("--to-server",
                                            _("Nothing"),
                                            custom_help=_(_GUILD_HELP))

        from_guild = vals.get("from_guild", None) or vals.get(
            "from_server", None)
        if is_owner and from_guild:
            source_server_error = ""
            source_guild = None
            from_guild_raw = " ".join(from_guild).strip()
            try:
                source_guild = await global_unique_guild_finder(
                    ctx, from_guild_raw)
            except TooManyMatches as err:
                source_server_error = f"{err}\n"
            except NoMatchesFound as err:
                source_server_error = f"{err}\n"
            if source_guild is None:
                raise commands.ArgParserFailure(
                    "--from-guild",
                    from_guild_raw,
                    custom_help=f"{source_server_error}{_(_GUILD_HELP)}",
                )
        elif not is_owner and (from_guild or any(
                x in argument for x in ["--from-guild", "--from-server"])):
            raise commands.BadArgument(_("You cannot use `--from-server`"))
        elif any(x in argument for x in ["--from-guild", "--from-server"]):
            raise commands.ArgParserFailure("--from-server",
                                            _("Nothing"),
                                            custom_help=_(_GUILD_HELP))

        to_author = (vals.get("to_author", None) or vals.get("to_user", None)
                     or vals.get("to_member", None))
        if to_author:
            target_user_error = ""
            target_user = None
            to_user_raw = " ".join(to_author).strip()
            try:
                target_user = await global_unique_user_finder(
                    ctx, to_user_raw, guild=target_guild)
                specified_target_user = True
            except TooManyMatches as err:
                target_user_error = f"{err}\n"
            except NoMatchesFound as err:
                target_user_error = f"{err}\n"
            if target_user is None:
                raise commands.ArgParserFailure(
                    "--to-author",
                    to_user_raw,
                    custom_help=f"{target_user_error}{_(_USER_HELP)}")
        elif any(x in argument
                 for x in ["--to-author", "--to-user", "--to-member"]):
            raise commands.ArgParserFailure("--to-user",
                                            _("Nothing"),
                                            custom_help=_(_USER_HELP))

        from_author = (vals.get("from_author", None)
                       or vals.get("from_user", None)
                       or vals.get("from_member", None))
        if from_author:
            source_user_error = ""
            source_user = None
            from_user_raw = " ".join(from_author).strip()
            try:
                source_user = await global_unique_user_finder(
                    ctx, from_user_raw, guild=target_guild)
                specified_target_user = True
            except TooManyMatches as err:
                source_user_error = f"{err}\n"
            except NoMatchesFound as err:
                source_user_error = f"{err}\n"
            if source_user is None:
                raise commands.ArgParserFailure(
                    "--from-author",
                    from_user_raw,
                    custom_help=f"{source_user_error}{_(_USER_HELP)}",
                )
        elif any(x in argument
                 for x in ["--from-author", "--from-user", "--from-member"]):
            raise commands.ArgParserFailure("--from-user",
                                            _("Nothing"),
                                            custom_help=_(_USER_HELP))

        target_scope = target_scope or PlaylistScope.GUILD.value
        target_user = target_user or ctx.author
        target_guild = target_guild or ctx.guild

        source_scope = source_scope or PlaylistScope.GUILD.value
        source_user = source_user or ctx.author
        source_guild = source_guild or ctx.guild

        return (
            source_scope,
            source_user,
            source_guild,
            specified_source_user,
            target_scope,
            target_user,
            target_guild,
            specified_target_user,
        )
예제 #28
0
    obj: Union[commands.Command, commands.Cog]

    # noinspection PyArgumentList
    @classmethod
    async def convert(cls, ctx: commands.Context, arg: str) -> "CogOrCommand":
        ret = None
        if cog := ctx.bot.get_cog(arg):
            ret = cls(type="COG", name=cog.qualified_name, obj=cog)

        elif cmd := ctx.bot.get_command(arg):
            ret = cls(type="COMMAND", name=cmd.qualified_name, obj=cmd)

        if ret:
            if isinstance(ret.obj, commands.commands._RuleDropper):
                raise commands.BadArgument(
                    "You cannot apply permission rules to this cog or command."
                )
            return ret

        raise commands.BadArgument(
            _('Cog or command "{name}" not found. Please note that this is case sensitive.'
              ).format(name=arg))


def RuleType(arg: str) -> bool:
    if arg.lower() in ("allow", "whitelist", "allowed"):
        return True
    if arg.lower() in ("deny", "blacklist", "denied"):
        return False

    raise commands.BadArgument(
예제 #29
0
    async def rift_search(self, ctx: commands.Context, *, scope: str = "channel"):
        """
        Provides info about rifts opened in the specified scope.
        """
        author = Limited(message=ctx.message) if ctx.guild else ctx.author
        try:
            scoped = {
                "user": author,
                "member": author,
                "author": author,
                "channel": ctx.channel if ctx.guild else ctx.author,
                "guild": ctx.guild,
                "server": ctx.guild,
                "global": None,
            }[scope.casefold()]
        except KeyError:
            raise commands.BadArgument(
                _("Invalid scope. Scope must be author, channel, guild, server, or global.")
            )

        if not scoped and not await ctx.bot.is_owner(ctx.author):
            raise commands.CheckFailure()
        if scoped == ctx.guild and not await mod.is_admin_or_superior(ctx.bot, ctx.author):
            raise commands.CheckFailure()

        def check(vector):
            if not scoped:
                return True
            if scoped in vector:
                return True
            if scoped in map(lambda c: getattr(c, "guild", None), vector):
                return True
            return False

        unique_rifts: Set[Vector[Messageable]] = set()
        for source, destination in self.rifts.vectors():
            if check((source, destination)) and (destination, source) not in unique_rifts:
                unique_rifts.add((source, destination))
        total_rifts = len(unique_rifts)
        if not total_rifts:
            return await ctx.send(_("No rifts are connected to this scope."))

        pages: List[discord.Embed] = []
        for i, (source, destination) in enumerate(unique_rifts, 1):
            if source in self.rifts.get(destination, ()):
                delim = "⟷"
            else:
                delim = "⟶"
            embed = discord.Embed(
                title=f"{source} {delim} {destination}", color=await ctx.embed_color()
            )
            if topic := getattr(destination, "topic", None):
                embed.description = topic
            try:
                members = destination.users
            except AttributeError:
                members = destination.members
            # TODO: format and sort members
            member_str = humanize_list(list(map(str, members)))
            short_member_str = next(pagify(member_str, delims=[","]))
            if len(member_str) != len(short_member_str):
                short_member_str += " …"
            embed.add_field(name=f"Connected from {destination}", value=member_str)
            embed.set_footer(text=f"Rift {i} of {total_rifts}")
            pages.append(embed)
예제 #30
0
파일: cleanup.py 프로젝트: Veestire/botbase
    async def user(self,
                   ctx: commands.Context,
                   user: str,
                   number: int,
                   delete_pinned: bool = False):
        """Deletes last X messages from specified user.

        Examples:
        cleanup user @\u200bTwentysix 2
        cleanup user Red 6"""
        channel = ctx.channel
        if not channel.permissions_for(ctx.guild.me).manage_messages:
            await ctx.send("I need the Manage Messages permission to do this.")
            return

        member = None
        try:
            member = await commands.converter.MemberConverter().convert(
                ctx, user)
        except commands.BadArgument:
            try:
                _id = int(user)
            except ValueError:
                raise commands.BadArgument()
        else:
            _id = member.id

        author = ctx.author
        is_bot = self.bot.user.bot

        if number > 100:
            cont = await self.check_100_plus(ctx, number)
            if not cont:
                return

        def check(m):
            if m.author.id == _id:
                return True
            elif m == ctx.message:
                return True
            else:
                return False

        to_delete = await self.get_messages_for_deletion(
            ctx,
            channel,
            number,
            check=check,
            limit=1000,
            before=ctx.message,
            delete_pinned=delete_pinned,
        )
        reason = ("{}({}) deleted {} messages "
                  " made by {}({}) in channel {}."
                  "".format(author.name, author.id, len(to_delete), member
                            or "???", _id, channel.name))
        log.info(reason)

        if is_bot:
            # For whatever reason the purge endpoint requires manage_messages
            await mass_purge(to_delete, channel)
        else:
            await slow_deletion(to_delete)