Remove a large amount of fetch_user calls (#3075)

* Non-audio changes

* address Flame's feedback
This commit is contained in:
Michael H 2019-12-21 01:15:34 -05:00 committed by GitHub
parent b457f8d1c1
commit a36e95c286
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 65 additions and 50 deletions

View File

@ -0,0 +1 @@
Red takes less time to fetch cases, unban members, and list warnings.

View File

@ -0,0 +1,3 @@
Red no longer uses bot.fetch_user in core
- This is a 1/1s global ratelimit
- It really really really should be avoided.

View File

@ -122,14 +122,23 @@ class KickBanMixin(MixinMeta):
member = namedtuple("Member", "id guild") member = namedtuple("Member", "id guild")
while self == self.bot.get_cog("Mod"): while self == self.bot.get_cog("Mod"):
for guild in self.bot.guilds: for guild in self.bot.guilds:
if not guild.me.guild_permissions.ban_members:
continue
try:
banned_users = {b.user.id: b.user for b in (await guild.bans())}
except discord.HTTPException:
continue
async with self.settings.guild(guild).current_tempbans() as guild_tempbans: async with self.settings.guild(guild).current_tempbans() as guild_tempbans:
for uid in guild_tempbans.copy(): for uid in guild_tempbans.copy():
user = banned_users.get(uid, None)
if not user:
continue
unban_time = datetime.utcfromtimestamp( unban_time = datetime.utcfromtimestamp(
await self.settings.member(member(uid, guild)).banned_until() await self.settings.member(member(uid, guild)).banned_until()
) )
if datetime.utcnow() > unban_time: # Time to unban the user if datetime.utcnow() > unban_time: # Time to unban the user
user = await self.bot.fetch_user(uid) queue_entry = (guild.id, uid)
queue_entry = (guild.id, user.id)
try: try:
await guild.unban(user, reason=_("Tempban finished")) await guild.unban(user, reason=_("Tempban finished"))
guild_tempbans.remove(uid) guild_tempbans.remove(uid)
@ -137,7 +146,7 @@ class KickBanMixin(MixinMeta):
# 50013: Missing permissions error code or 403: Forbidden status # 50013: Missing permissions error code or 403: Forbidden status
if e.code == 50013 or e.status == 403: if e.code == 50013 or e.status == 403:
log.info( log.info(
f"Failed to unban {user}({user.id}) user from " f"Failed to unban ({uid}) user from "
f"{guild.name}({guild.id}) guild due to permissions" f"{guild.name}({guild.id}) guild due to permissions"
) )
break # skip the rest of this guild break # skip the rest of this guild
@ -334,15 +343,13 @@ class KickBanMixin(MixinMeta):
else: else:
banned.append(user_id) banned.append(user_id)
user_info = await self.bot.fetch_user(user_id)
try: try:
await modlog.create_case( await modlog.create_case(
self.bot, self.bot,
guild, guild,
ctx.message.created_at, ctx.message.created_at,
"hackban", "hackban",
user_info, user_id,
author, author,
reason, reason,
until=None, until=None,
@ -551,18 +558,14 @@ class KickBanMixin(MixinMeta):
click the user and select 'Copy ID'.""" click the user and select 'Copy ID'."""
guild = ctx.guild guild = ctx.guild
author = ctx.author author = ctx.author
try:
user = await self.bot.fetch_user(user_id)
except discord.errors.NotFound:
await ctx.send(_("Couldn't find a user with that ID!"))
return
audit_reason = get_audit_reason(ctx.author, reason) audit_reason = get_audit_reason(ctx.author, reason)
bans = await guild.bans() bans = await guild.bans()
bans = [be.user for be in bans] bans = [be.user for be in bans]
if user not in bans: user = discord.utils.get(bans, id=user_id)
if not user:
await ctx.send(_("It seems that user isn't banned!")) await ctx.send(_("It seems that user isn't banned!"))
return return
queue_entry = (guild.id, user.id) queue_entry = (guild.id, user_id)
try: try:
await guild.unban(user, reason=audit_reason) await guild.unban(user, reason=audit_reason)
except discord.HTTPException: except discord.HTTPException:
@ -586,6 +589,13 @@ class KickBanMixin(MixinMeta):
await ctx.send(_("Unbanned that user from this server")) await ctx.send(_("Unbanned that user from this server"))
if await self.settings.guild(guild).reinvite_on_unban(): if await self.settings.guild(guild).reinvite_on_unban():
user = ctx.bot.get_user(user_id)
if not user:
await ctx.send(
_("I don't share another server with this user. I can't reinvite them.")
)
return
invite = await self.get_invite_for_reinvite(ctx) invite = await self.get_invite_for_reinvite(ctx)
if invite: if invite:
try: try:

View File

@ -374,13 +374,8 @@ class Warnings(commands.Cog):
await ctx.send(_("That user has no warnings!")) await ctx.send(_("That user has no warnings!"))
else: else:
for key in user_warnings.keys(): for key in user_warnings.keys():
mod = ctx.guild.get_member(user_warnings[key]["mod"]) mod_id = user_warnings[key]["mod"]
if mod is None: mod = ctx.bot.get_user(mod_id) or _("Unknown Moderator ({})").format(mod_id)
mod = discord.utils.get(
self.bot.get_all_members(), id=user_warnings[key]["mod"]
)
if mod is None:
mod = await self.bot.fetch_user(user_warnings[key]["mod"])
msg += _( msg += _(
"{num_points} point warning {reason_name} issued by {user} for " "{num_points} point warning {reason_name} issued by {user} for "
"{description}\n" "{description}\n"

View File

@ -1687,13 +1687,14 @@ class Core(commands.Cog, CoreLogic):
pass pass
@whitelist.command(name="add") @whitelist.command(name="add")
async def whitelist_add(self, ctx, user: discord.User): async def whitelist_add(self, ctx, *, user: Union[discord.Member, int]):
""" """
Adds a user to the whitelist. Adds a user to the whitelist.
""" """
uid = getattr(user, "id", user)
async with ctx.bot._config.whitelist() as curr_list: async with ctx.bot._config.whitelist() as curr_list:
if user.id not in curr_list: if uid not in curr_list:
curr_list.append(user.id) curr_list.append(uid)
await ctx.send(_("User added to whitelist.")) await ctx.send(_("User added to whitelist."))
@ -1712,16 +1713,16 @@ class Core(commands.Cog, CoreLogic):
await ctx.send(box(page)) await ctx.send(box(page))
@whitelist.command(name="remove") @whitelist.command(name="remove")
async def whitelist_remove(self, ctx: commands.Context, *, user: discord.User): async def whitelist_remove(self, ctx: commands.Context, *, user: Union[discord.Member, int]):
""" """
Removes user from whitelist. Removes user from whitelist.
""" """
removed = False removed = False
uid = getattr(user, "id", user)
async with ctx.bot._config.whitelist() as curr_list: async with ctx.bot._config.whitelist() as curr_list:
if user.id in curr_list: if uid in curr_list:
removed = True removed = True
curr_list.remove(user.id) curr_list.remove(uid)
if removed: if removed:
await ctx.send(_("User has been removed from whitelist.")) await ctx.send(_("User has been removed from whitelist."))
@ -1745,7 +1746,7 @@ class Core(commands.Cog, CoreLogic):
pass pass
@blacklist.command(name="add") @blacklist.command(name="add")
async def blacklist_add(self, ctx: commands.Context, *, user: discord.User): async def blacklist_add(self, ctx: commands.Context, *, user: Union[discord.Member, int]):
""" """
Adds a user to the blacklist. Adds a user to the blacklist.
""" """
@ -1753,9 +1754,10 @@ class Core(commands.Cog, CoreLogic):
await ctx.send(_("You cannot blacklist an owner!")) await ctx.send(_("You cannot blacklist an owner!"))
return return
uid = getattr(user, "id", user)
async with ctx.bot._config.blacklist() as curr_list: async with ctx.bot._config.blacklist() as curr_list:
if user.id not in curr_list: if uid not in curr_list:
curr_list.append(user.id) curr_list.append(uid)
await ctx.send(_("User added to blacklist.")) await ctx.send(_("User added to blacklist."))
@ -1774,16 +1776,17 @@ class Core(commands.Cog, CoreLogic):
await ctx.send(box(page)) await ctx.send(box(page))
@blacklist.command(name="remove") @blacklist.command(name="remove")
async def blacklist_remove(self, ctx: commands.Context, *, user: discord.User): async def blacklist_remove(self, ctx: commands.Context, *, user: Union[discord.Member, int]):
""" """
Removes user from blacklist. Removes user from blacklist.
""" """
removed = False removed = False
uid = getattr(user, "id", user)
async with ctx.bot._config.blacklist() as curr_list: async with ctx.bot._config.blacklist() as curr_list:
if user.id in curr_list: if uid in curr_list:
removed = True removed = True
curr_list.remove(user.id) curr_list.remove(uid)
if removed: if removed:
await ctx.send(_("User has been removed from blacklist.")) await ctx.send(_("User has been removed from blacklist."))
@ -1809,12 +1812,16 @@ class Core(commands.Cog, CoreLogic):
@localwhitelist.command(name="add") @localwhitelist.command(name="add")
async def localwhitelist_add( async def localwhitelist_add(
self, ctx: commands.Context, *, user_or_role: Union[discord.Member, discord.Role] self, ctx: commands.Context, *, user_or_role: Union[discord.Member, discord.Role, int]
): ):
""" """
Adds a user or role to the whitelist. Adds a user or role to the whitelist.
""" """
user = isinstance(user_or_role, discord.Member) user = isinstance(user_or_role, discord.Member)
if isinstance(user_or_role, int):
user_or_role = discord.Object(id=user_or_role)
user = True
async with ctx.bot._config.guild(ctx.guild).whitelist() as curr_list: async with ctx.bot._config.guild(ctx.guild).whitelist() as curr_list:
if user_or_role.id not in curr_list: if user_or_role.id not in curr_list:
curr_list.append(user_or_role.id) curr_list.append(user_or_role.id)
@ -1840,12 +1847,15 @@ class Core(commands.Cog, CoreLogic):
@localwhitelist.command(name="remove") @localwhitelist.command(name="remove")
async def localwhitelist_remove( async def localwhitelist_remove(
self, ctx: commands.Context, *, user_or_role: Union[discord.Member, discord.Role] self, ctx: commands.Context, *, user_or_role: Union[discord.Member, discord.Role, int]
): ):
""" """
Removes user or role from whitelist. Removes user or role from whitelist.
""" """
user = isinstance(user_or_role, discord.Member) user = isinstance(user_or_role, discord.Member)
if isinstance(user_or_role, int):
user_or_role = discord.Object(id=user_or_role)
user = True
removed = False removed = False
async with ctx.bot._config.guild(ctx.guild).whitelist() as curr_list: async with ctx.bot._config.guild(ctx.guild).whitelist() as curr_list:
@ -1883,12 +1893,15 @@ class Core(commands.Cog, CoreLogic):
@localblacklist.command(name="add") @localblacklist.command(name="add")
async def localblacklist_add( async def localblacklist_add(
self, ctx: commands.Context, *, user_or_role: Union[discord.Member, discord.Role] self, ctx: commands.Context, *, user_or_role: Union[discord.Member, discord.Role, int]
): ):
""" """
Adds a user or role to the blacklist. Adds a user or role to the blacklist.
""" """
user = isinstance(user_or_role, discord.Member) user = isinstance(user_or_role, discord.Member)
if isinstance(user_or_role, int):
user_or_role = discord.Object(id=user_or_role)
user = True
if user and await ctx.bot.is_owner(user_or_role): if user and await ctx.bot.is_owner(user_or_role):
await ctx.send(_("You cannot blacklist an owner!")) await ctx.send(_("You cannot blacklist an owner!"))
@ -1919,13 +1932,16 @@ class Core(commands.Cog, CoreLogic):
@localblacklist.command(name="remove") @localblacklist.command(name="remove")
async def localblacklist_remove( async def localblacklist_remove(
self, ctx: commands.Context, *, user_or_role: Union[discord.Member, discord.Role] self, ctx: commands.Context, *, user_or_role: Union[discord.Member, discord.Role, int]
): ):
""" """
Removes user or role from blacklist. Removes user or role from blacklist.
""" """
removed = False removed = False
user = isinstance(user_or_role, discord.Member) user = isinstance(user_or_role, discord.Member)
if isinstance(user_or_role, int):
user_or_role = discord.Object(id=user_or_role)
user = True
async with ctx.bot._config.guild(ctx.guild).blacklist() as curr_list: async with ctx.bot._config.guild(ctx.guild).blacklist() as curr_list:
if user_or_role.id in curr_list: if user_or_role.id in curr_list:

View File

@ -304,7 +304,7 @@ class Case:
) )
if isinstance(self.user, int): if isinstance(self.user, int):
user = f"Deleted User#0000 ({self.user})" user = f"[Unknown or Deleted User] ({self.user})"
avatar_url = None avatar_url = None
else: else:
user = escape_spoilers( user = escape_spoilers(
@ -448,12 +448,7 @@ class Case:
if user_id is None: if user_id is None:
user_object = None user_object = None
else: else:
user_object = bot.get_user(user_id) user_object = bot.get_user(user_id) or user_id
if user_object is None:
try:
user_object = await bot.fetch_user(user_id)
except discord.NotFound:
user_object = user_id
user_objects[user_key] = user_object user_objects[user_key] = user_object
channel = kwargs.get("channel") or guild.get_channel(data["channel"]) or data["channel"] channel = kwargs.get("channel") or guild.get_channel(data["channel"]) or data["channel"]
@ -687,12 +682,7 @@ async def get_cases_for_member(
member_id = member.id member_id = member.id
if not member: if not member:
member = bot.get_user(member_id) member = bot.get_user(member_id) or member_id
if not member:
try:
member = await bot.fetch_user(member_id)
except discord.NotFound:
member = member_id
try: try:
modlog_channel = await get_modlog_channel(guild) modlog_channel = await get_modlog_channel(guild)