Exemple #1
0
    async def send_leaderboard(self, ctx: commands.Context, data: dict, key: str, top: int):
        """Send the leaderboard from the given data.

        Parameters
        ----------
        ctx : commands.Context
            The context to send the leaderboard to.
        data : dict
            The data for the leaderboard. This must map `discord.Member` ->
            `dict`.
        key : str
            The field to sort the data by. Can be ``wins``, ``total_score``,
            ``games`` or ``average_score``.
        top : int
            The number of members to display on the leaderboard.

        Returns
        -------
        `list` of `discord.Message`
            The sent leaderboard messages.

        """
        if not data:
            await ctx.send("There are no scores on record!")
            return
        leaderboard = self._get_leaderboard(data, key, top)
        ret = []
        for page in pagify(leaderboard):
            ret.append(await ctx.send(box(page, lang="py")))
        return ret
Exemple #2
0
    async def cc_list(self, ctx):
        """Shows custom commands list"""

        response = await CommandObj.get_commands(self.config.guild(ctx.guild))

        if not response:
            await ctx.send(
                _("There are no custom commands in this server."
                  " Use `{}` to start adding some.").format(
                      "{}customcom add".format(ctx.prefix)))
            return

        results = []

        for command, body in response.items():
            responses = body["response"]
            if isinstance(responses, list):
                result = ", ".join(responses)
            elif isinstance(responses, str):
                result = responses
            else:
                continue
            results.append("{command:<15} : {result}".format(command=command,
                                                             result=result))

        commands = "\n".join(results)

        if len(commands) < 1500:
            await ctx.send(box(commands))
        else:
            for page in pagify(commands, delims=[" ", "\n"]):
                await ctx.author.send(box(page))
Exemple #3
0
    async def discover_guild(
        self,
        author: discord.User,
        *,
        mod: bool = False,
        permissions: Union[discord.Permissions, dict] = None,
        prompt: str = "",
    ):
        """
        discovers which of shared guilds between the bot
        and provided user based on conditions (mod or permissions is an or)

        prompt is for providing a user prompt for selection
        """
        shared_guilds = []
        if permissions is None:
            perms = discord.Permissions()
        elif isinstance(permissions, discord.Permissions):
            perms = permissions
        else:
            perms = discord.Permissions(**permissions)

        for guild in self.bot.guilds:
            x = guild.get_member(author.id)
            if x is not None:
                if await self.internal_filter(x, mod, perms):
                    shared_guilds.append(guild)
        if len(shared_guilds) == 0:
            raise ValueError("No Qualifying Shared Guilds")
        if len(shared_guilds) == 1:
            return shared_guilds[0]
        output = ""
        guilds = sorted(shared_guilds, key=lambda g: g.name)
        for i, guild in enumerate(guilds, 1):
            output += "{}: {}\n".format(i, guild.name)
        output += "\n{}".format(prompt)

        for page in pagify(output, delims=["\n"]):
            dm = await author.send(box(page))

        def pred(m):
            return m.author == author and m.channel == dm.channel

        try:
            message = await self.bot.wait_for("message", check=pred, timeout=45)
        except asyncio.TimeoutError:
            await author.send(_("You took too long to select. Try again later."))
            return None

        try:
            message = int(message.content.strip())
            guild = guilds[message - 1]
        except (ValueError, IndexError):
            await author.send(_("That wasn't a valid choice."))
            return None
        else:
            return guild
Exemple #4
0
    async def _repo_list(self, ctx):
        """
        Lists all installed repos.
        """
        repos = self._repo_manager.get_all_repo_names()
        repos = sorted(repos, key=str.lower)
        joined = _("Installed Repos:\n\n")
        for repo_name in repos:
            repo = self._repo_manager.get_repo(repo_name)
            joined += "+ {}: {}\n".format(repo.name, repo.short or "")

        for page in pagify(joined, ["\n"], shorten_by=16):
            await ctx.send(box(page.lstrip(" "), lang="diff"))
