Beispiel #1
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))
Beispiel #2
0
 async def economyset(self, ctx: commands.Context):
     """Changes economy module settings"""
     guild = ctx.guild
     if ctx.invoked_subcommand is None:
         if await bank.is_global():
             slot_min = await self.config.SLOT_MIN()
             slot_max = await self.config.SLOT_MAX()
             slot_time = await self.config.SLOT_TIME()
             payday_time = await self.config.PAYDAY_TIME()
             payday_amount = await self.config.PAYDAY_CREDITS()
         else:
             slot_min = await self.config.guild(guild).SLOT_MIN()
             slot_max = await self.config.guild(guild).SLOT_MAX()
             slot_time = await self.config.guild(guild).SLOT_TIME()
             payday_time = await self.config.guild(guild).PAYDAY_TIME()
             payday_amount = await self.config.guild(guild).PAYDAY_CREDITS()
         register_amount = await bank.get_default_balance(guild)
         msg = box(
             _(
                 "Minimum slot bid: {}\n"
                 "Maximum slot bid: {}\n"
                 "Slot cooldown: {}\n"
                 "Payday amount: {}\n"
                 "Payday cooldown: {}\n"
                 "Amount given at account registration: {}"
                 ""
             ).format(
                 slot_min, slot_max, slot_time, payday_amount, payday_time, register_amount
             ),
             _("Current Economy settings:"),
         )
         await ctx.send(msg)
Beispiel #3
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
Beispiel #4
0
    async def set_cases(self, ctx: commands.Context, action: str = None):
        """Enables or disables case creation for each type of mod action"""
        guild = ctx.guild

        if action is None:  # No args given
            casetypes = await modlog.get_all_casetypes(guild)
            await ctx.send_help()
            title = _("Current settings:")
            msg = ""
            for ct in casetypes:
                enabled = await ct.is_enabled()
                value = "enabled" if enabled else "disabled"
                msg += "%s : %s\n" % (ct.name, value)

            msg = title + "\n" + box(msg)
            await ctx.send(msg)
            return
        casetype = await modlog.get_casetype(action, guild)
        if not casetype:
            await ctx.send(_("That action is not registered"))
        else:

            enabled = await casetype.is_enabled()
            await casetype.set_enabled(True if not enabled else False)

            msg = _("Case creation for {} actions is now {}.").format(
                action, "enabled" if not enabled else "disabled")
            await ctx.send(msg)
Beispiel #5
0
    async def selfrole_list(self, ctx: commands.Context):
        """
        Lists all available selfroles.
        """
        selfroles = await self._valid_selfroles(ctx.guild)
        fmt_selfroles = "\n".join(["+ " + r.name for r in selfroles])

        msg = "Available Selfroles:\n{}".format(fmt_selfroles)
        await ctx.send(box(msg, "diff"))
Beispiel #6
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
Beispiel #7
0
    async def trivia_list(self, ctx: commands.Context):
        """List available trivia categories."""
        lists = set(p.stem for p in self._all_lists())

        msg = box("**Available trivia lists**\n\n{}".format(", ".join(sorted(lists))))
        if len(msg) > 1000:
            await ctx.author.send(msg)
            return
        await ctx.send(msg)
Beispiel #8
0
 async def _list_global_alias(self, ctx: commands.Context):
     """
     Lists the available global aliases on this bot.
     """
     names = [_("Aliases:")] + sorted(
         ["+ " + a.name for a in await self.unloaded_global_aliases()])
     if len(names) == 0:
         await ctx.send(_("There are no aliases on this server."))
     else:
         await ctx.send(box("\n".join(names), "diff"))
Beispiel #9
0
    async def dataconversioncommand(self, ctx: commands.Context, v2path: str):
        """
        Interactive prompt for importing data from Red v2

        Takes the path where the v2 install is

        Overwrites values which have entries in both v2 and v3,
        use with caution.
        """
        resolver = SpecResolver(Path(v2path.strip()))

        if not resolver.available:
            return await ctx.send(
                _("There don't seem to be any data files I know how to "
                  "handle here. Are you sure you gave me the base "
                  "installation path?"))
        while resolver.available:
            menu = _(
                "Please select a set of data to import by number, or 'exit' to exit"
            )
            for index, entry in enumerate(resolver.available, 1):
                menu += "\n{}. {}".format(index, entry)

            menu_message = await ctx.send(box(menu))

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

            try:
                message = await self.bot.wait_for("message",
                                                  check=pred,
                                                  timeout=60)
            except asyncio.TimeoutError:
                return await ctx.send(
                    _("Try this again when you are more ready"))
            else:
                if message.content.strip().lower() in [
                        "quit", "exit", "-1", "q", "cancel"
                ]:
                    return await ctx.tick()
                try:
                    message = int(message.content.strip())
                    to_conv = resolver.available[message - 1]
                except (ValueError, IndexError):
                    await ctx.send(_("That wasn't a valid choice."))
                    continue
                else:
                    async with ctx.typing():
                        await resolver.convert(self.bot, to_conv)
                    await ctx.send(_("{} converted.").format(to_conv))
            await menu_message.delete()
        else:
            return await ctx.send(
                _("There isn't anything else I know how to convert here."
                  "\nThere might be more things I can convert in the future."))
Beispiel #10
0
    async def _repo_info(self, ctx, repo_name: Repo):
        """
        Lists information about a single repo
        """
        if repo_name is None:
            await ctx.send(_("There is no repo `{}`").format(repo_name.name))
            return

        msg = _("Information on {}:\n{}").format(repo_name.name,
                                                 repo_name.description or "")
        await ctx.send(box(msg))
Beispiel #11
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"))
Beispiel #12
0
    async def _cog_info(self, ctx, repo_name: Repo, cog_name: str):
        """
        Lists information about a single cog.
        """
        cog = discord.utils.get(repo_name.available_cogs, name=cog_name)
        if cog is None:
            await ctx.send(
                _("There is no cog `{}` in the repo `{}`").format(
                    cog_name, repo_name.name))
            return

        msg = _("Information on {}:\n{}\n\nRequirements: {}").format(
            cog.name, cog.description or "", ", ".join(cog.requirements)
            or "None")
        await ctx.send(box(msg))
Beispiel #13
0
 async def triviaset(self, ctx: commands.Context):
     """Manage trivia settings."""
     if ctx.invoked_subcommand is None:
         settings = self.conf.guild(ctx.guild)
         settings_dict = await settings.all()
         msg = box(
             "**Current settings**\n"
             "Bot gains points: {bot_plays}\n"
             "Answer time limit: {delay} seconds\n"
             "Lack of response timeout: {timeout} seconds\n"
             "Points to win: {max_score}\n"
             "Reveal answer on timeout: {reveal_answer}\n"
             "Payout multiplier: {payout_multiplier}\n"
             "Allow lists to override settings: {allow_override}"
             "".format(**settings_dict),
             lang="py",
         )
         await ctx.send(msg)
Beispiel #14
0
    async def bankset(self, ctx: commands.Context):
        """Base command for bank settings"""
        if ctx.invoked_subcommand is None:
            if await bank.is_global():
                bank_name = await bank._conf.bank_name()
                currency_name = await bank._conf.currency()
                default_balance = await bank._conf.default_balance()
            else:
                if not ctx.guild:
                    return
                bank_name = await bank._conf.guild(ctx.guild).bank_name()
                currency_name = await bank._conf.guild(ctx.guild).currency()
                default_balance = await bank._conf.guild(ctx.guild
                                                         ).default_balance()

            settings = _(
                "Bank settings:\n\nBank name: {}\nCurrency: {}\nDefault balance: {}"
            ).format(bank_name, currency_name, default_balance)
            await ctx.send(box(settings))
Beispiel #15
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"))
Beispiel #16
0
    async def findcog(self, ctx: commands.Context, command_name: str):
        """
        Figures out which cog a command comes from. Only works with loaded
            cogs.
        """
        command = ctx.bot.all_commands.get(command_name)

        if command is None:
            await ctx.send(_("That command doesn't seem to exist."))
            return

        # Check if in installed cogs
        cog_name = self.cog_name_from_instance(command.instance)
        installed, cog_installable = await self.is_installed(cog_name)
        if installed:
            msg = self.format_findcog_info(command_name, cog_installable)
        else:
            # Assume it's in a base cog
            msg = self.format_findcog_info(command_name, command.instance)

        await ctx.send(box(msg))
Beispiel #17
0
 async def send_table(self):
     """Send a table of scores to the session's channel."""
     table = "+ Results: \n\n"
     for user, score in self.scores.most_common():
         table += "+ {}\t{}\n".format(user, score)
     await self.ctx.send(box(table, lang="diff"))
Beispiel #18
0
    async def send_interactive(self,
                               messages: Iterable[str],
                               box_lang: str = None,
                               timeout: int = 15) -> List[discord.Message]:
        """Send multiple messages interactively.

        The user will be prompted for whether or not they would like to view
        the next message, one at a time. They will also be notified of how
        many messages are remaining on each prompt.

        Parameters
        ----------
        messages : `iterable` of `str`
            The messages to send.
        box_lang : str
            If specified, each message will be contained within a codeblock of
            this language.
        timeout : int
            How long the user has to respond to the prompt before it times out.
            After timing out, the bot deletes its prompt message.

        """
        messages = tuple(messages)
        ret = []

        more_check = lambda m: (m.author == self.author and m.channel == self.
                                channel and m.content.lower() == "more")

        for idx, page in enumerate(messages, 1):
            if box_lang is None:
                msg = await self.send(page)
            else:
                msg = await self.send(box(page, lang=box_lang))
            ret.append(msg)
            n_remaining = len(messages) - idx
            if n_remaining > 0:
                if n_remaining == 1:
                    plural = ""
                    is_are = "is"
                else:
                    plural = "s"
                    is_are = "are"
                query = await self.send(
                    "There {} still {} message{} remaining. "
                    "Type `more` to continue."
                    "".format(is_are, n_remaining, plural))
                try:
                    resp = await self.bot.wait_for("message",
                                                   check=more_check,
                                                   timeout=timeout)
                except asyncio.TimeoutError:
                    await query.delete()
                    break
                else:
                    try:
                        await self.channel.delete_messages((query, resp))
                    except (discord.HTTPException, AttributeError):
                        # In case the bot can't delete other users' messages,
                        # or is not a bot account
                        # or chanel is a DM
                        await query.delete()
        return ret