Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The big intents checklist. #4574

Draft
wants to merge 12 commits into
base: V3/develop
Choose a base branch
from
2 changes: 1 addition & 1 deletion redbot/cogs/customcom/customcom.py
Original file line number Diff line number Diff line change
Expand Up @@ -562,7 +562,7 @@ async def cc_show(self, ctx, command_name: str):

if _aid == 0xDE1:
author = _("Deleted User")
elif member := ctx.guild.get_member(_aid):
elif member := await self.bot.get_or_fetch_member(ctx.guild, _aid):
author = f"{member} ({_aid})"
else:
author = f"{cmd['author']['name']} ({_aid})"
Expand Down
11 changes: 6 additions & 5 deletions redbot/cogs/economy/economy.py
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,7 @@ async def payday(self, ctx: commands.Context):
# Sets the current time as the latest payday
await self.config.user(author).next_payday.set(cur_time)

pos = await bank.get_leaderboard_position(author)
pos = await bank.get_leaderboard_position(self.bot, author)
await ctx.send(
_(
"{author.mention} Here, take some {currency}. "
Expand Down Expand Up @@ -451,7 +451,7 @@ async def payday(self, ctx: commands.Context):
next_payday = cur_time

await self.config.member(author).next_payday.set(next_payday)
pos = await bank.get_leaderboard_position(author)
pos = await bank.get_leaderboard_position(self.bot, author)
await ctx.send(
_(
"{author.mention} Here, take some {currency}. "
Expand Down Expand Up @@ -493,10 +493,10 @@ async def leaderboard(self, ctx: commands.Context, top: int = 10, show_global: b
base_embed = discord.Embed(title=_("Economy Leaderboard"))
if await bank.is_global() and show_global:
# show_global is only applicable if bank is global
bank_sorted = await bank.get_leaderboard(positions=top, guild=None)
bank_sorted = await bank.get_leaderboard(bot=self.bot, positions=top, guild=None)
base_embed.set_author(name=ctx.bot.user.name, icon_url=ctx.bot.user.avatar_url)
else:
bank_sorted = await bank.get_leaderboard(positions=top, guild=guild)
bank_sorted = await bank.get_leaderboard(bot=self.bot, positions=top, guild=guild)
if guild:
base_embed.set_author(name=guild.name, icon_url=guild.icon_url)

Expand All @@ -521,7 +521,8 @@ async def leaderboard(self, ctx: commands.Context, top: int = 10, show_global: b
temp_msg = header
for acc in bank_sorted:
try:
name = guild.get_member(acc[0]).display_name
user_obj = await self.bot.get_or_fetch_member(ctx.guild, acc[0])
name = user_obj.display_name
except AttributeError:
user_id = ""
if await ctx.bot.is_owner(ctx.author):
Expand Down
1 change: 1 addition & 0 deletions redbot/cogs/mod/kickban.py
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,7 @@ def remove_processed(ids):
to_query: List[int] = []

for user_id in user_ids:
# This get_member is okay here due to the query below
member = guild.get_member(user_id)
if member is not None:
members[user_id] = member
Expand Down
66 changes: 44 additions & 22 deletions redbot/cogs/mod/names.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,29 +183,41 @@ async def userinfo(self, ctx, *, user: discord.Member = None):
user_joined = _("Unknown")
user_created = user.created_at.strftime("%d %b %Y %H:%M")
voice_state = user.voice
member_number = (
sorted(guild.members, key=lambda m: m.joined_at or ctx.message.created_at).index(user)
+ 1
)

created_on = _("{}\n({} days ago)").format(user_created, since_created)
joined_on = _("{}\n({} days ago)").format(user_joined, since_joined)

if any(a.type is discord.ActivityType.streaming for a in user.activities):
statusemoji = "\N{LARGE PURPLE CIRCLE}"
elif user.status.name == "online":
statusemoji = "\N{LARGE GREEN CIRCLE}"
elif user.status.name == "offline":
statusemoji = "\N{MEDIUM WHITE CIRCLE}\N{VARIATION SELECTOR-16}"
elif user.status.name == "dnd":
statusemoji = "\N{LARGE RED CIRCLE}"
elif user.status.name == "idle":
statusemoji = "\N{LARGE ORANGE CIRCLE}"
activity = _("Chilling in {} status").format(user.status)
status_string = self.get_status_string(user)
# INTENTS
# Member intent
if self.bot.intents.members:
member_number = (
sorted(guild.members, key=lambda m: m.joined_at or ctx.message.created_at).index(
user
)
+ 1
)
else:
member_number = None

# Presences intent
presences_enabled = self.bot.intents.presences

if presences_enabled:
if any(a.type is discord.ActivityType.streaming for a in user.activities):
statusemoji = "\N{LARGE PURPLE CIRCLE}"
elif user.status.name == "online":
statusemoji = "\N{LARGE GREEN CIRCLE}"
elif user.status.name == "offline":
statusemoji = "\N{MEDIUM WHITE CIRCLE}\N{VARIATION SELECTOR-16}"
elif user.status.name == "dnd":
statusemoji = "\N{LARGE RED CIRCLE}"
elif user.status.name == "idle":
statusemoji = "\N{LARGE ORANGE CIRCLE}"

activity = _("Chilling in {} status").format(user.status)
status_string = self.get_status_string(user)

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.
Expand Down Expand Up @@ -240,7 +252,10 @@ async def userinfo(self, ctx, *, user: discord.Member = None):
else:
role_str = None

data = discord.Embed(description=status_string or activity, colour=user.colour)
data = discord.Embed(colour=user.colour)

if presences_enabled:
data.description = status_string or activity

data.add_field(name=_("Joined Discord on"), value=created_on)
data.add_field(name=_("Joined this server on"), value=joined_on)
Expand All @@ -267,17 +282,24 @@ async def userinfo(self, ctx, *, user: discord.Member = None):
if voice_state and voice_state.channel:
data.add_field(
name=_("Current voice channel"),
value="{0.mention} ID: {0.id}".format(voice_state.channel),
value="{0.mention}\nID: {0.id}".format(voice_state.channel),
inline=False,
)
data.set_footer(text=_("Member #{} | User ID: {}").format(member_number, user.id))
if member_number:
data.set_footer(text=_("Member #{} | User ID: {}").format(member_number, user.id))
else:
data.set_footer(text=_("User ID: {}").format(user.id))

name = str(user)
name = " ~ ".join((name, user.nick)) if user.nick else name
name = filter_invites(name)

avatar = user.avatar_url_as(static_format="png")
data.set_author(name=f"{statusemoji} {name}", url=avatar)

if presences_enabled:
data.set_author(name=f"{statusemoji} {name}", url=avatar)
else:
data.set_author(name=f"{name}", url=avatar)

data.set_thumbnail(url=avatar)

await ctx.send(embed=data)
Expand Down
18 changes: 9 additions & 9 deletions redbot/cogs/mutes/mutes.py
Original file line number Diff line number Diff line change
Expand Up @@ -230,8 +230,8 @@ async def _auto_unmute_user(self, guild: discord.Guild, data: dict):
delay = 0
await asyncio.sleep(delay)

member = guild.get_member(data["member"])
author = guild.get_member(data["author"])
member = await self.bot.get_or_fetch_member(guild, data["member"])
author = await self.bot.get_or_fetch_member(guild, data["author"])
if not member:
async with self.config.guild(guild).muted_users() as muted_users:
if str(data["member"]) in muted_users:
Expand Down Expand Up @@ -308,7 +308,7 @@ async def _handle_channel_unmutes(self):
if task_name in self._unmute_tasks:
continue
log.debug(f"Creating task: {task_name}")
member = guild.get_member(user)
member = await self.bot.get_or_fetch_member(guild ,user)
self._unmute_tasks[task_name] = asyncio.create_task(
self._auto_channel_unmute_user_multi(member, guild, channels)
)
Expand All @@ -333,7 +333,7 @@ async def _auto_channel_unmute_user_multi(
self._channel_mute_events[guild.id] = asyncio.Event()
tasks = []
for channel, mute_data in channels.items():
author = guild.get_member(mute_data["author"])
author = self.bot.get_or_fetch_member(guild, mute_data["author"])
tasks.append(
self._auto_channel_unmute_user(guild.get_channel(channel), mute_data, False)
)
Expand Down Expand Up @@ -399,8 +399,8 @@ async def _auto_channel_unmute_user(
if delay < 1:
delay = 0
await asyncio.sleep(delay)
member = channel.guild.get_member(data["member"])
author = channel.guild.get_member(data["author"])
member = await self.bot.get_or_fetch_member(channel.guild, data["member"])
author = await self.bot.get_or_fetch_member(channel.guild, data["author"])
if not member:
async with self.config.channel(channel).muted_users() as muted_users:
if str(data["member"]) in muted_users:
Expand Down Expand Up @@ -551,7 +551,7 @@ async def on_guild_channel_update(
if user_id in before_perms and (
user_id not in after_perms or any((send_messages, speak))
):
user = after.guild.get_member(user_id)
user = await self.bot.get_or_fetch_member(after.guild, user_id)
if not user:
user = discord.Object(id=user_id)
log.debug(f"{user} - {type(user)}")
Expand Down Expand Up @@ -882,7 +882,7 @@ async def activemutes(self, ctx: commands.Context):
for user_id, mutes in mutes_data.items():
if not mutes:
continue
user = ctx.guild.get_member(user_id)
user = await self.bot.get_or_fetch_member(ctx.guild, user_id)
if not user:
user_str = f"<@!{user_id}>"
else:
Expand All @@ -907,7 +907,7 @@ async def activemutes(self, ctx: commands.Context):
for user_id, mutes in mutes_data.items():
if not mutes:
continue
user = ctx.guild.get_member(user_id)
user = await self.bot.get_or_fetch_member(ctx.guild, user_id)
if not user:
user_str = f"<@!{user_id}>"
else:
Expand Down
2 changes: 1 addition & 1 deletion redbot/cogs/permissions/converters.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ async def convert(
if channel is not None:
return channel

member: discord.Member = guild.get_member(_id)
member: discord.Member = await ctx.bot.get_or_fetch_member(guild, _id)
if member is not None:
return member

Expand Down
6 changes: 3 additions & 3 deletions redbot/cogs/reports/reports.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ async def discover_guild(
perms = discord.Permissions(**permissions)

async for guild in AsyncIter(self.bot.guilds, steps=100):
x = guild.get_member(author.id)
x = await self.bot.get_or_fetch_member(guild, author.id)
if x is not None:
if await self.internal_filter(x, mod, perms):
shared_guilds.append(guild)
Expand Down Expand Up @@ -194,7 +194,7 @@ async def discover_guild(

async def send_report(self, msg: discord.Message, guild: discord.Guild):

author = guild.get_member(msg.author.id)
author = await self.bot.get_or_fetch_member(guild, msg.author.id)
report = msg.clean_content

channel_id = await self.config.guild(guild).output_channel()
Expand Down Expand Up @@ -404,7 +404,7 @@ async def response(self, ctx, ticket_number: int):
rec = await self.config.custom("REPORT", guild.id, ticket_number).report()

try:
user = guild.get_member(rec.get("user_id"))
user = self.bot.get_or_fetch_member(guild, rec.get("user_id"))
except KeyError:
return await ctx.send(_("That ticket doesn't seem to exist"))

Expand Down
5 changes: 3 additions & 2 deletions redbot/cogs/trivia/trivia.py
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,8 @@ async def trivia_leaderboard_server(
return
guild = ctx.guild
data = await self.config.all_members(guild)
data = {guild.get_member(u): d for u, d in data.items()}
# Possible optimisation here of using query, will re-evaluate later.
data = {await ctx.bot.get_or_fetch_member(guild, u): d for u, d in data.items()}
data.pop(None, None) # remove any members which aren't in the guild
await self.send_leaderboard(ctx, data, key, top)

Expand Down Expand Up @@ -440,7 +441,7 @@ async def trivia_leaderboard_global(
if guild is None:
continue
for member_id, member_data in guild_data.items():
member = guild.get_member(member_id)
member = await ctx.bot.get_or_fetch_member(guild, member_id)
if member is None:
continue
collated_member_data = collated_data.get(member, Counter())
Expand Down
4 changes: 2 additions & 2 deletions redbot/cogs/warnings/warnings.py
Original file line number Diff line number Diff line change
Expand Up @@ -525,7 +525,7 @@ async def warnings(self, ctx: commands.Context, user: Union[discord.Member, int]
userid: int = user.id
except AttributeError:
userid: int = user
user = ctx.guild.get_member(userid)
user = await self.bot.get_or_fetch_member(ctx.guild, userid)
user = user or namedtuple("Member", "id guild")(userid, ctx.guild)

msg = ""
Expand Down Expand Up @@ -609,7 +609,7 @@ async def unwarn(
member = user
except AttributeError:
user_id = user
member = guild.get_member(user_id)
member = await self.bot.get_or_fetch_member(guild, user_id)
member = member or namedtuple("Member", "guild id")(guild, user_id)

if user_id == ctx.author.id:
Expand Down
7 changes: 4 additions & 3 deletions redbot/core/bank.py
Original file line number Diff line number Diff line change
Expand Up @@ -520,7 +520,7 @@ async def bank_prune(bot: Red, guild: discord.Guild = None, user_id: int = None)
del bank_data[user_id]


async def get_leaderboard(positions: int = None, guild: discord.Guild = None) -> List[tuple]:
async def get_leaderboard(bot: Red, positions: int = None, guild: discord.Guild = None) -> List[tuple]:
"""
Gets the bank's leaderboard

Expand Down Expand Up @@ -548,7 +548,7 @@ async def get_leaderboard(positions: int = None, guild: discord.Guild = None) ->
if guild is not None:
tmp = raw_accounts.copy()
for acc in tmp:
if not guild.get_member(acc):
if not await bot.get_or_fetch_member(guild, acc):
del raw_accounts[acc]
else:
if guild is None:
Expand All @@ -562,6 +562,7 @@ async def get_leaderboard(positions: int = None, guild: discord.Guild = None) ->


async def get_leaderboard_position(
bot: Red,
member: Union[discord.User, discord.Member]
) -> Union[int, None]:
"""
Expand All @@ -588,7 +589,7 @@ async def get_leaderboard_position(
else:
guild = member.guild if hasattr(member, "guild") else None
try:
leaderboard = await get_leaderboard(None, guild)
leaderboard = await get_leaderboard(bot, None, guild)
except TypeError:
raise
else:
Expand Down
14 changes: 14 additions & 0 deletions redbot/core/bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,20 @@ async def _red_before_invoke_method(self, ctx):
return_exceptions=return_exceptions,
)

def has_intents(self, **intents: bool) -> bool:
"""Check if the bot has the specified intents."""

invalid_keys = set(intents.keys()) - set(discord.Intents.VALID_FLAGS)
if invalid_keys:
raise TypeError(f"Invalid intent name(s): {', '.join(invalid_keys)}")
for perm, value in intents.items():
if value is not True:
# We reject any Intent not specified as 'True', since this is the only value which
# makes practical sense.
raise TypeError(f"Intent {perm} may only be specified as 'True', not {value}")
missing = set(intents) - set(self.intents)
return not missing

async def cog_disabled_in_guild(
self, cog: commands.Cog, guild: Optional[discord.Guild]
) -> bool:
Expand Down