(moderation): tickets command and note ticket.
Add new `tickets` command for viewing moderation tickets. Add `Note` ticket implementation, with command. Add `offer_delete` context utility. Add `guild_moderator` command ward.
This commit is contained in:
@@ -1,8 +1,10 @@
|
||||
import asyncio
|
||||
import discord
|
||||
from cmdClient import Context
|
||||
|
||||
from data import tables
|
||||
from core import Lion
|
||||
from . import lib
|
||||
from settings import GuildSettings, UserSettings
|
||||
|
||||
|
||||
@@ -43,6 +45,85 @@ async def error_reply(ctx, error_str, **kwargs):
|
||||
return message
|
||||
|
||||
|
||||
@Context.util
|
||||
async def offer_delete(ctx: Context, *to_delete, timeout=300):
|
||||
"""
|
||||
Offers to delete the provided messages via a reaction on the last message.
|
||||
Removes the reaction if the offer times out.
|
||||
|
||||
If any exceptions occur, handles them silently and returns.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
to_delete: List[Message]
|
||||
The messages to delete.
|
||||
|
||||
timeout: int
|
||||
Time in seconds after which to remove the delete offer reaction.
|
||||
"""
|
||||
# Get the delete emoji from the config
|
||||
emoji = lib.cross
|
||||
|
||||
# Return if there are no messages to delete
|
||||
if not to_delete:
|
||||
return
|
||||
|
||||
# The message to add the reaction to
|
||||
react_msg = to_delete[-1]
|
||||
|
||||
# Build the reaction check function
|
||||
if ctx.guild:
|
||||
modrole = ctx.guild_settings.mod_role.value if ctx.guild else None
|
||||
|
||||
def check(reaction, user):
|
||||
if not (reaction.message.id == react_msg.id and reaction.emoji == emoji):
|
||||
return False
|
||||
if user == ctx.guild.me:
|
||||
return False
|
||||
return ((user == ctx.author)
|
||||
or (user.permissions_in(ctx.ch).manage_messages)
|
||||
or (modrole and modrole in user.roles))
|
||||
else:
|
||||
def check(reaction, user):
|
||||
return user == ctx.author and reaction.message.id == react_msg.id and reaction.emoji == emoji
|
||||
|
||||
try:
|
||||
# Add the reaction to the message
|
||||
await react_msg.add_reaction(emoji)
|
||||
|
||||
# Wait for the user to press the reaction
|
||||
reaction, user = await ctx.client.wait_for("reaction_add", check=check, timeout=timeout)
|
||||
|
||||
# Since the check was satisfied, the reaction is correct. Delete the messages, ignoring any exceptions
|
||||
deleted = False
|
||||
# First try to bulk delete if we have the permissions
|
||||
if ctx.guild and ctx.ch.permissions_for(ctx.guild.me).manage_messages:
|
||||
try:
|
||||
await ctx.ch.delete_messages(to_delete)
|
||||
deleted = True
|
||||
except Exception:
|
||||
deleted = False
|
||||
|
||||
# If we couldn't bulk delete, delete them one by one
|
||||
if not deleted:
|
||||
try:
|
||||
asyncio.gather(*[message.delete() for message in to_delete], return_exceptions=True)
|
||||
except Exception:
|
||||
pass
|
||||
except (asyncio.TimeoutError, asyncio.CancelledError):
|
||||
# Timed out waiting for the reaction, attempt to remove the delete reaction
|
||||
try:
|
||||
await react_msg.remove_reaction(emoji, ctx.client.user)
|
||||
except Exception:
|
||||
pass
|
||||
except discord.Forbidden:
|
||||
pass
|
||||
except discord.NotFound:
|
||||
pass
|
||||
except discord.HTTPException:
|
||||
pass
|
||||
|
||||
|
||||
def context_property(func):
|
||||
setattr(Context, func.__name__, property(func))
|
||||
return func
|
||||
|
||||
Reference in New Issue
Block a user