示例#1
0
    async def format_page(self, menu: MenuBase, entries):
        offset = menu.current_page * self.per_page
        contents = ((f"{b.author}", f'**{b}** `{humanize.precisedelta(b.joined_at)}`')
                    for i, b in enumerate(entries, start=offset))

        embed = BaseEmbed(title="Bots added today")
        for n, v in contents:
            embed.add_field(name=n, value=v, inline=False)
        return menu.generate_page(embed, self._max_pages)
示例#2
0
 async def each_commands_list(self, menu: MenuBase, entries):
     offset = menu.current_page * self.per_page
     embed = BaseEmbed(title=f"All Commands")
     key = "(\u200b|\u200b)"
     contents = [
         "`{i}. {command}{k}{command_count}`".format(i=i, k=key, **b)
         for i, b in enumerate(entries, start=offset + 1)
     ]
     embed.description = "\n".join(realign(contents, key))
     return embed
示例#3
0
async def bot_pending_list(self, menu: MenuBase, entry):
    stellabot = menu.ctx.bot
    bot = menu.cached_bots.setdefault(entry["bot_id"], await stellabot.fetch_user(entry["bot_id"]))
    fields = (("Requested by", stellabot.get_user(entry["author_id"]) or "idk really"),
              ("Reason", entry["reason"]),
              ("Created at", default_date(bot.created_at)),
              ("Requested at", default_date(entry["requested_at"])),
              ("Message", f"[jump]({entry['jump_url']})"))
    embed = BaseEmbed(title=f"{bot}(`{bot.id}`)", fields=fields)
    embed.set_thumbnail(url=bot.avatar_url)
    return embed
示例#4
0
    async def whatprefix(self, ctx, member: BotPrefix):
        prefix = self.clean_prefix(member.prefix)
        embed = BaseEmbed.default(ctx,
                                  title=f"{member}'s Prefix",
                                  description=f"`{prefix}`")

        await ctx.maybe_reply(embed=embed)
示例#5
0
async def bot_added_list(self, menu: MenuBase, entries):
    """Menu for recentbotadd command."""
    offset = menu.current_page * self.per_page
    contents = ((f"{b.author}",
                 f'**{b}** `{humanize.precisedelta(b.joined_at)}`')
                for i, b in enumerate(entries, start=offset))
    return BaseEmbed(title="Bots added today", fields=contents)
示例#6
0
 def get_command_help(self, command):
     """Returns an Embed version of the command object given."""
     embed = BaseEmbed.default(self.context)
     embed.title = self.get_command_signature(command)
     embed.description = self.get_help(command, brief=False)
     if demo := self.get_demo(command):
         embed.set_image(url=demo)
示例#7
0
    async def whatadd(self,
                      ctx,
                      *,
                      author: IsBot(is_bot=False, user_check=False) = None):
        author = author or ctx.author
        if author.bot:
            return await ctx.maybe_reply("That's a bot lol")
        query = "SELECT * FROM {}_bots WHERE author_id=$1"
        total_list = [
            await self.bot.pool_pg.fetch(query.format(x), author.id)
            for x in ("pending", "confirmed")
        ]
        total_list = itertools.chain.from_iterable(total_list)

        async def get_member(b_id):
            return ctx.guild.get_member(b_id) or await self.bot.fetch_user(b_id
                                                                           )

        list_bots = [
            BotAdded.from_json(await get_member(x["bot_id"]), **x)
            for x in total_list
        ]
        embed = BaseEmbed.default(ctx,
                                  title=plural(f"{author}'s bot(s)",
                                               len(list_bots)))
        for dbot in list_bots:
            bot_id = dbot.bot.id
            value = ""
            if bprefix := await try_call(BotPrefixes.convert, ctx,
                                         str(bot_id)):
                value += f"**Most Used Prefix:** `{self.clean_prefix(ctx, bprefix.prefix)}`\n"
            if buse := await try_call(BotCommands.convert, ctx, str(bot_id)):
                high_use = buse.highest_command
                value += f"**Top Command:** `{high_use}`[`{buse.get_command(high_use)}`]\n"
                value += f"**Total Usage:** `{buse.total_usage}`\n"
