From 7fecf73ff0116005aebbdf2d9f3238ba7b714727 Mon Sep 17 00:00:00 2001 From: misson20000 Date: Wed, 26 Dec 2018 01:45:00 -0800 Subject: [PATCH 1/3] add clearreacts commands --- cogs/mod.py | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/cogs/mod.py b/cogs/mod.py index e88dc8b..96c56cb 100644 --- a/cogs/mod.py +++ b/cogs/mod.py @@ -1,3 +1,4 @@ +import asyncio import discord from discord.ext import commands import config @@ -609,6 +610,85 @@ class Mod: else: await ctx.send(del_warn) + @commands.guild_only() + @commands.check(check_if_staff) + @commands.command() + async def clearreactsbyuser(self, ctx, user: discord.Member, *, channel: discord.TextChannel = None, limit: int = 50): + """Clears reacts from a given user in the given channel, staff only.""" + log_channel = self.bot.get_channel(config.log_channel) + if not channel: + channel = ctx.channel + count = 0 + async for msg in channel.history(limit = limit): + for react in msg.reactions: + if (await react.users().find(lambda u: u == user)) is not None: + count = count + 1 + async for u in react.users(): + await msg.remove_reaction(react, u) + msg = f"✏️ **Cleared reacts**: {ctx.author.mention} cleared {user.mention}'s "\ + f"reacts from the last {limit} messages in {channel.mention}." + await ctx.channel.send(f"Cleared {count} unique reactions") + await log_channel.send(msg) + + @commands.guild_only() + @commands.check(check_if_staff) + @commands.command() + async def clearallreacts(self, ctx, *, limit: int = 50, channel: discord.TextChannel = None): + """Clears all reacts in a given channel, staff only. Use with care.""" + log_channel = self.bot.get_channel(config.log_channel) + if not channel: + channel = ctx.channel + count = 0 + async for msg in channel.history(limit = limit): + if msg.reactions: + count = count + 1 + await msg.clear_reactions() + msg = f"✏️ **Cleared reacts**: {ctx.author.mention} cleared all "\ + f"reacts from the last {limit} messages in {channel.mention}." + await ctx.channel.send(f"Cleared reacts from {count} messages!") + await log_channel.send(msg) + + @commands.guild_only() + @commands.check(check_if_staff) + @commands.command() + async def clearreactsinteractive(self, ctx): + """Clears reacts interactively, staff only. Use with care.""" + log_channel = self.bot.get_channel(config.log_channel) + + msg_text = f"{ctx.author.mention}, react to the reactions you want to remove. React to this message when you're done." + msg = await ctx.channel.send(msg_text) + + tasks = [] + + def check(event): + # we only care about the user who is clearing reactions + if event.user_id != ctx.author.id: + return False + # this is how the user finishes + if event.message_id == msg.id: + return True + else: + # remove a reaction + async def impl(): + msg = await self.bot.get_guild(event.guild_id).get_channel(event.channel_id).get_message(event.message_id) + def check_emoji(r): + if event.emoji.is_custom_emoji(): + return event.emoji.id == r.emoji.id + else: + return event.emoji.name == r.emoji # gotta love consistent APIs + for reaction in filter(check_emoji, msg.reactions): + async for u in reaction.users(): + await reaction.message.remove_reaction(reaction, u) + tasks.append(asyncio.create_task(impl())) # schedule immediately + return False + + try: + await self.bot.wait_for("raw_reaction_add", timeout=120.0, check=check) + except asyncio.TimeoutError: + await msg.edit(content = msg_text + " Timed out.") + else: + await asyncio.gather(*tasks) + await msg.edit(content = msg_text + " Done!") def setup(bot): bot.add_cog(Mod(bot)) From 687a26105dc6bdf07b3e8ca597dd09df2fae08ab Mon Sep 17 00:00:00 2001 From: misson20000 Date: Wed, 26 Dec 2018 02:47:32 -0800 Subject: [PATCH 2/3] formatting fixes and fix for custom emojis --- cogs/mod.py | 52 ++++++++++++++++++++++++++++++++++------------------ 1 file changed, 34 insertions(+), 18 deletions(-) diff --git a/cogs/mod.py b/cogs/mod.py index 96c56cb..00de062 100644 --- a/cogs/mod.py +++ b/cogs/mod.py @@ -613,35 +613,40 @@ class Mod: @commands.guild_only() @commands.check(check_if_staff) @commands.command() - async def clearreactsbyuser(self, ctx, user: discord.Member, *, channel: discord.TextChannel = None, limit: int = 50): + async def clearreactsbyuser(self, ctx, user: discord.Member, *, + channel: discord.TextChannel = None, + limit: int = 50): """Clears reacts from a given user in the given channel, staff only.""" log_channel = self.bot.get_channel(config.log_channel) if not channel: channel = ctx.channel count = 0 - async for msg in channel.history(limit = limit): + async for msg in channel.history(limit=limit): for react in msg.reactions: - if (await react.users().find(lambda u: u == user)) is not None: - count = count + 1 + if await react.users().find(lambda u: u == user): + count+= 1 async for u in react.users(): await msg.remove_reaction(react, u) - msg = f"✏️ **Cleared reacts**: {ctx.author.mention} cleared {user.mention}'s "\ - f"reacts from the last {limit} messages in {channel.mention}." + msg = f"✏️ **Cleared reacts**: {ctx.author.mention} cleared "\ + f"{user.mention}'s reacts from the last {limit} messages "\ + f"in {channel.mention}." await ctx.channel.send(f"Cleared {count} unique reactions") await log_channel.send(msg) @commands.guild_only() @commands.check(check_if_staff) @commands.command() - async def clearallreacts(self, ctx, *, limit: int = 50, channel: discord.TextChannel = None): + async def clearallreacts(self, ctx, *, + limit: int = 50, + channel: discord.TextChannel = None): """Clears all reacts in a given channel, staff only. Use with care.""" log_channel = self.bot.get_channel(config.log_channel) if not channel: channel = ctx.channel count = 0 - async for msg in channel.history(limit = limit): + async for msg in channel.history(limit=limit): if msg.reactions: - count = count + 1 + count+= 1 await msg.clear_reactions() msg = f"✏️ **Cleared reacts**: {ctx.author.mention} cleared all "\ f"reacts from the last {limit} messages in {channel.mention}." @@ -655,7 +660,8 @@ class Mod: """Clears reacts interactively, staff only. Use with care.""" log_channel = self.bot.get_channel(config.log_channel) - msg_text = f"{ctx.author.mention}, react to the reactions you want to remove. React to this message when you're done." + msg_text = f"{ctx.author.mention}, react to the reactions you want "\ + f"to remove. React to this message when you're done." msg = await ctx.channel.send(msg_text) tasks = [] @@ -670,25 +676,35 @@ class Mod: else: # remove a reaction async def impl(): - msg = await self.bot.get_guild(event.guild_id).get_channel(event.channel_id).get_message(event.message_id) + msg = await self.bot \ + .get_guild(event.guild_id) \ + .get_channel(event.channel_id) \ + .get_message(event.message_id) def check_emoji(r): - if event.emoji.is_custom_emoji(): - return event.emoji.id == r.emoji.id + if event.emoji.is_custom_emoji() == r.custom_emoji: + if event.emoji.is_custom_emoji(): + return event.emoji.id == r.emoji.id + else: + # gotta love consistent APIs + return event.emoji.name == r.emoji else: - return event.emoji.name == r.emoji # gotta love consistent APIs + return False for reaction in filter(check_emoji, msg.reactions): async for u in reaction.users(): await reaction.message.remove_reaction(reaction, u) - tasks.append(asyncio.create_task(impl())) # schedule immediately + # schedule immediately + tasks.append(asyncio.create_task(impl())) return False try: - await self.bot.wait_for("raw_reaction_add", timeout=120.0, check=check) + await self.bot.wait_for("raw_reaction_add", + timeout=120.0, + check=check) except asyncio.TimeoutError: - await msg.edit(content = msg_text + " Timed out.") + await msg.edit(content = f"{msg_text} Timed out.") else: await asyncio.gather(*tasks) - await msg.edit(content = msg_text + " Done!") + await msg.edit(content = f"{msg_text} Done!") def setup(bot): bot.add_cog(Mod(bot)) From 6237ac9e8c14c7439da0506fc6aa79a11645b477 Mon Sep 17 00:00:00 2001 From: misson20000 Date: Wed, 26 Dec 2018 02:55:59 -0800 Subject: [PATCH 3/3] fix += formatting --- cogs/mod.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cogs/mod.py b/cogs/mod.py index 00de062..13374f7 100644 --- a/cogs/mod.py +++ b/cogs/mod.py @@ -624,7 +624,7 @@ class Mod: async for msg in channel.history(limit=limit): for react in msg.reactions: if await react.users().find(lambda u: u == user): - count+= 1 + count += 1 async for u in react.users(): await msg.remove_reaction(react, u) msg = f"✏️ **Cleared reacts**: {ctx.author.mention} cleared "\ @@ -646,7 +646,7 @@ class Mod: count = 0 async for msg in channel.history(limit=limit): if msg.reactions: - count+= 1 + count += 1 await msg.clear_reactions() msg = f"✏️ **Cleared reacts**: {ctx.author.mention} cleared all "\ f"reacts from the last {limit} messages in {channel.mention}."