Exemple #5
0
    async def message_forwarder(*,
                                destination: discord.abc.Messageable,
                                content: str = None,
                                embed=None,
                                files=[]) -> List[discord.Message]:
        """
        This does the actual sending, use this instead of a full tunnel
        if you are using command initiated reactions instead of persistent
        event based ones

        Parameters
        ----------
        destination: `discord.abc.Messageable`
            Where to send
        content: `str`
            The message content
        embed: `discord.Embed`
            The embed to send
        files: `list` of `discord.File`
            A list of files to send.

        Returns
        -------
        list of `discord.Message`
            The `discord.Message`\ (s) sent as a result

        Raises
        ------
        discord.Forbidden
            see `discord.abc.Messageable.send`
        discord.HTTPException
            see `discord.abc.Messageable.send`
        """
        rets = []
        files = files if files else None
        if content:
            for page in pagify(content):
                rets.append(await destination.send(page,
                                                   files=files,
                                                   embed=embed))
                if files:
                    del files
                if embed:
                    del embed
        elif embed or files:
            rets.append(await destination.send(files=files, embed=embed))
        return rets
Exemple #6
0
    async def _filter(self, ctx: commands.Context):
        """Adds/removes words from filter

        Use double quotes to add/remove sentences
        Using this command with no subcommands will send
        the list of the server's filtered words."""
        if ctx.invoked_subcommand is None:
            server = ctx.guild
            author = ctx.author
            word_list = await self.settings.guild(server).filter()
            if word_list:
                words = ", ".join(word_list)
                words = _("Filtered in this server:") + "\n\n" + words
                try:
                    for page in pagify(words, delims=[" ", "\n"], shorten_by=8):
                        await author.send(page)
                except discord.Forbidden:
                    await ctx.send(_("I can't send direct messages to you."))
Exemple #7
0
 async def _cog_list(self, ctx, repo_name: Repo):
     """
     Lists all available cogs from a single repo.
     """
     installed = await self.installed_cogs()
     installed_str = ""
     if installed:
         installed_str = _("Installed Cogs:\n") + "\n".join([
             "- {}{}".format(i.name,
                             ": {}".format(i.short) if i.short else "")
             for i in installed if i.repo_name == repo_name.name
         ])
     cogs = repo_name.available_cogs
     cogs = _("Available Cogs:\n") + "\n".join([
         "+ {}: {}".format(c.name, c.short or "")
         for c in cogs if not (c.hidden or c in installed)
     ])
     cogs = cogs + "\n\n" + installed_str
     for page in pagify(cogs, ["\n"], shorten_by=16):
         await ctx.send(box(page.lstrip(" "), lang="diff"))
Exemple #8
0
    async def streamalert_list(self, ctx: commands.Context):
        """List all active stream alerts in this server."""
        streams_list = defaultdict(list)
        guild_channels_ids = [c.id for c in ctx.guild.channels]
        msg = _("Active alerts:\n\n")

        for stream in self.streams:
            for channel_id in stream.channels:
                if channel_id in guild_channels_ids:
                    streams_list[channel_id].append(stream.name.lower())

        if not streams_list:
            await ctx.send(_("There are no active alerts in this server."))
            return

        for channel_id, streams in streams_list.items():
            channel = ctx.guild.get_channel(channel_id)
            msg += "** - #{}**\n{}\n".format(channel, ", ".join(streams))

        for page in pagify(msg):
            await ctx.send(page)
