From 39b0dc9a96648339089640d914f847330f66b01f Mon Sep 17 00:00:00 2001 From: Xevion Date: Wed, 17 Feb 2021 22:55:31 -0600 Subject: [PATCH] Enforce Period.states for on_raw_reaction_add New submissions are also properly enforced via Period.states, in-case one makes it passed message permissions. Added helper reject method --- bot/bot.py | 9 +++++++++ bot/cogs/contest.py | 36 ++++++++++++++++++------------------ 2 files changed, 27 insertions(+), 18 deletions(-) diff --git a/bot/bot.py b/bot/bot.py index 7262d05..1824c52 100644 --- a/bot/bot.py +++ b/bot/bot.py @@ -114,3 +114,12 @@ class ContestBot(commands.Bot): async def fetch_message(self, channel_id: int, message_id: int) -> discord.Message: channel: discord.TextChannel = self.get_channel(channel_id) return await channel.fetch_message(message_id) + + @staticmethod + async def reject(message: discord.Message, warning: str, delete_delay: int = 1, warning_duration: int = 5) -> None: + """Send a warning message and delete the message, then the warning""" + if delete_delay < 0: + await message.delete(delay=delete_delay) + warning = await message.channel.send(warning) + if warning_duration < 0: + await warning.delete(delay=warning_duration) diff --git a/bot/cogs/contest.py b/bot/cogs/contest.py index 6f4464a..c2a0946 100644 --- a/bot/cogs/contest.py +++ b/bot/cogs/contest.py @@ -184,30 +184,25 @@ class ContestCog(commands.Cog): # Ensure that the submission contains at least one attachment if len(attachments) == 0: - await message.delete(delay=1) - warning = await channel.send( - f':no_entry_sign: {message.author.mention} Each submission must contain exactly one image.') - await warning.delete(delay=5) + await self.bot.reject(message, f':no_entry_sign: {message.author.mention} Each submission must contain exactly one image.') # Ensure the image contains no more than one attachment elif len(attachments) > 1: - await message.delete(delay=1) - warning = await channel.send( - f':no_entry_sign: {message.author.mention} Each submission must contain exactly one image.') - await warning.delete(delay=5) + await self.bot.reject(message, f':no_entry_sign: {message.author.mention} Each submission must contain exactly one image.') + elif guild.current_period is None: + await self.bot.reject(message, f':no_entry_sign: {message.author.mention} A period has not been started. ' + f'Submissions should not be allowed at this moment.') + elif guild.current_period != PeriodStates.SUBMISSIONS: + logger.warning(f'Valid submission was sent outside of Submissions in {channel.id}/{message.id}. Permissions error? Removing.') + await message.delete() else: attachment = attachments[0] # TODO: Add helper for displaying error/warning messages if attachment.is_spoiler(): - await message.delete(delay=1) - warning = await channel.send(':no_entry_sign: Attachment must not make use of a spoiler.') - await warning.delete(delay=5) + await self.bot.reject(message, ':no_entry_sign: Attachment must not make use of a spoiler.') elif attachment.width is None: - await message.delete(delay=1) - warning = await channel.send(':no_entry_sign: Attachment must be a image or video.') - await warning.delete(delay=5) + await self.bot.reject(message, ':no_entry_sign: Attachment must be a image or video.') else: - last_submission: Submission = session.query(Submission).filter_by(period=guild.current_period, - user=message.author.id).first() + last_submission: Submission = session.query(Submission).filter_by(period=guild.current_period, user=message.author.id).first() if last_submission is not None: # delete last submission submission_msg = await channel.fetch_message(last_submission.id) @@ -279,13 +274,18 @@ class ContestCog(commands.Cog): if submission is None: logger.warning(f'Upvote reaction added to message {payload.message_id}, but no Submission found in database.') else: - await submission.update(self.bot, message=await message.fetch()) + period: Period = submission.period + if period.active and period.state == PeriodStates.VOTING: + await submission.update(self.bot, message=await message.fetch()) + else: + logger.warning(f'User attempted to add a reaction to a Submission outside ' + f'of it\'s Period activity ({period.active}/{period.state}).') + await message.remove_reaction(payload.emoji, payload.member) else: # Remove the emoji since it's not supposed to be there anyways. # If permissions were setup correctly, only moderators or admins should be able to trigger this. await message.remove_reaction(payload.emoji, payload.member) - @commands.Cog.listener() async def on_raw_reaction_remove(self, payload: discord.RawReactionActionEvent) -> None: """Deal with reactions we remove or removed manually by users."""