示例#8
0
    async def botinfo(self, ctx, *, bot: IsBot):
        # TODO: I said this 3 months ago to redo this, but im lazy
        titles = (("Bot Prefix", "{0.allprefixes}", BotPrefixes),
                  ("Command Usage", "{0.total_usage}", BotCommands),
                  (("Bot Invited by", "{0.author}"),
                   (("Reason", "reason"), ("Requested at",
                                           'requested_at')), BotAdded))
        embed = BaseEmbed.default(ctx, title=str(bot))
        embed.set_thumbnail(url=bot.avatar.url)
        embed.add_field(name="ID", value=f"`{bot.id}`")
        for title, attrib, converter in reversed(titles):
            with contextlib.suppress(Exception):
                if obj := await converter.convert(ctx, str(bot.id)):
                    if isinstance(attrib, tuple):
                        for t, a in attrib:
                            if dat := getattr(obj, a):
                                dat = dat if not isinstance(
                                    dat,
                                    datetime.datetime) else default_date(dat)
                                embed.add_field(name=t,
                                                value=f"`{dat}`",
                                                inline=False)

                        title, attrib = title
                    embed.add_field(name=title,
                                    value=f"{attrib.format(obj)}",
                                    inline=False)
示例#9
0
 async def format_page(self, menu: MenuBase, entries):
     key = "(\u200b|\u200b)"
     offset = menu.current_page * self.per_page
     content = "`{no}. {prefix} {key} {b.count}`" if self.count_mode else "`{no}. {b} {key} {prefix}`"
     contents = [content.format(no=i+1, b=b, key=key, prefix=pprefix(menu.ctx.bot, b.prefix)) for i, b in enumerate(entries, start=offset)]
     embed = BaseEmbed(title="All Prefixes",
                       description="\n".join(realign(contents, key)))
     return menu.generate_page(embed, self._max_pages)
示例#10
0
 async def format_page(self, menu: MenuBase, entries):
     key = "(\u200b|\u200b)"
     offset = menu.current_page * self.per_page
     content = "`{no}. {b} {key} {b.count}`"
     contents = [content.format(no=i+1, b=b, key=key) for i, b in enumerate(entries, start=offset)]
     embed = BaseEmbed(title="Bot Command Rank",
                       description="\n".join(realign(contents, key)))
     return menu.generate_page(embed, self._max_pages)
示例#11
0
async def all_bot_count(self, menu: MenuBase, entries):
    """Menu for botrank command."""
    key = "(\u200b|\u200b)"
    offset = menu.current_page * self.per_page
    content = "`{no}. {b} {key} {b.count}`"
    contents = [content.format(no=i+1, b=b, key=key) for i, b in enumerate(entries, start=offset)]
    return BaseEmbed(title="Bot Command Rank",
                     description="\n".join(realign(contents, key)))
示例#12
0
 async def end_message(self, message, **kwargs):
     self.ended_at = datetime.datetime.utcnow()
     display = await self.render_board()
     file = discord.File(display, filename="connect_4.png")
     embed = BaseEmbed(timestamp=self.ended_at, **kwargs)
     embed.title = self.game
     embed.description = message
     embed.set_image(url=f"attachment://{file.filename}")
     embed.set_footer(text=self.GAME_TIME.format(precisedelta(self.ended_at - self.created_at)))
     return {"embed": embed, "file": file}
