mirror of
https://github.com/allthingslinux/tux.git
synced 2024-10-02 16:43:12 +00:00
refactor(info.py): remove unnecessary line of code to improve readability and maintainability
refactor(info.py): simplify command decorators for readability refactor(info.py): change ctx type from commands.Context[commands.Bot] to commands.Context for simplicity feat(info.py): add paginated_embed method to handle paginated embeds in a more reusable way fix(info.py): check if guild exists before proceeding with commands to prevent errors feat(info.py): add more detailed server and member information to embeds refactor(info.py): streamline embed creation for cleaner code refactor(info.py): remove unused _create_embed_desc method refactor(info.py): update _chunks method to return list of strings for consistency refactor(info.py): update _add_buttons_to_menu method to return ViewMenu for consistency refactor: replace individual button addition with loop to improve code readability and maintainability
This commit is contained in:
parent
cd30e811ef
commit
ab01455674
1 changed files with 146 additions and 147 deletions
|
@ -9,233 +9,232 @@ class Info(commands.Cog):
|
|||
def __init__(self, bot: commands.Bot) -> None:
|
||||
self.bot = bot
|
||||
|
||||
@commands.hybrid_group(
|
||||
name="info",
|
||||
aliases=["i"],
|
||||
usage="info <subcommand>",
|
||||
)
|
||||
@commands.hybrid_group(name="info", aliases=["i"], usage="info <subcommand>")
|
||||
async def info(self, ctx: commands.Context[commands.Bot]) -> None:
|
||||
"""
|
||||
Information commands.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
ctx : commands.Context[commands.Bot]
|
||||
The discord context object.
|
||||
ctx : commands.Context
|
||||
The context object associated with the command.
|
||||
"""
|
||||
|
||||
if ctx.invoked_subcommand is None:
|
||||
await ctx.send_help("info")
|
||||
|
||||
@info.command(
|
||||
name="server",
|
||||
aliases=["s"],
|
||||
usage="info server",
|
||||
)
|
||||
@info.command(name="server", aliases=["s"], usage="info server")
|
||||
async def server(self, ctx: commands.Context[commands.Bot]) -> None:
|
||||
"""
|
||||
Show information about the server.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
ctx : commands.Context[commands.Bot]
|
||||
The discord context object.
|
||||
ctx : commands.Context
|
||||
The context object associated with the command.
|
||||
"""
|
||||
|
||||
if not ctx.guild:
|
||||
return
|
||||
guild = ctx.guild
|
||||
if not guild:
|
||||
return
|
||||
|
||||
embed = discord.Embed(
|
||||
title=ctx.guild.name,
|
||||
description=guild.description or "No description available.",
|
||||
color=discord.Color.blurple(),
|
||||
embed: discord.Embed = (
|
||||
discord.Embed(
|
||||
title=guild.name,
|
||||
description=guild.description or "No description available.",
|
||||
color=discord.Color.blurple(),
|
||||
)
|
||||
.set_author(name="Server Information", icon_url=guild.icon)
|
||||
.add_field(name="Owner", value=str(guild.owner.mention) if guild.owner else "Unknown")
|
||||
.add_field(name="Vanity URL", value=guild.vanity_url_code or "None")
|
||||
.add_field(name="Boosts", value=guild.premium_subscription_count)
|
||||
.add_field(name="Text Channels", value=len(guild.text_channels))
|
||||
.add_field(name="Voice Channels", value=len(guild.voice_channels))
|
||||
.add_field(name="Forum Channels", value=len(guild.forums))
|
||||
.add_field(name="Emojis", value=f"{len(guild.emojis)}/{guild.emoji_limit}")
|
||||
.add_field(name="Stickers", value=f"{len(guild.stickers)}/{guild.sticker_limit}")
|
||||
.add_field(name="Roles", value=len(guild.roles))
|
||||
.add_field(name="Humans", value=sum(not member.bot for member in guild.members))
|
||||
.add_field(name="Bots", value=sum(member.bot for member in guild.members))
|
||||
.add_field(name="Bans", value=len([entry async for entry in guild.bans(limit=2000)]))
|
||||
.set_footer(text=f"ID: {guild.id} | Created: {guild.created_at.strftime('%B %d, %Y')}")
|
||||
)
|
||||
|
||||
embed.set_author(name="Server Information", icon_url=guild.icon)
|
||||
embed.add_field(name="Owner", value=str(guild.owner.mention) if guild.owner else "Unknown")
|
||||
embed.add_field(name="Vanity URL", value=guild.vanity_url_code or "None")
|
||||
embed.add_field(name="Boosts", value=guild.premium_subscription_count)
|
||||
embed.add_field(name="Text Channels", value=len(guild.text_channels))
|
||||
embed.add_field(name="Voice Channels", value=len(guild.voice_channels))
|
||||
embed.add_field(name="Forum Channels", value=len(guild.forums))
|
||||
embed.add_field(name="Emojis", value=f"{len(guild.emojis)}/{guild.emoji_limit}")
|
||||
embed.add_field(name="Stickers", value=f"{len(guild.stickers)}/{guild.sticker_limit}")
|
||||
embed.add_field(name="Roles", value=len(guild.roles))
|
||||
embed.add_field(name="Humans", value=sum(not member.bot for member in guild.members))
|
||||
embed.add_field(name="Bots", value=sum(member.bot for member in guild.members))
|
||||
embed.add_field(name="Bans", value=len([entry async for entry in guild.bans(limit=2000)]))
|
||||
embed.set_footer(text=f"ID: {guild.id} | Created: {guild.created_at.strftime('%B %d, %Y')}")
|
||||
|
||||
await ctx.send(embed=embed)
|
||||
|
||||
@info.command(
|
||||
name="member",
|
||||
aliases=["m", "user", "u"],
|
||||
usage="info member [member]",
|
||||
)
|
||||
@info.command(name="member", aliases=["m", "user", "u"], usage="info member [member]")
|
||||
async def member(self, ctx: commands.Context[commands.Bot], member: discord.Member) -> None:
|
||||
"""
|
||||
Show information about a member.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
ctx : commands.Context[commands.Bot]
|
||||
The discord context object.
|
||||
ctx : commands.Context
|
||||
The context object associated with the command.
|
||||
member : discord.Member
|
||||
The member to get information about.
|
||||
"""
|
||||
|
||||
bot_status = "✅" if member.bot else "❌"
|
||||
joined = discord.utils.format_dt(member.joined_at, "R") if member.joined_at else "Unknown"
|
||||
created = discord.utils.format_dt(member.created_at, "R") if member.created_at else "Unknown"
|
||||
roles = ", ".join(role.mention for role in member.roles[1:]) if member.roles[1:] else "No roles"
|
||||
fetched_member = await self.bot.fetch_user(member.id)
|
||||
|
||||
embed = discord.Embed(
|
||||
title=member.display_name,
|
||||
description="Here is some information about the member.",
|
||||
color=discord.Color.blurple(),
|
||||
embed: discord.Embed = (
|
||||
discord.Embed(
|
||||
title=member.display_name,
|
||||
description="Here is some information about the member.",
|
||||
color=discord.Color.blurple(),
|
||||
)
|
||||
.set_thumbnail(url=member.display_avatar.url)
|
||||
.set_image(
|
||||
url=(await self.bot.fetch_user(member.id)).banner, # Fetched member's banner
|
||||
)
|
||||
.add_field(name="Bot?", value="✅" if member.bot else "❌", inline=False)
|
||||
.add_field(name="Username", value=member.name, inline=False)
|
||||
.add_field(name="ID", value=str(member.id), inline=False)
|
||||
.add_field(
|
||||
name="Joined",
|
||||
value=discord.utils.format_dt(member.joined_at, "R") if member.joined_at else "Unknown",
|
||||
inline=False,
|
||||
)
|
||||
.add_field(
|
||||
name="Registered",
|
||||
value=discord.utils.format_dt(member.created_at, "R") if member.created_at else "Unknown",
|
||||
inline=False,
|
||||
)
|
||||
.add_field(
|
||||
name="Roles",
|
||||
value=", ".join(role.mention for role in member.roles[1:]) if member.roles[1:] else "No roles",
|
||||
inline=False,
|
||||
)
|
||||
)
|
||||
|
||||
embed.set_thumbnail(url=member.display_avatar.url)
|
||||
embed.set_image(url=fetched_member.banner)
|
||||
embed.add_field(name="Bot?", value=bot_status, inline=False)
|
||||
embed.add_field(name="Username", value=member.name, inline=False)
|
||||
embed.add_field(name="ID", value=str(member.id), inline=False)
|
||||
embed.add_field(name="Joined", value=joined, inline=False)
|
||||
embed.add_field(name="Registered", value=created, inline=False)
|
||||
embed.add_field(name="Roles", value=roles, inline=False)
|
||||
|
||||
await ctx.send(embed=embed)
|
||||
|
||||
@info.command(
|
||||
name="roles",
|
||||
aliases=["r"],
|
||||
usage="info roles",
|
||||
)
|
||||
@info.command(name="roles", aliases=["r"], usage="info roles")
|
||||
async def roles(self, ctx: commands.Context[commands.Bot]) -> None:
|
||||
"""
|
||||
List all roles in the server.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
ctx : commands.Context[commands.Bot]
|
||||
The discord context object.
|
||||
ctx : commands.Context
|
||||
The context object associated with the command.
|
||||
"""
|
||||
if not ctx.guild:
|
||||
return
|
||||
|
||||
guild = ctx.guild
|
||||
roles = [role.mention for role in guild.roles]
|
||||
|
||||
embed = discord.Embed(
|
||||
title="Server Roles",
|
||||
color=discord.Color.blurple(),
|
||||
)
|
||||
|
||||
chunk_size = 32
|
||||
if not len(roles) > chunk_size:
|
||||
embed.description = self._create_embed_desc("roles", guild.name, roles)
|
||||
await ctx.send(embed=embed)
|
||||
if not guild:
|
||||
return
|
||||
|
||||
chunks = self._chunks(iter(roles), chunk_size)
|
||||
menu = ViewMenu(ctx, menu_type=ViewMenu.TypeEmbed)
|
||||
roles: list[str] = [role.mention for role in guild.roles]
|
||||
|
||||
for chunk in chunks:
|
||||
embed = embed.copy()
|
||||
await self.paginated_embed(ctx, "Server Roles", "roles", guild.name, roles, 32)
|
||||
|
||||
embed.description = self._create_embed_desc("roles", guild.name, chunk)
|
||||
menu.add_page(embed)
|
||||
|
||||
menu = self._add_buttons_to_menu(menu)
|
||||
await menu.start()
|
||||
|
||||
@info.command(
|
||||
name="emotes",
|
||||
aliases=["e"],
|
||||
usage="info emotes",
|
||||
)
|
||||
@info.command(name="emotes", aliases=["e"], usage="info emotes")
|
||||
async def emotes(self, ctx: commands.Context[commands.Bot]) -> None:
|
||||
"""
|
||||
List all emotes in the server.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
ctx : commands.Context[commands.Bot]
|
||||
The discord context object.
|
||||
ctx : commands.Context
|
||||
The context object associated with the command.
|
||||
"""
|
||||
if not ctx.guild:
|
||||
return
|
||||
|
||||
guild = ctx.guild
|
||||
emotes: list[str] = [str(emote) for emote in guild.emojis]
|
||||
|
||||
embed = discord.Embed(
|
||||
title="Server Emotes",
|
||||
color=discord.Color.blurple(),
|
||||
)
|
||||
|
||||
chunk_size = 128
|
||||
if not len(emotes) > chunk_size:
|
||||
embed.description = self._create_embed_desc("emotes", guild.name, emotes)
|
||||
await ctx.send(embed=embed)
|
||||
if not guild:
|
||||
return
|
||||
|
||||
chunks = self._chunks(iter(emotes), chunk_size)
|
||||
menu = ViewMenu(ctx, menu_type=ViewMenu.TypeEmbed)
|
||||
emotes: list[str] = [str(emote) for emote in guild.emojis]
|
||||
await self.paginated_embed(ctx, "Server Emotes", "emotes", guild.name, emotes, 128)
|
||||
|
||||
for chunk in chunks:
|
||||
embed = embed.copy()
|
||||
|
||||
embed.description = self._create_embed_desc("emotes", guild.name, chunk)
|
||||
menu.add_page(embed)
|
||||
|
||||
menu = self._add_buttons_to_menu(menu)
|
||||
await menu.start()
|
||||
|
||||
def _chunks[T](self, it: Iterator[T], size: int) -> Generator[list[T], None, None]:
|
||||
async def paginated_embed(
|
||||
self,
|
||||
ctx: commands.Context[commands.Bot],
|
||||
title: str,
|
||||
list_type: str,
|
||||
guild_name: str,
|
||||
items: Iterable[str],
|
||||
chunk_size: int,
|
||||
) -> None:
|
||||
"""
|
||||
Split an iterator into chunks of a specified size.
|
||||
|
||||
This function takes an iterator and divides it into chunks of a given size.
|
||||
Any remaining elements that do not fill a complete chunk are included in the
|
||||
final chunk, which may be smaller than the specified size.
|
||||
Send a paginated embed.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
it : Iterator[T]
|
||||
ctx : commands.Context
|
||||
The context object associated with the command.
|
||||
title : str
|
||||
The title of the embed.
|
||||
list_type : str
|
||||
The type of list (e.g., roles, emotes).
|
||||
guild_name : str
|
||||
The name of the guild.
|
||||
items : Iterable[str]
|
||||
The items to display in the embed.
|
||||
chunk_size : int
|
||||
The size of each chunk for pagination.
|
||||
"""
|
||||
embed: discord.Embed = discord.Embed(title=title, color=discord.Color.blurple())
|
||||
chunks: list[list[str]] = list(self._chunks(iter(items), chunk_size))
|
||||
|
||||
if not chunks:
|
||||
embed.description = "No items available."
|
||||
await ctx.send(embed=embed)
|
||||
return
|
||||
|
||||
menu: ViewMenu = ViewMenu(ctx, menu_type=ViewMenu.TypeEmbed)
|
||||
for chunk in chunks:
|
||||
page_embed: discord.Embed = embed.copy()
|
||||
page_embed.description = f"{list_type.capitalize()} list for {guild_name}:\n{' '.join(chunk)}"
|
||||
menu.add_page(page_embed)
|
||||
|
||||
self._add_buttons_to_menu(menu)
|
||||
await menu.start()
|
||||
|
||||
def _chunks(self, it: Iterator[str], size: int) -> Generator[list[str], None, None]:
|
||||
"""
|
||||
Split an iterator into chunks of a specified size.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
it : Iterator[str]
|
||||
The input iterator to be split into chunks.
|
||||
size : int
|
||||
The size of each chunk.
|
||||
|
||||
Yields
|
||||
-------
|
||||
list[T]
|
||||
------
|
||||
List[str]
|
||||
A list containing a chunk of elements from the input iterator. The last
|
||||
list may contain fewer elements if there are not enough remaining to fill
|
||||
a complete chunk.
|
||||
"""
|
||||
chunk: list[T] = []
|
||||
chunk: list[str] = []
|
||||
for item in it:
|
||||
chunk.append(item)
|
||||
if len(chunk) == size:
|
||||
yield chunk
|
||||
chunk = []
|
||||
if chunk: # if last chunk has any items
|
||||
if chunk:
|
||||
yield chunk
|
||||
|
||||
def _create_embed_desc(self, list_type: str, guild_name: str, items: Iterable[str]) -> str:
|
||||
return (
|
||||
f"{list_type.capitalize()} list for {guild_name}:\n {" ".join(items) if items else "No items available."}"
|
||||
)
|
||||
def _add_buttons_to_menu(self, menu: ViewMenu) -> ViewMenu:
|
||||
"""
|
||||
Add buttons to the menu.
|
||||
|
||||
def _add_buttons_to_menu[T: ViewMenu](self, menu: T) -> T:
|
||||
menu.add_button(ViewButton.go_to_first_page())
|
||||
menu.add_button(ViewButton.back())
|
||||
menu.add_button(ViewButton.next())
|
||||
menu.add_button(ViewButton.go_to_last_page())
|
||||
menu.add_button(ViewButton.end_session())
|
||||
Parameters
|
||||
----------
|
||||
menu : ViewMenu
|
||||
The menu to add buttons to.
|
||||
|
||||
Returns
|
||||
-------
|
||||
ViewMenu
|
||||
The menu with buttons added.
|
||||
"""
|
||||
buttons = [
|
||||
ViewButton.go_to_first_page(),
|
||||
ViewButton.back(),
|
||||
ViewButton.next(),
|
||||
ViewButton.go_to_last_page(),
|
||||
ViewButton.end_session(),
|
||||
]
|
||||
|
||||
for button in buttons:
|
||||
menu.add_button(button)
|
||||
return menu
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue