fixed userinfo

This commit is contained in:
Seaswimmer 2023-03-03 15:03:32 -05:00
parent ba3e9402b5
commit 9247d7f74f

View file

@ -1,23 +1,20 @@
from datetime import datetime
import time
from enum import Enum
from random import randint, choice
from typing import Final
import urllib.parse
import aiohttp
from typing import Final, cast
import discord
from redbot.core import commands
from redbot.core import commands, checks
from redbot.core.bot import Red
from redbot.core.i18n import Translator, cog_i18n
from redbot.core.utils.menus import menu
import re
from redbot.core.utils.chat_formatting import (
bold,
escape,
italics,
humanize_number,
humanize_timedelta,
)
from redbot.core.utils.common_filters import (
filter_invites
)
_ = T_ = Translator("General", __file__)
@ -261,25 +258,230 @@ class Info(commands.Cog):
await ctx.send(embed=data)
def handle_custom(self, user):
a = [c for c in user.activities if c.type == discord.ActivityType.custom]
if not a:
return None, discord.ActivityType.custom
a = a[0]
c_status = None
if not a.name and not a.emoji:
return None, discord.ActivityType.custom
elif a.name and a.emoji:
c_status = _("Custom: {emoji} {name}").format(emoji=a.emoji, name=a.name)
elif a.emoji:
c_status = _("Custom: {emoji}").format(emoji=a.emoji)
elif a.name:
c_status = _("Custom: {name}").format(name=a.name)
return c_status, discord.ActivityType.custom
def handle_playing(self, user):
p_acts = [c for c in user.activities if c.type == discord.ActivityType.playing]
if not p_acts:
return None, discord.ActivityType.playing
p_act = p_acts[0]
act = _("Playing: {name}").format(name=p_act.name)
return act, discord.ActivityType.playing
def handle_streaming(self, user):
s_acts = [c for c in user.activities if c.type == discord.ActivityType.streaming]
if not s_acts:
return None, discord.ActivityType.streaming
s_act = s_acts[0]
if isinstance(s_act, discord.Streaming):
act = _("Streaming: [{name}{sep}{game}]({url})").format(
name=discord.utils.escape_markdown(s_act.name),
sep=" | " if s_act.game else "",
game=discord.utils.escape_markdown(s_act.game) if s_act.game else "",
url=s_act.url,
)
else:
act = _("Streaming: {name}").format(name=s_act.name)
return act, discord.ActivityType.streaming
def handle_listening(self, user):
l_acts = [c for c in user.activities if c.type == discord.ActivityType.listening]
if not l_acts:
return None, discord.ActivityType.listening
l_act = l_acts[0]
if isinstance(l_act, discord.Spotify):
act = _("Listening: [{title}{sep}{artist}]({url})").format(
title=discord.utils.escape_markdown(l_act.title),
sep=" | " if l_act.artist else "",
artist=discord.utils.escape_markdown(l_act.artist) if l_act.artist else "",
url=f"https://open.spotify.com/track/{l_act.track_id}",
)
else:
act = _("Listening: {title}").format(title=l_act.name)
return act, discord.ActivityType.listening
def handle_watching(self, user):
w_acts = [c for c in user.activities if c.type == discord.ActivityType.watching]
if not w_acts:
return None, discord.ActivityType.watching
w_act = w_acts[0]
act = _("Watching: {name}").format(name=w_act.name)
return act, discord.ActivityType.watching
def handle_competing(self, user):
w_acts = [c for c in user.activities if c.type == discord.ActivityType.competing]
if not w_acts:
return None, discord.ActivityType.competing
w_act = w_acts[0]
act = _("Competing in: {competing}").format(competing=w_act.name)
return act, discord.ActivityType.competing
def get_status_string(self, user):
string = ""
for a in [
self.handle_custom(user),
self.handle_playing(user),
self.handle_listening(user),
self.handle_streaming(user),
self.handle_watching(user),
self.handle_competing(user),
]:
status_string, status_type = a
if status_string is None:
continue
string += f"{status_string}\n"
return string
@commands.command()
@commands.guild_only()
async def userinfo(self, ctx, member: discord.Member):
"""Gives information on a specific person."""
if member.color.value == 0:
colorint = 10070709
@commands.bot_has_permissions(embed_links=True)
async def userinfo(self, ctx, *, member: discord.Member = None):
"""Show information about a member.
This includes fields for status, discord join date, server
join date, voice state and previous names/nicknames.
If the member has no roles, previous names or previous nicknames,
these fields will be omitted.
"""
author = ctx.author
guild = ctx.guild
if not member:
member = author
# A special case for a special someone :^)
special_date = datetime.datetime(2016, 1, 10, 6, 8, 4, 443000, datetime.timezone.utc)
is_special = member.id == 96130341705637888 and guild.id == 133049272517001216
roles = member.roles[-1:0:-1]
names, nicks = await self.get_names_and_nicks(member)
if is_special:
joined_at = special_date
else:
colorint = member.color.value
avatarurl = str(member.avatar_url)
timestamp_create = int(datetime.timestamp(member.created_at))
timestamp_join = int(datetime.timestamp(member.joined_at))
embed = discord.Embed(title=f"{member.name}#{member.discriminator}", color=colorint)
embed.add_field(name="Joined At", value=f"<t:{timestamp_join}>")
embed.add_field(name="Created At", value=f"<t:{timestamp_create}>")
embed.add_field(name="Avatar", value=f"[Click Here]({avatarurl})")
embed.add_field(name="Roles", value=f"{member.roles}")
embed.set_thumbnail(url=f"{avatarurl}")
embed.set_footer(text=f"ID: {member.id}")
await ctx.send(embed=embed)
joined_at = member.joined_at
voice_state = member.voice
member_number = (
sorted(guild.members, key=lambda m: m.joined_at or ctx.message.created_at).index(
member
)
+ 1
)
created_on = (
f"{discord.utils.format_dt(member.created_at)}\n"
f"{discord.utils.format_dt(member.created_at, 'R')}"
)
if joined_at is not None:
joined_on = (
f"{discord.utils.format_dt(joined_at)}\n"
f"{discord.utils.format_dt(joined_at, 'R')}"
)
else:
joined_on = _("Unknown")
if any(a.type is discord.ActivityType.streaming for a in member.activities):
statusemoji = "\N{LARGE PURPLE CIRCLE}"
elif member.status.name == "online":
statusemoji = "\N{LARGE GREEN CIRCLE}"
elif member.status.name == "offline":
statusemoji = "\N{MEDIUM WHITE CIRCLE}\N{VARIATION SELECTOR-16}"
elif member.status.name == "dnd":
statusemoji = "\N{LARGE RED CIRCLE}"
elif member.status.name == "idle":
statusemoji = "\N{LARGE ORANGE CIRCLE}"
activity = _("Chilling in {} status").format(member.status)
status_string = self.get_status_string(member)
if roles:
role_str = ", ".join([x.mention for x in roles])
# 400 BAD REQUEST (error code: 50035): Invalid Form Body
# In embed.fields.2.value: Must be 1024 or fewer in length.
if len(role_str) > 1024:
# Alternative string building time.
# This is not the most optimal, but if you're hitting this, you are losing more time
# to every single check running on users than the occasional user info invoke
# We don't start by building this way, since the number of times we hit this should be
# infinitesimally small compared to when we don't across all uses of Red.
continuation_string = _(
"and {numeric_number} more roles not displayed due to embed limits."
)
available_length = 1024 - len(continuation_string) # do not attempt to tweak, i18n
role_chunks = []
remaining_roles = 0
for r in roles:
chunk = f"{r.mention}, "
chunk_size = len(chunk)
if chunk_size < available_length:
available_length -= chunk_size
role_chunks.append(chunk)
else:
remaining_roles += 1
role_chunks.append(continuation_string.format(numeric_number=remaining_roles))
role_str = "".join(role_chunks)
else:
role_str = None
data = discord.Embed(description=status_string or activity, colour=member.colour)
data.add_field(name=_("Joined Discord on"), value=created_on)
data.add_field(name=_("Joined this server on"), value=joined_on)
if role_str is not None:
data.add_field(
name=_("Roles") if len(roles) > 1 else _("Role"), value=role_str, inline=False
)
if names:
# May need sanitizing later, but mentions do not ping in embeds currently
val = filter_invites(", ".join(names))
data.add_field(
name=_("Previous Names") if len(names) > 1 else _("Previous Name"),
value=val,
inline=False,
)
if nicks:
# May need sanitizing later, but mentions do not ping in embeds currently
val = filter_invites(", ".join(nicks))
data.add_field(
name=_("Previous Nicknames") if len(nicks) > 1 else _("Previous Nickname"),
value=val,
inline=False,
)
if voice_state and voice_state.channel:
data.add_field(
name=_("Current voice channel"),
value="{0.mention} ID: {0.id}".format(voice_state.channel),
inline=False,
)
data.set_footer(text=_("Member #{} | User ID: {}").format(member_number, member.id))
name = str(member)
name = " ~ ".join((name, member.nick)) if member.nick else name
name = filter_invites(name)
avatar = member.display_avatar.replace(static_format="png")
data.set_author(name=f"{statusemoji} {name}", url=avatar)
data.set_thumbnail(url=avatar)
await ctx.send(embed=data)
@commands.command()
@commands.guild_only()