示例#13
0
    async def on_command_error(self, ctx, error):
        """The event triggered when an error is raised while invoking a command."""
        async def send_del(*args, **kwargs):
            await ctx.reply(*args,
                            delete_after=60,
                            mention_author=False,
                            **kwargs)
            if ctx.me.permissions_in(ctx.channel).manage_messages:
                with contextlib.suppress(discord.NotFound):
                    await ctx.message.delete(delay=60)

        if hasattr(ctx.command, 'on_error'):
            return

        cog = ctx.cog
        if cog:
            if cog._get_overridden_method(cog.cog_command_error) is not None:
                return

        ignored = (commands.CommandNotFound, )
        default_error = (commands.NotOwner, commands.TooManyArguments,
                         flags.ArgumentParsingError, NotInDpy)

        error = getattr(error, 'original', error)

        if isinstance(error, ignored):
            return

        if isinstance(error, commands.DisabledCommand):
            await send_del(f'{ctx.command} has been disabled.')

        elif isinstance(error, commands.CommandOnCooldown):
            if ctx.author == self.bot.stella:
                return await ctx.reinvoke()
            await send_del(embed=BaseEmbed.to_error(
                title="Cooldown Error",
                description=
                f"You're on cooldown. Retry after `{error.retry_after:.2f}` seconds"
            ))
        elif isinstance(error, default_error):
            await send_del(embed=BaseEmbed.to_error(description=f"{error}"))
        else:
            if template := await self.generate_signature_error(ctx, error):
                await send_del(embed=template)
            else:
示例#14
0
    async def cogs_handler(self, ctx, method, extensions):
        def do_cog(exts):
            func = getattr(self.bot, f"{method}_extension")
            return func(f"cogs.{exts}")

        outputs = [
            call(do_cog, ext, ret=True) or f"cogs.{ext} is {method}ed"
            for ext in extensions
        ]
        await ctx.maybe_reply(embed=BaseEmbed.default(
            ctx, description="\n".join(str(x) for x in outputs)))
示例#15
0
        def each_page(self, menu, entries):
            number = menu.current_page * self.per_page + 1
            list_commands = "\n".join(
                f"{x}. {c}[`{bot.get_command(c)}`]"
                for x, c in enumerate(entries, start=number))
            embed = BaseEmbed.default(
                ctx,
                title=f"{bot} Commands[`{bot.total_usage}`]",
                description=list_commands)
            if owner_info and owner_info.author:
                embed.set_author(icon_url=owner_info.author.avatar.url,
                                 name=f"Owner {owner_info.author}")

            return embed.set_thumbnail(url=bot.bot.avatar.url)
示例#16
0
 async def on_information_show(self, payload):
     ctx = self.ctx
     exists = [str(emoji) for emoji in super().buttons]
     embed = BaseEmbed.default(ctx,
                               title="Information",
                               description="This shows each commands in this bot. Each page is a category that shows "
                                           "what commands that the category have.")
     curr = self.current_page + 1 if (p := self.current_page > -1) else "cover page"
     pa = "page" if p else "the"
     embed.set_author(icon_url=ctx.bot.user.avatar.url,
                      name=f"You were on {pa} {curr}")
     nav = '\n'.join(f"{self.dict_emoji[e].emoji} {self.dict_emoji[e].explain}" for e in exists)
     embed.add_field(name="Navigation:", value=nav)
     await self.message.edit(embed=embed, allowed_mentions=discord.AllowedMentions(replied_user=False))
示例#17
0
 async def botrank(self, ctx, bot: BotUsage = None):
     bots = {x.id: x for x in ctx.guild.members if x.bot}
     query = "SELECT * FROM bot_usage_count WHERE bot_id=ANY($1::BIGINT[])"
     record = await self.bot.pool_pg.fetch(query, list(bots))
     bot_data = [BotUsage(bots[r["bot_id"]], r["count"]) for r in record]
     bot_data.sort(key=lambda x: x.count, reverse=True)
     if not bot:
         menu = MenuBase(source=AllBotCount(bot_data), delete_message_after=True)
         await menu.start(ctx)
     else:
         key = "(\u200b|\u200b)"
         idx = [*map(int, bot_data)].index(bot.bot.id)
         scope_bot = bot_data[idx:min(idx + len(bot_data[idx:]), idx + 10)]
         contents = ["`{0}. {1} {2} {1.count}`".format(i + idx + 1, b, key) for i, b in enumerate(scope_bot)]
         embed = BaseEmbed(title="Bot Command Rank", description="\n".join(realign(contents, key)))
         await ctx.maybe_reply(embed=embed)
