Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions bot/exts/info/pep.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

from bot.bot import Bot
from bot.log import get_logger
from bot.utils.messages import send_or_reply

log = get_logger(__name__)

Expand Down Expand Up @@ -93,8 +94,7 @@ async def pep_command(self, ctx: Context, pep_number: int) -> None:
colour=Colour.red(),
)

await ctx.send(embed=embed)

await send_or_reply(ctx, embed)

async def setup(bot: Bot) -> None:
"""Load the PEP cog."""
Expand Down
3 changes: 2 additions & 1 deletion bot/exts/info/resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from discord.ext import commands

from bot.bot import Bot
from bot.utils.messages import send_or_reply

REGEX_CONSECUTIVE_NON_LETTERS = r"[^A-Za-z0-9]+"
RESOURCE_URL = "https://www.pythondiscord.com/resources/"
Expand Down Expand Up @@ -61,7 +62,7 @@ async def resources_command(self, ctx: commands.Context, *, resource_topic: str
f"of hand-selected learning resources that we "
f"regularly recommend to both beginners and experts."
)
await ctx.send(embed=embed)
await send_or_reply(ctx, embed)


async def setup(bot: Bot) -> None:
Expand Down
7 changes: 5 additions & 2 deletions bot/exts/info/source.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from bot.bot import Bot
from bot.constants import URLs
from bot.exts.info.tags import TagIdentifier
from bot.utils.messages import send_or_reply

SourceObject = commands.HelpCommand | commands.Command | commands.Cog | TagIdentifier | commands.ExtensionNotLoaded

Expand Down Expand Up @@ -40,12 +41,14 @@ async def source_command(
embed = Embed(title="Bot's GitHub Repository")
embed.add_field(name="Repository", value=f"[Go to GitHub]({URLs.github_bot_repo})")
embed.set_thumbnail(url="https://avatars1.githubusercontent.com/u/9919")
await ctx.send(embed=embed)

await send_or_reply(ctx, embed)
return

obj, source_type = await self.get_source_object(ctx, source_item)
embed = await self.build_embed(obj, source_type)
await ctx.send(embed=embed)

await send_or_reply(ctx, embed)

@staticmethod
async def get_source_object(ctx: commands.Context, argument: str) -> tuple[SourceObject, SourceType]:
Expand Down
4 changes: 2 additions & 2 deletions bot/exts/info/tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from bot.bot import Bot
from bot.log import get_logger
from bot.pagination import LinePaginator
from bot.utils.messages import wait_for_deletion
from bot.utils.messages import send_or_reply, wait_for_deletion

log = get_logger(__name__)

Expand Down Expand Up @@ -305,7 +305,7 @@ async def get_command_ctx(
if embed is not COOLDOWN.obj:

await wait_for_deletion(
await ctx.send(embed=embed),
await send_or_reply(ctx, embed),
(ctx.author.id,)
)
# A valid tag was found and was either sent, or is on cooldown
Expand Down
34 changes: 33 additions & 1 deletion bot/utils/messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from itertools import zip_longest

import discord
from discord import Message
from discord import DeletedReferencedMessage, Embed, Message
from discord.ext.commands import Context
from pydis_core.site_api import ResponseCodeError
from pydis_core.utils import scheduling
Expand Down Expand Up @@ -285,3 +285,35 @@ async def upload_log(
raise

return f"{URLs.site_logs_view}/{response['id']}"

async def get_reference_message(ctx: Context) -> Message | None:
"""Return a message reference if the reference exists and it does not refer to the author of the message."""
if (ctx.message.reference is None
or ctx.message.reference.message_id is None):
return None
try:
referenced_message = (
ctx.message.reference.resolved
or ctx.message.reference.cached_message
or await ctx.fetch_message(ctx.message.reference.message_id)
)
except (discord.Forbidden, discord.NotFound):
return None
else:
if referenced_message is None or isinstance(referenced_message, DeletedReferencedMessage):

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes this looks gud now, just one minor nit: referenced_message can never be None here as if resolved or cached_message is None, we will fetch using the API, which will raise NotFound etc. if the message can't be fetched.

return None
if referenced_message.author == ctx.author:
return None
return referenced_message
Comment on lines +289 to +307

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry if wasn't very clear,
it should look something like this

Suggested change
async def get_reference_message(ctx: Context) -> Message | None:
"""Return a message reference if the reference exists and it does not refer to the author of the message."""
if ctx.message.reference is None:
return None
try:
referenced_message = ctx.message.reference.resolved
except (discord.Forbidden, discord.NotFound):
return None
else:
if referenced_message is None or isinstance(referenced_message, DeletedReferencedMessage):
return None
if referenced_message.author == ctx.author:
return None
return referenced_message
async def get_reference_message(ctx: Context) -> Message | None:
"""Return a message reference if the reference exists and it does not refer to the author of the message."""
if ctx.message.reference is None:
return None
try:
referenced_message = .resolved or .cached_message or await fetch_message(...)
except (discord.Forbidden, discord.NotFound):
return None
else:
if isinstance(referenced_message, DeletedReferencedMessage):
return None
if referenced_message.author == ctx.author:
return None
return referenced_message

NotFound and Forbidden won't ever be raised unless an API call is made.
Basically the idea is to check the data in resolved, if empty, check cached_message, if also empty finally make an api call.


async def send_or_reply(ctx: Context, embed: Embed) -> Message:
"""
Sends the bot message as a reply if the callers message has a reference.

If the callers message does not have a reference or the reference is deleted,
the bot messsage is sent without replying.
"""
if message_reference := await get_reference_message(ctx):
reference = message_reference.to_reference(fail_if_not_exists=False)
return await ctx.send(embed=embed, reference=reference)
return await ctx.send(embed=embed)