Files
mustafa/src/cogs/info.py
T
leanderandClaude Opus 5.5 e24523d1b3 simplify member status counting in /botinfo and /guild info
Count statuses with a Counter over discord.Status instead of one set or
counter per status, and share the emoji formatting between both commands.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 19:32:53 +01:00

818 lines
35 KiB
Python

from collections import Counter
import discord
from discord import app_commands
from discord.ext import commands
from cogs.utils import discord_utils
from cogs.utils import embed_templates
from cogs.utils import misc_utils
class Info(commands.Cog):
"""View information about Discord object such as guilds, users, roles and channels"""
def __init__(self, bot: commands.Bot):
"""
Parameters
----------
bot (commands.Bot): The bot instance
"""
self.bot = bot
guild_group = app_commands.Group(name="guild", description="Se ting om serveren", guild_only=True)
user_group = app_commands.Group(name="bruker", description="Se ting om brukeren", guild_only=True)
def construct_role_string(self, roles: list[discord.Role]) -> str:
"""
Puts all roles except @everyone into a list and joins them to a string
Parameters
----------
roles (list[discord.Role]): List of roles
Returns
----------
(str): String of roles
"""
if not roles:
return "**Ingen roller**"
roles = [role.name for role in roles if role.name != "@everyone"]
roles.reverse()
return ", ".join(roles)
def construct_booster_string(self, interaction: discord.Interaction, join_method: callable = ", ".join) -> str:
"""
Joins all boosters into a string
Parameters
----------
interaction (discord.Interaction): The interaction that triggered this
join_method (callable): Function to join the boosters with
Returns
----------
(str): String of boosters
"""
if not interaction.guild.premium_subscribers:
return "**Ingen boostere**"
# Sort boosters by boost date and put name as well as date of boost into a list of stirngs
boosters = [
f"* {b.name} - {discord.utils.format_dt(b.premium_since)}"
for b in sorted(interaction.guild.premium_subscribers, key=lambda m: m.premium_since)
]
return join_method(boosters)
def construct_member_string(self, members: list[discord.Member]) -> str:
"""
Joins all names into a string
Parameters
----------
members (list[discord.Member]): List of members
Returns
----------
(str): String of members
"""
if not members:
return "**Ingen**"
members = [member.name for member in members]
return ", ".join(members)
@app_commands.checks.bot_has_permissions(embed_links=True, external_emojis=True)
@app_commands.checks.cooldown(1, 2)
@guild_group.command(name="info", description="Hent informasjon om en server")
async def guild_info(self, interaction: discord.Interaction):
"""
Sends general information about the guild
Parameters
----------
interaction (discord.Interaction): The slash command interaction
"""
# Days since guild was created
creation_date_timestamp = discord.utils.format_dt(interaction.guild.created_at, style="F")
since_created_days = (interaction.created_at - interaction.guild.created_at).days
days_ago = f"{since_created_days} dager" if since_created_days != 1 else f"{since_created_days} dag"
# Member count and status counts
total_members = interaction.guild.member_count
bot_members = sum(member.bot for member in interaction.guild.members)
status_counts = Counter(member.status for member in interaction.guild.members)
# Roles
roles = self.construct_role_string(interaction.guild.roles)
roles = (
roles
if len(roles) < 1024
else f"Bruk `/{self.bot.tree.get_command('guild').get_command('roller').qualified_name}` for å se rollene"
)
# Boosts
boosters = self.construct_booster_string(interaction, join_method="\n".join)
boosters = (
boosters
if len(boosters) < 1024
else f"Bruk `/{self.bot.tree.get_command('guild').get_command('boosters').qualified_name}` for å se boostere" # noqa: E501
)
# Channels counts
text_channels = len(interaction.guild.text_channels)
voice_channels = len(interaction.guild.voice_channels)
categories = len(interaction.guild.categories)
total_channels = text_channels + voice_channels
# Features
features_string = ""
if interaction.guild.features != []:
features = {
"ANIMATED_BANNER": "Animer serverbanner",
"ANIMATED_ICON": "Animert serverikon",
"APPLICATION_COMMAND_PERMISSIONS_V2": "Gamle slash command tillatelser",
"AUTO_MODERATION": "Automoderering",
"BANNER": "Serverbanner",
"COMMUNITY": "Samfunnsserver",
"CREATOR_MONETIZABLE_PROVISIONAL": "Betalingsmuligheter",
"CREATOR_STORE_PAGE": "Abonnomentsside",
"DEVELOPER_SUPPORT_SERVER": "Støtteserver for utviklere",
"DISCOVERABLE": "På utforsksiden",
"FEATURABLE": "Fremhevbar",
"INVITES_DISABLED": "Invitasjoner deaktivert",
"INVITE_SPLASH": "Invitasjonsbilde",
"MEMBER_VERIFICATION_GATE_ENABLED": "Medlemsverifisering",
"MORE_STICKERS": "Flere stickers",
"NEWS": "Nyhetskanaler",
"PARTNERED": "Partner",
"PREVIEW_ENABLED": "Forhåndsvisning",
"RAID_ALERTS_DISABLED": "Raidvarsler deaktivert",
"ROLE_ICONS": "Rolleikon",
"ROLE_SUBSCRIPTIONS_AVAILABLE_FOR_PURCHASE": "Abonomentsroller tilgjengelig",
"ROLE_SUBSCRIPTIONS_ENABLED": "Abonomentsroller aktivert",
"TICKETED_EVENTS_ENABLED": "Arrangmenter med billettsalg",
"VANITY_URL": "Egendefinert URL",
"VERIFIED": "Verifisert",
"VIP_REGIONS": "Høyere bitrate i stemmekanaler",
"WELCOME_SCREEN_ENABLED": "Velkomstskjerm",
}
for feature in interaction.guild.features:
if translation := features.get(feature):
features_string += f"* {translation}\n"
photos = {}
if interaction.guild.splash:
photos["Invitasjonsbilde"] = interaction.guild.splash
if interaction.guild.banner:
photos["Banner"] = interaction.guild.banner
verification_level = {
"none": "ingen",
"low": "e-post",
"medium": "e-post, registrert i 5 min",
"high": "e-post, registrert i 5 min, medlem i 10 min",
"highest": "telefon",
}
verification = verification_level[str(interaction.guild.verification_level)]
content_filter = {"disabled": "nei", "no_role": "for alle uten rolle", "all_members": "ja"}
content = content_filter[str(interaction.guild.explicit_content_filter)]
embed = discord.Embed(
color=interaction.guild.me.color,
description=f"* **Verifiseringskrav:** {verification}\n"
+ f"* **Innholdsfilter:** {content}\n"
+ f"* **Boost Tier:** {interaction.guild.premium_tier}\n"
+ f"* **Emoji:** {len(interaction.guild.emojis)}\n"
+ f"* **Stickers:** {len(interaction.guild.stickers)}\n",
)
embed.set_author(name=interaction.guild.name, icon_url=interaction.guild.icon)
embed.set_thumbnail(url=interaction.guild.icon)
embed.add_field(name="ID", value=interaction.guild.id)
embed.add_field(name="Eier", value=interaction.guild.owner.mention)
embed.add_field(name="Opprettet", value=f"{creation_date_timestamp}\n{days_ago} siden")
embed.add_field(
name=f"Kanaler ({total_channels})",
value=f"💬 Tekst: **{text_channels}**\n"
+ f"🔊 Tale: **{voice_channels}**\n"
+ f"🗃️ Kategorier: **{categories}**",
)
embed.add_field(
name=f"Medlemmer ({total_members})",
value=f"👤 Mennesker: **{int(total_members) - int(bot_members)}**\n"
+ f"🤖 Båtter: **{bot_members}**\n"
+ discord_utils.format_status_counts(status_counts, self.bot.emoji, " "),
)
embed.add_field(name=f"Roller ({len(interaction.guild.roles) - 1})", value=roles, inline=False)
if interaction.guild.premium_tier != 0:
embed.add_field(
name=f"Boosts ({interaction.guild.premium_subscription_count})", value=boosters, inline=False
)
if features_string:
embed.add_field(name="Tillegsfunksjoner", value=features_string)
if photos:
photos_string = ""
for key, value in photos.items():
photos_string += f"* [{key}]({value})\n"
embed.add_field(name="Bilder", value=photos_string)
await interaction.response.send_message(embed=embed)
@app_commands.checks.bot_has_permissions(embed_links=True, attach_files=True)
@app_commands.checks.cooldown(1, 2)
@guild_group.command(name="roller", description="Se rollene på serveren")
async def guild_roles(self, interaction: discord.Interaction):
"""
List all roles in the guild
Parameters
----------
interaction (discord.Interaction): The slash command interaction
"""
roles = self.construct_role_string(interaction.guild.roles)
# IF roles list is longer than 2048, create text file and send it
if len(roles) > 2048:
await discord_utils.send_as_txt_file(interaction, roles, f"{interaction.guild.id}_roles.txt")
else:
embed = discord.Embed(color=interaction.guild.me.color, description=roles)
embed.set_author(name=f"Roller ({len(interaction.guild.roles)})", icon_url=interaction.guild.icon)
embed.set_footer(text=interaction.guild.name, icon_url=interaction.guild.icon)
await interaction.response.send_message(embed=embed)
@app_commands.checks.bot_has_permissions(embed_links=True)
@app_commands.checks.cooldown(1, 2)
@guild_group.command(name="boosters", description="Se boostere på serveren")
async def guild_boosters(self, interaction: discord.Interaction):
"""
List all boosters in the guild
Parameters
----------
interaction (discord.Interaction): The slash command interaction
"""
if len(interaction.guild.premium_subscribers) == 0:
embed = embed_templates.error_warning("Serveren har ikke noen boosts :(")
return await interaction.response.send_message(embed=embed)
boosters = self.construct_booster_string(interaction, "\n".join)
embed = discord.Embed(color=interaction.guild.me.color, description=boosters)
embed.set_author(
name=f"Boosts ({interaction.guild.premium_subscription_count})", icon_url=interaction.guild.icon
)
embed.set_footer(text=interaction.guild.name, icon_url=interaction.guild.icon)
await interaction.response.send_message(embed=embed)
@app_commands.checks.bot_has_permissions(embed_links=True)
@app_commands.checks.cooldown(1, 2)
@guild_group.command(name="ikon", description="Hent serverens ikon")
async def guild_icon(self, interaction: discord.Interaction):
"""
Get the guild icon
Parameters
----------
interaction (discord.Interaction): The slash command interaction
"""
embed = discord.Embed(color=interaction.guild.me.color, description=f"[Lenke]({interaction.guild.icon})")
embed.set_author(name=interaction.guild.name, icon_url=interaction.guild.icon)
embed.set_image(url=interaction.guild.icon)
await interaction.response.send_message(embed=embed)
@app_commands.checks.bot_has_permissions(embed_links=True)
@app_commands.checks.cooldown(1, 2)
@guild_group.command(name="splash", description="Hent serverens splash (bakgrunnsbilde på invitasjonsside)")
async def guild_splash(self, interaction: discord.Interaction):
"""
Get the guild splash
Parameters
----------
interaction (discord.Interaction): The slash command interaction
"""
if not interaction.guild.splash:
embed = embed_templates.error_warning("Serveren har ikke en splash")
return await interaction.response.send_message(embed=embed)
embed = discord.Embed(color=interaction.guild.me.color, description=f"[Lenke]({interaction.guild.splash})")
embed.set_author(name=interaction.guild.name, icon_url=interaction.guild.icon)
embed.set_image(url=interaction.guild.splash)
await interaction.response.send_message(embed=embed)
@app_commands.checks.bot_has_permissions(embed_links=True)
@app_commands.checks.cooldown(1, 2)
@guild_group.command(name="banner", description="Hen serverens banner")
async def guild_banner(self, interaction: discord.Interaction):
"""
Get the guild banner
Parameters
----------
interaction (discord.Interaction): The slash command interaction
"""
if not interaction.guild.banner:
embed = embed_templates.error_warning("Serveren har ikke et banner :(")
return await interaction.response.send_message(embed=embed)
embed = discord.Embed(color=interaction.guild.me.color, description=f"[Lenke]({interaction.guild.banner})")
embed.set_author(name=interaction.guild.name, icon_url=interaction.guild.icon)
embed.set_image(url=interaction.guild.banner)
await interaction.response.send_message(embed=embed)
@app_commands.checks.bot_has_permissions(embed_links=True)
@app_commands.checks.cooldown(1, 2)
@guild_group.command(name="rolle", description="Hent informasjon om en rolle på serveren")
@app_commands.rename(role="rolle")
@app_commands.describe(role="Rollen du vil se informasjon om")
async def guild_role(self, interaction: discord.Interaction, role: discord.Role):
"""
Get information about a role
Parameters
----------
interaction (discord.Interaction): The slash command interaction
role (discord.Role): Role to fetch information about
"""
if role.name == "@everyone":
embed = embed_templates.error_warning("Skriv inn en annen rolle enn `@everyone`")
return await interaction.response.send_message(embed=embed)
# Timestamp and days since creation
created_at_timestamp = discord.utils.format_dt(role.created_at, style="F")
since_created_days = (interaction.created_at - role.created_at).days
# List of members with the role
members = self.construct_member_string(role.members)
members = members if len(members) < 1024 else "For mange medlemmer for å vise her"
# List of permissions
permissions = ", ".join([permission for permission, value in iter(role.permissions) if value is True])
embed = discord.Embed(title=role.name, description=f"{role.mention}\n**ID:** {role.id}", color=role.color)
embed.set_author(name=role.guild.name, icon_url=role.guild.icon)
embed.add_field(name="Fargekode", value=str(role.color))
embed.add_field(
name="Opprettet",
value=f"{created_at_timestamp}\n{since_created_days} "
+ f'{"dager" if since_created_days != 1 else "dag"} siden',
)
embed.add_field(name="Posisjon", value=role.position)
embed.add_field(name="Nevnbar", value="Ja" if role.mentionable else "Nei")
embed.add_field(name="Vises separat i medlemsliste", value="Ja" if role.hoist else "Nei")
if permissions:
embed.add_field(name="Tillatelser", value=permissions, inline=False)
embed.add_field(name=f"Brukere med rollen ({len(role.members)})", value=members, inline=False)
await interaction.response.send_message(embed=embed)
@app_commands.checks.bot_has_permissions(embed_links=True)
@app_commands.checks.cooldown(1, 2)
@guild_group.command(name="tekstkanal", description="Hent informasjon om en tekstkanal")
@app_commands.rename(channel="kanal")
@app_commands.describe(channel="Tekstkanalen du vil se informasjon om")
async def guild_text_channel(self, interaction: discord.Interaction, channel: discord.TextChannel):
"""
Get information about a text channel
Parameters
----------
interaction (discord.Interaction): The slash command interaction
channel (discord.TextChannel): Text channel to fetch information about
"""
members = self.construct_member_string(channel.members)
if len(members) > 1024:
members = "For mange for å vise her"
embed = discord.Embed(
color=interaction.guild.me.color, title=channel.name, description=f"{channel.mention}\nID: {channel.id}"
)
embed.set_author(name=channel.guild.name, icon_url=channel.guild.icon)
embed.add_field(name="Beskrivelse", value=channel.topic if channel.topic else "**Ingen**", inline=False)
embed.add_field(name="Opprettet", value=discord.utils.format_dt(channel.created_at, style="F"))
embed.add_field(name="NSFW", value="Ja" if channel.is_nsfw() else "Nei")
embed.add_field(
name="Saktemodus", value=f"Ja ({channel.slowmode_delay} sekunder)" if channel.slowmode_delay else "Nei"
)
if channel.category:
embed.add_field(name="Kategori", value=channel.category.name)
embed.add_field(name=f"Antall med tilgang ({len(channel.members)})", value=members)
await interaction.response.send_message(embed=embed)
@app_commands.checks.bot_has_permissions(embed_links=True)
@app_commands.checks.cooldown(1, 2)
@guild_group.command(name="talekanal", description="Hent informasjon om en talekanal")
@app_commands.rename(channel="kanal")
@app_commands.describe(channel="Talekanalen du vil se informasjon om")
async def guild_voice_channel(self, interaction: discord.Interaction, channel: discord.VoiceChannel):
"""
Get information about a voice channel
Parameters
----------
interaction (discord.Interaction): The slash command interaction
channel (discord.VoiceChannel): Voice channel to fetch information about
"""
embed = discord.Embed(color=interaction.guild.me.color, title=channel.name, description=f"ID: {channel.id}")
embed.set_author(name=channel.guild.name, icon_url=channel.guild.icon)
embed.add_field(name="Opprettet", value=discord.utils.format_dt(channel.created_at, style="F"))
embed.add_field(name="Bitrate", value=f"{int(channel.bitrate / 1000)}kbps")
embed.add_field(
name="Maksgrense", value=f"{channel.user_limit} personer" if channel.user_limit != 0 else "∞ personer"
)
if channel.category:
embed.add_field(name="Kategori", value=channel.category.name)
embed.add_field(name="Antall koblet til", value=len(channel.members))
await interaction.response.send_message(embed=embed)
@app_commands.checks.bot_has_permissions(embed_links=True)
@app_commands.checks.cooldown(1, 5)
@guild_group.command(name="topproller", description="Viser rollene med flest brukere i kronologisk rekkefølge")
async def guild_top_roles(self, interaction: discord.Interaction):
"""
Show the roles with the most users in chronological order
Parameters
----------
interaction (discord.Interaction): The slash command interaction
"""
roles = sorted(
[r for r in interaction.guild.roles if r.name != "@everyone"], key=lambda x: len(x.members), reverse=True
)
roles_formatted = [f"**#{i + 1}** {r.mention} - {len(r.members)}" for i, r in enumerate(roles)]
paginator = misc_utils.Paginator(roles_formatted)
view = discord_utils.Scroller(paginator, interaction.user)
embed = view.construct_embed(
discord.Embed(color=interaction.guild.me.color, title="Rollene med flest brukere på serveren")
)
await interaction.response.send_message(embed=embed, view=view)
@app_commands.guild_only()
@app_commands.checks.bot_has_permissions(embed_links=True)
@app_commands.checks.cooldown(1, 2)
@app_commands.command(name="emoji", description="Hent informasjon om en emoji i serveren")
@app_commands.describe(emoji="Emojien du vil se informasjon om")
async def emoji(self, interaction: discord.Interaction, emoji: str):
"""
Get information about an emoji in the server
Parameters
----------
interaction (discord.Interaction): The slash command interaction
emoji (discord.Emoji): Emoji to fetch information about
"""
emoji = discord.PartialEmoji.from_str(emoji)
if not emoji.is_custom_emoji():
embed = embed_templates.error_warning("Denne kommandoen støtter bare serveremoji")
return await interaction.response.send_message(embed=embed)
try:
emoji = await interaction.guild.fetch_emoji(emoji.id)
except discord.NotFound:
embed = embed_templates.error_warning("Emoji kunne ikke hentes. Den er muligens fra en annen server")
return await interaction.response.send_message(embed=embed)
self.bot.logger.info(emoji)
try:
emoji_creator = f"{emoji.user.mention}\n{emoji.user.name}"
except AttributeError:
emoji_creator = "Jeg trenger `manage_emojis`-tillatelsen på serveren den er fra for å hente dette"
embed = discord.Embed(title=emoji.name, description=f"ID: {emoji.id}")
embed.set_author(name=emoji.guild.name, icon_url=emoji.guild.icon)
embed.add_field(name="Opprettet", value=discord.utils.format_dt(emoji.created_at, style="F"))
embed.add_field(name="Animert", value="Ja" if emoji.animated else "Nei")
embed.add_field(name="Lagt til av", value=emoji_creator)
embed.set_image(url=emoji.url)
await interaction.response.send_message(embed=embed)
@commands.guild_only()
@commands.bot_has_permissions(embed_links=True)
@commands.cooldown(1, 2, commands.BucketType.user)
@commands.command(name="sticker", description="Hent informasjon om en sticker på serveren")
async def sticker(self, ctx: commands.Context):
"""
Get information about a sticker in the server
Parameters
----------
ctx (commands.Context): The command context
"""
if ctx.message.type != discord.MessageType.reply:
embed = embed_templates.error_warning("Du må svare på en melding som inneholder en sticker")
return await ctx.reply(embed=embed)
if ctx.message.reference and isinstance(ctx.message.reference.resolved, discord.Message):
replied_message = ctx.message.reference.resolved
elif ctx.message.reference:
try:
replied_message = await ctx.message.channel.fetch_message(ctx.message.reference.message_id)
except discord.NotFound:
embed = embed_templates.error_warning("Kunne ikke hente meldingen du svarte på")
return await ctx.reply(embed=embed)
if not replied_message.stickers:
embed = embed_templates.error_warning("Meldingen du svarte på inneholder ikke en sticker")
return await ctx.reply(embed=embed)
try:
sticker = await replied_message.guild.fetch_sticker(replied_message.stickers[0].id)
except discord.NotFound:
embed = embed_templates.error_warning("Sticker kunne ikke hentes. Den er muligens fra en annen server")
return await ctx.reply(embed=embed)
embed = discord.Embed(title=sticker.name, description=f"ID: {sticker.id}\n\n{sticker.description}")
embed.set_author(name=sticker.guild.name, icon_url=sticker.guild.icon)
embed.add_field(name="Opprettet", value=discord.utils.format_dt(sticker.created_at, style="F"))
embed.add_field(name="Format", value=str(sticker.format).split(".")[-1].upper())
embed.add_field(name="Emoji", value=sticker.emoji)
embed.add_field(name="Lagt til av", value=sticker.user.mention if sticker.user else "Ikke tilgjengelig")
embed.set_image(url=sticker.url)
await ctx.reply(embed=embed)
guild_oldest_group = app_commands.Group(
name="eldst", description="Viser de eldste medlemmene på serveren", parent=guild_group
)
@app_commands.checks.bot_has_permissions(embed_links=True)
@app_commands.checks.cooldown(1, 5)
@guild_oldest_group.command(
name="lagd", description="Liste over de eldste brukerene på serveren basert på når de ble lagd"
)
async def guild_user_created_oldest(self, interaction: discord.Interaction):
"""
List the oldest users on the server based on when they were created
Parameters
----------
interaction (discord.Interaction): The slash command interaction
"""
# Sort members by creation date
members = sorted(interaction.guild.members, key=lambda m: m.created_at)
# Create list of members with index, name and creation date
members_formatted = [
f"**#{i+1}** {m.name} - {discord.utils.format_dt(m.created_at, style='F')}" for i, m in enumerate(members)
]
paginator = misc_utils.Paginator(members_formatted)
view = discord_utils.Scroller(paginator, interaction.user)
embed = view.construct_embed(
discord.Embed(
color=interaction.guild.me.color, title="Eldste brukere på serveren basert på når de ble lagd"
)
)
await interaction.response.send_message(embed=embed, view=view)
@app_commands.checks.bot_has_permissions(embed_links=True)
@app_commands.checks.cooldown(1, 5)
@guild_oldest_group.command(
name="joined", description="Liste over de eldste brukerene på serveren basert på når de ble med"
)
async def guild_user_joined_oldest(self, interaction: discord.Interaction):
"""
List the oldest users on the server based on when they joined
Parameters
----------
interaction (discord.Interaction): The slash command interaction
"""
# Sort members by creation date
members = sorted(interaction.guild.members, key=lambda m: m.joined_at)
# Create list of members with index, name#discriminator and creation date
members_formatted = [
f"**#{i+1}** {m.name} - {discord.utils.format_dt(m.joined_at, style='F')}" for i, m in enumerate(members)
]
paginator = misc_utils.Paginator(members_formatted)
view = discord_utils.Scroller(paginator, interaction.user)
# Send first page
embed = view.construct_embed(
discord.Embed(color=interaction.guild.me.color, title="Eldste brukere på serveren basert på når de ble med")
)
await interaction.response.send_message(embed=embed, view=view)
@app_commands.checks.bot_has_permissions(embed_links=True, external_emojis=True)
@app_commands.checks.cooldown(1, 2)
@user_group.command(name="info", description="Hent informasjon om en bruker")
@app_commands.rename(user="bruker")
@app_commands.describe(user="Brukeren du vil se informasjon om. Standard er deg selv")
async def user_info(self, interaction: discord.Interaction, *, user: discord.Member | None = None):
"""
Get information about a user
Parameters
----------
interaction (discord.Interaction): The slash command interaction
user (discord.Member | None): The user to get information about. Defaults to the invoking user
"""
if not user:
user = interaction.user
# Get device(s) that is currently used by the user
app = ""
if str(user.mobile_status) != "offline":
app += "📱 "
if str(user.web_status) != "offline":
app += "🌐 "
if str(user.desktop_status) != "offline":
app += "💻"
# Get index of join, creation and/or boost date in comparison to other users in the guild
join_index = sorted(interaction.guild.members, key=lambda m: m.joined_at).index(user) + 1
creation_index = sorted(interaction.guild.members, key=lambda m: m.created_at).index(user) + 1
if user.premium_since:
premium_index = sorted(interaction.guild.premium_subscribers, key=lambda m: m.premium_since).index(user) + 1
# Creation/join date & days ago
created_timestamp = discord.utils.format_dt(user.created_at, style="F")
joined_timestamp = discord.utils.format_dt(user.joined_at, style="F")
joined_days = (interaction.created_at - user.joined_at).days
created_days = (interaction.created_at - user.created_at).days
# Boost date & days ago
if user.premium_since:
premium_since = discord.utils.format_dt(user.premium_since, style="F")
premium_since_days = (interaction.created_at - user.premium_since).days
# Get user roles
roles = self.construct_role_string(user.roles)
roles = (
roles
if len(roles) < 1024
else f'Bruk `/{self.bot.tree.get_command("bruker").get_command("roller").qualified_name}` for å se rollene'
)
statuses = {
"online": f'{self.bot.emoji["online"]} Pålogget',
"idle": f'{self.bot.emoji["idle"]} Inaktiv',
"dnd": f'{self.bot.emoji["dnd"]} Ikke forstyrr',
"offline": f'{self.bot.emoji["offline"]} Frakoblet',
}
status = statuses[str(user.status)]
embed = discord.Embed(color=user.color, description=f"{user.mention}\nID: {user.id}\n{status}\n{app}")
if user.display_name == user.name:
embed.set_author(name=user.name, icon_url=user.display_avatar)
else:
embed.set_author(name=f"{user.name} | {user.display_name}", icon_url=user.display_avatar)
embed.set_thumbnail(url=user.display_avatar)
embed.add_field(
name="Opprettet",
value=f"{created_timestamp}\n{created_days} " + f'{"dag" if created_days == 1 else "dager"} siden',
)
embed.add_field(
name="Ble med i serveren",
value=f"{joined_timestamp}\n{joined_days} " + f'{"dag" if joined_days == 1 else "dager"} siden',
)
if user.premium_since:
embed.add_field(
name="Boost",
value=f"{premium_since}\n{premium_since_days} "
+ f'{"dag" if premium_since_days == 1 else "dager"} siden\n'
+ f"Booster #{premium_index} av serveren",
inline=False,
)
embed.add_field(name=f"Roller ({len(user.roles)})", value=roles, inline=False)
embed.set_footer(text=f"#{join_index} Medlem av serveren | #{creation_index} Eldste brukeren på serveren")
# Playing activity
if user.activities:
games = ""
for activity in user.activities:
games += f"{activity.name}\n"
if games:
embed.add_field(name="Spiller", value=games, inline=False)
await interaction.response.send_message(embed=embed)
@app_commands.checks.bot_has_permissions(embed_links=True)
@app_commands.checks.cooldown(1, 2)
@user_group.command(name="roller", description="Hent roller til en bruker")
@app_commands.rename(user="bruker")
@app_commands.describe(user="Brukeren du vil se rollene til. Standard er deg selv")
async def user_roles(self, interaction: discord.Interaction, user: discord.Member | None = None):
"""
Get roles of a user
Parameters
----------
interaction (discord.Interaction): The slash command interaction
user (discord.Member | None): The user to get the roles of. Defaults to the invoking user
"""
if not user:
user = interaction.user
roles = self.construct_role_string(user.roles)
# If the list of roles is too long, send it as a file
if len(roles) > 2048:
await discord_utils.send_as_txt_file(
interaction, roles, f"{interaction.guild.id}_{interaction.user.id}_roles.txt"
)
else:
embed = discord.Embed(color=user.color, description=roles)
embed.set_author(name=f"Roller ({len(user.roles)})", icon_url=user.display_avatar)
embed.set_footer(text=user.name, icon_url=user.display_avatar)
await interaction.response.send_message(embed=embed)
@app_commands.checks.bot_has_permissions(embed_links=True)
@app_commands.checks.cooldown(1, 2)
@user_group.command(name="manglenderoller", description="Se hvilke roller en bruker ikke har i en guild")
@app_commands.rename(user="bruker")
@app_commands.describe(user="Brukeren du vil se manglende roller for. Standard er deg selv")
async def user_missing_roles(self, interaction: discord.Interaction, user: discord.Member | None = None):
"""
See which roles a user does not have in a guild
Parameters
----------
interaction (discord.Interaction): The slash command interaction
user (discord.Member | None): The user to get the missing roles of. Defaults to the invoking user
"""
if not user:
user = interaction.user
missing_roles = set(interaction.guild.roles) - set(user.roles)
roles = self.construct_role_string(missing_roles)
# If the list of roles is too long, send it as a file
if len(roles) > 2048:
await discord_utils.send_as_txt_file(
interaction, roles, f"{interaction.guild.id}_{interaction.user.id}_missing_roles.txt"
)
else:
embed = discord.Embed(color=user.color, description=roles)
embed.set_author(name=f"Manglende roller ({len(missing_roles)})", icon_url=user.display_avatar)
embed.set_footer(text=user.name, icon_url=user.display_avatar)
await interaction.response.send_message(embed=embed)
@app_commands.checks.bot_has_permissions(embed_links=True)
@app_commands.checks.cooldown(1, 2)
@user_group.command(name="avatar", description="Hent avatar til en bruker")
@app_commands.rename(user="bruker")
@app_commands.describe(user="Brukeren du vil se avataren til. Standard er deg selv")
async def user_avatar(self, interaction: discord.Interaction, user: discord.User | discord.Member | None = None):
"""
Get avatar of a user
Parameters
----------
interaction (discord.Interaction): The slash command interaction
user (discord.User | None): The user to get the avatar of. Defaults to the invoking user
"""
if not user:
user = interaction.user
embed = discord.Embed(color=user.color, description=f"[Lenke]({user.display_avatar})")
embed.set_author(name=user.name, icon_url=user.display_avatar)
embed.set_image(url=user.display_avatar)
await interaction.response.send_message(embed=embed)
async def setup(bot: commands.Bot):
"""
Add the cog to the bot on extension load
Parameters
----------
bot (commands.Bot): The bot instance
"""
await bot.add_cog(Info(bot))