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)
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
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
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)
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)
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)
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"
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)
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)
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)
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)))
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}
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:
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)))
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)
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))
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)
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)
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)
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)
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"
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)
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)
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) )
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)) }
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)
"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)
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))
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))))