fix: Enhance userinfo command with additional member details including badges, account age, and device status
This commit is contained in:
parent
c75c01786f
commit
17d41df051
@ -1,7 +1,7 @@
|
||||
import discord
|
||||
from discord.ext import commands
|
||||
from discord import AllowedMentions, ui
|
||||
from datetime import datetime
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
class UserInfoCog(commands.Cog):
|
||||
def __init__(self, bot: commands.Bot):
|
||||
@ -44,43 +44,142 @@ class UserInfoCog(commands.Cog):
|
||||
f"Streaming {member.activity.name}" if member.activity and member.activity.type is discord.ActivityType.streaming else
|
||||
f"Listening to {member.activity.title}…" if member.activity and member.activity.type is discord.ActivityType.listening else
|
||||
f"Watching {member.activity.name}" if member.activity and member.activity.type is discord.ActivityType.watching else
|
||||
f"{member.activity.emoji} {member.activity.name}".strip()
|
||||
f"{member.activity.emoji} {member.activity.state}".strip() # Use .state for custom status text
|
||||
if member.activity and member.activity.type is discord.ActivityType.custom else
|
||||
"None"
|
||||
)
|
||||
|
||||
# Badges / Flags
|
||||
badges = [flag.name.replace('_', ' ').title()
|
||||
for flag in discord.PublicUserFlags
|
||||
if flag in member.public_flags]
|
||||
badges_str = ', '.join(badges) or "None"
|
||||
|
||||
# Pronouns
|
||||
pronouns_str = getattr(member, 'pronouns', 'N/A') # API v10-beta
|
||||
|
||||
# Avatar Type
|
||||
avatar_type = "GIF" if member.avatar and member.avatar.is_animated() else "Static"
|
||||
|
||||
# Account Age
|
||||
account_age = datetime.utcnow() - member.created_at
|
||||
account_age_str = f"{account_age.days // 365} years, {(account_age.days % 365) // 30} months"
|
||||
|
||||
# Join Position
|
||||
join_position_str = "N/A"
|
||||
if ctx.guild and member.joined_at:
|
||||
sorted_members = sorted(ctx.guild.members, key=lambda m: m.joined_at if m.joined_at else datetime.min)
|
||||
try:
|
||||
join_position_str = f"{sorted_members.index(member) + 1} of {len(sorted_members)}"
|
||||
except ValueError:
|
||||
pass # Member not found in sorted list, should not happen if member is from ctx.guild.members
|
||||
|
||||
# Server Boost Info
|
||||
boost_str = "Not boosting"
|
||||
if member.premium_since:
|
||||
months = (datetime.utcnow() - member.premium_since).days // 30
|
||||
boost_str = f"Boosting for {months} month{'s' if months!=1 else ''}"
|
||||
elif ctx.guild and discord.utils.get(member.roles, id=ctx.guild.premium_subscriber_role.id) in member.roles: # Check if they have the boost role
|
||||
boost_str = "Boosting (time unknown)"
|
||||
|
||||
# Top / Hoisted Role
|
||||
top_role_str = member.top_role.mention if member.top_role and member.top_role.name != "@everyone" else "None"
|
||||
|
||||
# Key Permissions
|
||||
key_permissions = []
|
||||
if member.guild_permissions.administrator:
|
||||
key_permissions.append("Administrator")
|
||||
if member.guild_permissions.manage_channels:
|
||||
key_permissions.append("Manage Channels")
|
||||
if member.guild_permissions.manage_guild:
|
||||
key_permissions.append("Manage Server")
|
||||
if member.guild_permissions.kick_members:
|
||||
key_permissions.append("Kick Members")
|
||||
if member.guild_permissions.ban_members:
|
||||
key_permissions.append("Ban Members")
|
||||
if member.guild_permissions.moderate_members:
|
||||
key_permissions.append("Moderate Members")
|
||||
if member.guild_permissions.manage_messages:
|
||||
key_permissions.append("Manage Messages")
|
||||
permissions_str = ", ".join(key_permissions) or "None"
|
||||
|
||||
# Timeout Status
|
||||
timeout_str = "Not timed out"
|
||||
if member.communication_disabled_until:
|
||||
until_time = member.communication_disabled_until
|
||||
time_left = until_time - datetime.utcnow()
|
||||
if time_left > timedelta(0):
|
||||
hours, remainder = divmod(int(time_left.total_seconds()), 3600)
|
||||
minutes, seconds = divmod(remainder, 60)
|
||||
timeout_str = f"Timed out for {hours}h {minutes}m {seconds}s"
|
||||
else:
|
||||
timeout_str = "Timeout expired"
|
||||
|
||||
# Device Status
|
||||
device_map = {
|
||||
discord.Status.online: "🟢",
|
||||
discord.Status.idle: "🌙",
|
||||
discord.Status.dnd: "⛔",
|
||||
discord.Status.offline: "⚫"
|
||||
}
|
||||
devices = []
|
||||
if member.desktop_status != discord.Status.offline:
|
||||
devices.append(f"Desktop {device_map.get(member.desktop_status, '⚫')}")
|
||||
if member.mobile_status != discord.Status.offline:
|
||||
devices.append(f"Mobile {device_map.get(member.mobile_status, '⚫')}")
|
||||
if member.web_status != discord.Status.offline:
|
||||
devices.append(f"Web {device_map.get(member.web_status, '⚫')}")
|
||||
device_status_str = ", ".join(devices) or "Offline"
|
||||
|
||||
|
||||
# --- UI Components v2 View ---
|
||||
class UserInfoView(ui.LayoutView):
|
||||
def __init__(self, target_member: discord.Member):
|
||||
super().__init__(timeout=180) # 3 minutes timeout
|
||||
|
||||
main_container = ui.Container(accent_colour=member.color)
|
||||
main_container = ui.Container(accent_colour=target_member.accent_color or discord.Color.default())
|
||||
self.add_item(main_container)
|
||||
|
||||
# Header Section with Avatar
|
||||
# Header Section with Avatar and Banner
|
||||
header_section = ui.Section(accessory=ui.Thumbnail(media=target_member.display_avatar.url, description="User Avatar"))
|
||||
main_container.add_item(header_section)
|
||||
header_section.add_item(ui.TextDisplay(f"**{target_member.display_name}**"))
|
||||
header_section.add_item(ui.TextDisplay(f"({username_discriminator}) - ID: {target_member.id}"))
|
||||
|
||||
if target_member.banner:
|
||||
main_container.add_item(ui.Thumbnail(media=target_member.banner.url, description="User Banner"))
|
||||
|
||||
main_container.add_item(ui.Separator(spacing=discord.SeparatorSpacing.small))
|
||||
|
||||
# Dates
|
||||
main_container.add_item(ui.TextDisplay(f"**Joined Server:** {joined_at_str}"))
|
||||
main_container.add_item(ui.TextDisplay(f"**Account Created:** {created_at_str}"))
|
||||
# Account & Profile
|
||||
main_container.add_item(ui.TextDisplay(f"**Account Created:** {created_at_str} ({account_age_str} ago)"))
|
||||
main_container.add_item(ui.TextDisplay(f"**Avatar Type:** {avatar_type}"))
|
||||
main_container.add_item(ui.TextDisplay(f"**Badges:** {badges_str}"))
|
||||
if pronouns_str != 'N/A':
|
||||
main_container.add_item(ui.TextDisplay(f"**Pronouns:** {pronouns_str}"))
|
||||
|
||||
main_container.add_item(ui.Separator(spacing=discord.SeparatorSpacing.small))
|
||||
|
||||
# Guild-specific
|
||||
if ctx.guild:
|
||||
main_container.add_item(ui.TextDisplay(f"**Joined Server:** {joined_at_str}"))
|
||||
main_container.add_item(ui.TextDisplay(f"**Join Position:** {join_position_str}"))
|
||||
main_container.add_item(ui.TextDisplay(f"**Server Boost:** {boost_str}"))
|
||||
main_container.add_item(ui.TextDisplay(f"**Top Role:** {top_role_str}"))
|
||||
main_container.add_item(ui.TextDisplay(f"**Key Permissions:** {permissions_str}"))
|
||||
main_container.add_item(ui.TextDisplay(f"**Timeout Status:** {timeout_str}"))
|
||||
if target_member.nick:
|
||||
main_container.add_item(ui.TextDisplay(f"**Nickname:** {target_member.nick}"))
|
||||
|
||||
main_container.add_item(ui.Separator(spacing=discord.SeparatorSpacing.small))
|
||||
|
||||
# Status & Activity
|
||||
main_container.add_item(ui.TextDisplay(f"**Status:** {status_str}"))
|
||||
main_container.add_item(ui.TextDisplay(f"**Device Status:** {device_status_str}"))
|
||||
main_container.add_item(ui.TextDisplay(f"**Activity:** {activity_str}"))
|
||||
|
||||
if target_member.nick:
|
||||
main_container.add_item(ui.TextDisplay(f"**Nickname:** {target_member.nick}"))
|
||||
|
||||
main_container.add_item(ui.Separator(spacing=discord.SeparatorSpacing.small))
|
||||
|
||||
# Roles
|
||||
main_container.add_item(ui.Separator(spacing=discord.SeparatorSpacing.small))
|
||||
main_container.add_item(ui.TextDisplay(f"**Roles ({len(roles)}):**"))
|
||||
if roles:
|
||||
main_container.add_item(ui.TextDisplay(roles_str))
|
||||
@ -101,9 +200,6 @@ class UserInfoCog(commands.Cog):
|
||||
if voice_state_details:
|
||||
main_container.add_item(ui.TextDisplay(f"**Voice State:** {', '.join(voice_state_details)}"))
|
||||
|
||||
|
||||
# Add more sections as needed (e.g., permissions)
|
||||
|
||||
try:
|
||||
view = UserInfoView(member)
|
||||
await ctx.send(view=view, ephemeral=False, allowed_mentions=AllowedMentions(roles=False, users=False, everyone=False)) # Send publicly by default
|
||||
|
Loading…
x
Reference in New Issue
Block a user