示例#18
0
    async def replycount(self, ctx, message: discord.Message):
        def count_reply(m, replies=0):
            if isinstance(m, discord.MessageReference):
                return count_reply(m.cached_message, replies)
            if isinstance(m, discord.Message):
                if not m.reference:
                    return m, replies
                replies += 1
                return count_reply(m.reference, replies)

        msg, count = count_reply(message)
        embed_dict = {
            "title": "Reply Count",
            "description": f"**Original:** `{msg.author}`\n"
                           f"**Message:** `{msg.content}`\n"
                           f"**Replies:** `{count}`\n"
                           f"**Origin:** [`jump`]({msg.jump_url})"
        }
        await ctx.reply(embed=BaseEmbed.default(ctx, **embed_dict), mention_author=False)
示例#19
0
 async def connect4_prompt(game, message=None):
     if not message:
         display = await game.render_board()
         player = game.current_player
         description = f"`{player}`, It's your turn. Please choose a column between `1` to `7`."
         message = BaseEmbed.board(player.mention,
                                   game.color,
                                   display,
                                   "connect_4",
                                   title="Connect 4",
                                   description=description)
     error = f"`{{}}` seconds is up. Looks like `{game.last_player}` wins"
     return await prompt(ctx,
                         message=message,
                         predicate=check_turn(game),
                         error=error,
                         delete_after=True,
                         ret=True,
                         delete_timeout=True)
示例#20
0
 async def recentbotadd(self, ctx):
     def predicate(m):
         return m.bot and m.joined_at > ctx.message.created_at - datetime.timedelta(days=1)
     members = {m.id: m for m in filter(predicate, ctx.guild.members)}
     if not members:
         member = max(filter(lambda x: x.bot, ctx.guild.members), key=lambda x: x.joined_at)
         time_add = humanize.precisedelta(member.joined_at, minimum_unit="minutes")
         await ctx.maybe_reply(
             embed=BaseEmbed.default(
                 ctx,
                 title="Bots added today",
                 description="Looks like there are no bots added in the span of 24 hours.\n"
                             f"The last time a bot was added was `{time_add}` for `{member}`"))
         return
     db_data = await self.bot.pool_pg.fetch("SELECT * FROM confirmed_bots WHERE bot_id=ANY($1::BIGINT[])", list(members))
     member_data = [BotAdded.from_json(bot=members[data["bot_id"]], **data) for data in db_data]
     member_data.sort(key=lambda x: x.joined_at)
     menu = MenuBase(source=BotAddedList(member_data), delete_message_after=True)
     await menu.start(ctx)
示例#21
0
    async def whatadd(self, ctx, author: discord.Member = None):
        if not author:
            author = ctx.author
        if author.bot:
            return await ctx.maybe_reply("That's a bot lol")
        query = "SELECT * FROM {}_bots WHERE author_id=$1"
        total_list = [await self.bot.pool_pg.fetch(query.format(x), author.id) for x in ("pending", "confirmed")]
        total_list = itertools.chain.from_iterable(total_list)

        async def get_member(b_id):
            return ctx.guild.get_member(b_id) or await self.bot.fetch_user(b_id)
        list_bots = [BotAdded.from_json(await get_member(x["bot_id"]), **x) for x in total_list]
        embed = BaseEmbed.default(ctx, title=plural(f"{author}'s bot(s)", len(list_bots)))
        for dbot in list_bots:
            bot_id = dbot.bot.id
            value = ""
            if buse := await try_call(BotUsage.convert, ctx, str(bot_id)):
                value += f"**Usage:** `{buse.count}`\n"
            if bprefix := await try_call(BotPrefix.convert, ctx, str(bot_id)):
                value += f"**Prefix:** `{self.clean_prefix(bprefix.prefix)}`\n"
示例#22
0
    async def generate_signature_error(self, ctx, error):
        command = ctx.command
        help_com = self.bot.help_command
        help_com.context = ctx
        real_signature = help_com.get_command_signature(command, ctx)
        if ctx.current_parameter is None:
            return

        parameter = [*ctx.command.params.values()
                     ][ctx.command.cog is not None:]
        pos = parameter.index(ctx.current_parameter)
        list_sig = real_signature.split()
        pos += list_sig.index(ctx.invoked_with)

        target = list_sig[pos]
        print(target, "here")
        target_list = list(target)
        alpha_index = [
            i for i, a in enumerate(target) if a.isalnum() or a in ("|", '"')
        ]
        minimum, maximum = min(alpha_index), max(alpha_index)
        target_list[minimum] = target_list[minimum].capitalize()
        list_sig[pos] = "".join(target_list)
        space = " " * sum([len(x) + 1 for x in list_sig[:pos]])
        offset = " " * int((minimum + 1 + (maximum - minimum)) / 2)
        embed = BaseEmbed.to_error(description=f"```{error}```\n")
        embed.description += f"**Errored at**\n" \
                             f"```prolog\n" \
                             f"{' '.join(list_sig)}\n" \
                             f"{space}{offset}^\n" \
                             f"```\n"
        if (demo := help_com.get_demo(command)) and isinstance(
                error, commands.MissingRequiredArgument):
            cooldown = self.error_cooldown
            bucket = cooldown.get_bucket(ctx.message)
            if not bucket.update_rate_limit():
                embed.description += "**Command Example**"
                embed.set_image(url=demo)
示例#23
0
    async def botuse(self, ctx, bot: BotUsage):
        embed = BaseEmbed.default(ctx,
                                  title=f"{bot}'s Usage",
                                  description=plural(f"`{bot.count}` command(s) has been called for **{bot}**.", bot.count))

        await ctx.maybe_reply(embed=embed)
示例#24
0
        elif isinstance(error, commands.CommandOnCooldown):
            if ctx.author == self.bot.stella:
                return await ctx.reinvoke()
            await send_del(embed=BaseEmbed.to_error(
                title="Cooldown Error",
                description=
                f"You're on cooldown. Retry after `{error.retry_after:.2f}` seconds"
            ))
        elif isinstance(error, default_error):
            await send_del(embed=BaseEmbed.to_error(description=f"{error}"))
        else:
            if template := await self.generate_signature_error(ctx, error):
                await send_del(embed=template)
            else:
                await send_del(embed=BaseEmbed.to_error(description=f"{error}")
                               )
                traceback_error = print_exception(
                    f'Ignoring exception in command {ctx.command}:', error)
                if not self.bot.tester:
                    error_message = f"**Command:** {ctx.message.content}\n" \
                                    f"**Message ID:** `{ctx.message.id}`\n" \
                                    f"**Author:** `{ctx.author}`\n" \
                                    f"**Guild:** `{ctx.guild}`\n" \
                                    f"**Channel:** `{ctx.channel}`\n" \
                                    f"**Jump:** [`jump`]({ctx.message.jump_url})```py\n" \
                                    f"{traceback_error}\n" \
                                    f"```"
                    await self.bot.error_channel.send(
                        embed=BaseEmbed.default(ctx, description=error_message)
                    )
示例#25
0
    async def connect4(self, ctx, player2: Player):
        GAME = "Connect 4"
        message = BaseEmbed.invite(ctx,
                                   GAME,
                                   status=None,
                                   invitation=self.INVITATION.format(
                                       player2, ctx, GAME))
        message["content"] = player2.mention
        responses_text = tuple(
            BaseEmbed.invite(ctx, GAME, status=not x, invited=player2)
            for x in range(2))  # first is approve, second disapprove
        responses = {
            ctx.bot.INVITE_REACT[1 - x]: y
            for x, y in zip(range(2), responses_text)
        }
        game = self.bot.global_player.add(ctx, [player2.id],
                                          game_classes.Connect4)
        error = f"Looks like {{}} seconds is up! Sorry **{ctx.author}**, You will have to request for another one"
        respond = await prompt(ctx,
                               message=message,
                               event_type="reaction_add",
                               responses=responses,
                               error=error,
                               target_id={player2.id})
        if not respond:
            self.bot.global_player.remove(game)
            return
        game.status = True

        def check_turn(game):
            def predicate(m):
                checking = (m.author in (game.current_player, self.bot.stella),
                            m.content.isdigit()
                            and 1 <= int(m.content) <= game.cols)
                return all(checking)

            return predicate

        async def connect4_prompt(game, message=None):
            if not message:
                display = await game.render_board()
                player = game.current_player
                description = f"`{player}`, It's your turn. Please choose a column between `1` to `7`."
                message = BaseEmbed.board(player.mention,
                                          game.color,
                                          display,
                                          "connect_4",
                                          title="Connect 4",
                                          description=description)
            error = f"`{{}}` seconds is up. Looks like `{game.last_player}` wins"
            return await prompt(ctx,
                                message=message,
                                predicate=check_turn(game),
                                error=error,
                                delete_after=True,
                                ret=True,
                                delete_timeout=True)

        message_sent = None
        while response := await connect4_prompt(game, message_sent):
            if isinstance(response, discord.Message):
                message_sent = None
                if game_result := await atry_catch(game.insert,
                                                   int(response.content) - 1,
                                                   ret=True):
                    if not isinstance(game_result, Connect4ColumnFull):
                        await ctx.send(**game_result)
                        break
                    else:
                        message_sent = {
                            "embed":
                            BaseEmbed.to_error(title="Connect 4",
                                               description=str(game_result))
                        }
