ryuko-ng/cogs/mod_reacts.py

123 lines
4.3 KiB
Python
Raw Normal View History

import asyncio
import discord
from discord.ext import commands
from discord.ext.commands import Cog
import config
from helpers.checks import check_if_staff
class ModReact(Cog):
def __init__(self, bot):
self.bot = bot
@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."""
2019-02-04 22:54:40 +00:00
log_channel = self.bot.get_channel(config.modlog_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):
count += 1
async for u in react.users():
await msg.remove_reaction(react, u)
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
):
"""Clears all reacts in a given channel, staff only. Use with care."""
2019-02-04 22:54:40 +00:00
log_channel = self.bot.get_channel(config.modlog_channel)
if not channel:
channel = ctx.channel
count = 0
async for msg in channel.history(limit=limit):
if msg.reactions:
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."""
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 = []
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() == 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 False
for reaction in filter(check_emoji, msg.reactions):
async for u in reaction.users():
await reaction.message.remove_reaction(reaction, u)
# schedule immediately
tasks.append(asyncio.create_task(impl()))
return False
try:
await self.bot.wait_for("raw_reaction_add", timeout=120.0, check=check)
except asyncio.TimeoutError:
await msg.edit(content=f"{msg_text} Timed out.")
else:
await asyncio.gather(*tasks)
await msg.edit(content=f"{msg_text} Done!")
def setup(bot):
bot.add_cog(ModReact(bot))