Module aethersprite.extensions.base.wipe
Wipe channel extension
Expand source code
"""Wipe channel extension"""
# TODO track which channels are being actively wiped
# TODO resume wipes on startup; clear missing channels from db
# TODO remove wipe record on completion
# TODO command with channel param to cancel active wipe
# TODO command to list active wipes on server
# TODO channel retention policy setting -- automatically delete messages older \
# than x days old on a schedule
# typing
# 3rd party
from discord.ext.commands import Bot, check, command, Context
from discord.channel import TextChannel
from discord.message import Message
from discord.raw_models import RawReactionActionEvent
from sqlitedict import SqliteDict
# api
from aethersprite import bot, data_folder, log
from aethersprite.authz import channel_only, require_admin
from aethersprite.emotes import CHECK_MARK, PROHIBITED
# database
wipes = SqliteDict(
f"{data_folder}wipe.sqlite3",
tablename="wipes",
autocommit=True,
)
async def on_raw_reaction_add(payload: RawReactionActionEvent):
"""Handle on_reaction_add event."""
assert bot.user
assert payload.member
assert payload.member.guild
if (
payload.user_id == bot.user.id
or payload.guild_id not in wipes
or wipes[payload.guild_id] != payload.message_id
):
return
channel: TextChannel = payload.member.guild.get_channel(
payload.channel_id # type: ignore
)
msg: Message = await channel.fetch_message(payload.message_id)
perms = channel.permissions_for(payload.member)
if not perms.manage_messages:
await msg.remove_reaction(payload.emoji, payload.member)
return
if payload.emoji.name == PROHIBITED:
log.info(f"{payload.member} canceled wipe in {channel}")
await msg.delete()
del wipes[payload.guild_id]
return
if payload.emoji.name != CHECK_MARK:
await msg.remove_reaction(payload.emoji, payload.member)
return
log.info(f"{payload.member} began wipe in {channel}")
del wipes[payload.guild_id]
# stop after a million just to be safe?
for _ in range(1_000_000):
done = True
log.info(f"Deleting up to 100 messages in {channel}")
async for m in channel.history(limit=100):
done = False
await m.delete()
if done:
break
log.info(f"{payload.member} finished wiping {channel}")
@command()
@check(channel_only)
@check(require_admin)
async def wipe(ctx: Context):
"""Delete all messages in a channel."""
assert ctx.guild
log.info(f"{ctx.author} requested wipe in {ctx.channel}")
msg = await ctx.send("Are you sure?")
await msg.add_reaction(PROHIBITED)
await msg.add_reaction(CHECK_MARK)
wipes[ctx.guild.id] = msg.id
async def setup(bot: Bot):
bot.add_command(wipe)
bot.add_listener(on_raw_reaction_add)
Functions
async def on_raw_reaction_add(payload: discord.raw_models.RawReactionActionEvent)
-
Handle on_reaction_add event.
Expand source code
async def on_raw_reaction_add(payload: RawReactionActionEvent): """Handle on_reaction_add event.""" assert bot.user assert payload.member assert payload.member.guild if ( payload.user_id == bot.user.id or payload.guild_id not in wipes or wipes[payload.guild_id] != payload.message_id ): return channel: TextChannel = payload.member.guild.get_channel( payload.channel_id # type: ignore ) msg: Message = await channel.fetch_message(payload.message_id) perms = channel.permissions_for(payload.member) if not perms.manage_messages: await msg.remove_reaction(payload.emoji, payload.member) return if payload.emoji.name == PROHIBITED: log.info(f"{payload.member} canceled wipe in {channel}") await msg.delete() del wipes[payload.guild_id] return if payload.emoji.name != CHECK_MARK: await msg.remove_reaction(payload.emoji, payload.member) return log.info(f"{payload.member} began wipe in {channel}") del wipes[payload.guild_id] # stop after a million just to be safe? for _ in range(1_000_000): done = True log.info(f"Deleting up to 100 messages in {channel}") async for m in channel.history(limit=100): done = False await m.delete() if done: break log.info(f"{payload.member} finished wiping {channel}")
async def setup(bot: discord.ext.commands.bot.Bot)
-
Expand source code
async def setup(bot: Bot): bot.add_command(wipe) bot.add_listener(on_raw_reaction_add)