示例#26
0
 def each_page(self, menu, entries):
     number = menu.current_page * self.per_page + 1
     list_commands = "\n".join(f"{x}. {c}" for x, c in enumerate(entries, start=number))
     embed = BaseEmbed.default(ctx, title=f"{bot} Commands", description=list_commands)
     return embed.set_thumbnail(url=bot.bot.avatar_url)
示例#27
0
                           "Useful for finding out who's the annoying person that uses common prefix help command.")
    async def recenthelptrigger(self, ctx):
        if message := self.help_trigger.get(ctx.channel.id):
            embed_dict = {
                "title": "Recent Help Trigger",
                "description": f"**Author:** `{message.author}`\n"
                               f"**Message ID:** `{message.id}`\n"
                               f"**Command:** `{message.content}`\n"
                               f"**Message Link:** [`jump`]({message.jump_url})",
            }
        else:
            embed_dict = {
                "title": "Recent Help Trigger",
                "description": "There is no help command triggered recently."
            }
        await ctx.maybe_reply(embed=BaseEmbed.default(ctx, **embed_dict))

    @commands.command(aliases=["br", "brrrr", "botranks", "botpos", "botposition", "botpositions"],
                      help="Shows all bot's command usage in the server on a sorted list.")
    async def botrank(self, ctx, bot: BotUsage = None):
        bots = {x.id: x for x in ctx.guild.members if x.bot}
        query = "SELECT * FROM bot_usage_count WHERE bot_id=ANY($1::BIGINT[])"
        record = await self.bot.pool_pg.fetch(query, list(bots))
        bot_data = [BotUsage(bots[r["bot_id"]], r["count"]) for r in record]
        bot_data.sort(key=lambda x: x.count, reverse=True)
        if not bot:
            menu = MenuBase(source=AllBotCount(bot_data), delete_message_after=True)
            await menu.start(ctx)
        else:
            key = "(\u200b|\u200b)"
            idx = [*map(int, bot_data)].index(bot.bot.id)
示例#28
0
 async def prefixuse(self, ctx, prefix):
     instance_bot = await self.get_all_prefix(ctx.guild, prefix)
     prefix = self.clean_prefix(prefix)
     desk = plural(f"There (is/are) `{len(instance_bot)}` bot(s) that use `{prefix}` as prefix", len(instance_bot))
     await ctx.maybe_reply(embed=BaseEmbed.default(ctx, description=desk))
示例#29
0
 async def prefixbot(self, ctx, prefix):
     instance_bot = await self.get_all_prefix(ctx.guild, prefix)
     list_bot = "\n".join(f"`{no + 1}. {x}`" for no, x in enumerate(instance_bot)) or "`Not a single bot have it.`"
     prefix = self.clean_prefix(prefix)
     desk = f"Bot(s) with `{prefix}` as prefix\n{list_bot}"
     await ctx.maybe_reply(embed=BaseEmbed.default(ctx, description=plural(desk, len(list_bot))))