Exemple #9
0
    async def warnings(self, ctx: commands.Context, userid: int = None):
        """Show warnings for the specified user.

        If userid is None, show warnings for the person running the command
        Note that showing warnings for users other than yourself requires
        appropriate permissions
        """
        if userid is None:
            user = ctx.author
        else:
            if not await is_admin_or_superior(self.bot, ctx.author):
                await ctx.send(
                    warning(
                        _("You are not allowed to check warnings for other users!"
                          )))
                return
            else:
                user = ctx.guild.get_member(userid)
                if user is None:  # user not in guild
                    user = namedtuple("Member", "id guild")(userid, ctx.guild)
        msg = ""
        member_settings = self.config.member(user)
        async with member_settings.warnings() as user_warnings:
            if not user_warnings.keys():  # no warnings for the user
                await ctx.send(_("That user has no warnings!"))
            else:
                for key in user_warnings.keys():
                    mod = ctx.guild.get_member(user_warnings[key]["mod"])
                    if mod is None:
                        mod = discord.utils.get(self.bot.get_all_members(),
                                                id=user_warnings[key]["mod"])
                        if mod is None:
                            mod = await self.bot.get_user_info(
                                user_warnings[key]["mod"])
                    msg += "{} point warning {} issued by {} for {}\n".format(
                        user_warnings[key]["points"], key, mod,
                        user_warnings[key]["description"])
                await ctx.send_interactive(
                    pagify(msg), box_lang="Warnings for {}".format(user))
Exemple #10
0
    async def format(self) -> dict:
        """Formats command for output.

        Returns a dict used to build embed"""
        emb = {"embed": {"title": "", "description": ""}, "footer": {"text": ""}, "fields": []}

        if self.is_cog():
            translator = getattr(self.command, "__translator__", lambda s: s)
            description = (
                inspect.cleandoc(translator(self.command.__doc__))
                if self.command.__doc__
                else EMPTY_STRING
            )
        else:
            description = self.command.description

        if not description == "" and description is not None:
            description = "*{0}*".format(description)

        if description:
            # <description> portion
            emb["embed"]["description"] = description[:2046]

        tagline = await self.context.bot.db.help.tagline()
        if tagline:
            footer = tagline
        else:
            footer = self.get_ending_note()
        emb["footer"]["text"] = footer

        if isinstance(self.command, discord.ext.commands.core.Command):
            # <signature portion>
            emb["embed"]["title"] = emb["embed"]["description"]
            emb["embed"]["description"] = "`Syntax: {0}`".format(self.get_command_signature())

            # <long doc> section
            if self.command.help:
                splitted = self.command.help.split("\n\n")
                name = "__{0}__".format(splitted[0])
                value = "\n\n".join(splitted[1:]).replace("[p]", self.clean_prefix)
                if value == "":
                    value = EMPTY_STRING
                field = EmbedField(name[:252], value[:1024], False)
                emb["fields"].append(field)

            # end it here if it's just a regular command
            if not self.has_subcommands():
                return emb

        def category(tup):
            # Turn get cog (Category) name from cog/list tuples
            cog = tup[1].cog_name
            return "**__{0}:__**".format(cog) if cog is not None else "**__\u200bNo Category:__**"

        # Get subcommands for bot or category
        filtered = await self.filter_command_list()

        if self.is_bot():
            # Get list of non-hidden commands for bot.
            data = sorted(filtered, key=category)
            for category, commands_ in itertools.groupby(data, key=category):
                commands_ = sorted(commands_)
                if len(commands_) > 0:
                    for i, page in enumerate(
                        pagify(self._add_subcommands(commands_), page_length=1000)
                    ):
                        title = category if i < 1 else f"{category} (continued)"
                        field = EmbedField(title, page, False)
                        emb["fields"].append(field)

        else:
            # Get list of commands for category
            filtered = sorted(filtered)
            if filtered:
                for i, page in enumerate(
                    pagify(self._add_subcommands(filtered), page_length=1000)
                ):
                    title = (
                        "**__Commands:__**"
                        if not self.is_bot() and self.is_cog()
                        else "**__Subcommands:__**"
                    )
                    if i > 0:
                        title += " (continued)"
                    field = EmbedField(title, page, False)
                    emb["fields"].append(field)

        return emb