Create ModlogCase scale wrapper

This commit is contained in:
Zeva Rose 2022-03-23 01:24:53 -06:00
parent e80afc97ad
commit 2308342de7
7 changed files with 96 additions and 49 deletions

View file

@ -1,15 +1,15 @@
"""J.A.R.V.I.S. Admin Cogs."""
from dis_snek import Snake
from jarvis.cogs.admin import ban, kick, mute, purge, roleping, warning
from jarvis.cogs.admin import ban, kick, lock, lockdown, mute, purge, roleping, warning
def setup(bot: Snake) -> None:
"""Add admin cogs to J.A.R.V.I.S."""
ban.BanCog(bot)
kick.KickCog(bot)
# lock.LockCog(bot)
# lockdown.LockdownCog(bot)
lock.LockCog(bot)
lockdown.LockdownCog(bot)
mute.MuteCog(bot)
purge.PurgeCog(bot)
roleping.RolepingCog(bot)

View file

@ -1,7 +1,7 @@
"""J.A.R.V.I.S. BanCog."""
import re
from dis_snek import InteractionContext, Permissions, Scale
from dis_snek import InteractionContext, Permissions
from dis_snek.client.utils.misc_utils import find, find_all
from dis_snek.ext.paginators import Paginator
from dis_snek.models.discord.embed import EmbedField
@ -17,10 +17,11 @@ from jarvis_core.db import q
from jarvis_core.db.models import Ban, Unban
from jarvis.utils import build_embed
from jarvis.utils.cogs import ModcaseCog
from jarvis.utils.permissions import admin_or_permissions
class BanCog(Scale):
class BanCog(ModcaseCog):
"""J.A.R.V.I.S. BanCog."""
async def discord_apply_ban(
@ -105,6 +106,12 @@ class BanCog(Scale):
SlashCommandChoice(name="Soft", value="soft"),
],
)
@slash_option(
name="duration",
description="Temp ban duration in hours",
opt_type=OptionTypes.INTEGER,
required=False,
)
@check(admin_or_permissions(Permissions.BAN_MEMBERS))
async def _ban(
self,

View file

@ -1,5 +1,5 @@
"""J.A.R.V.I.S. KickCog."""
from dis_snek import InteractionContext, Permissions, Scale
from dis_snek import InteractionContext, Permissions
from dis_snek.models.discord.embed import EmbedField
from dis_snek.models.discord.user import User
from dis_snek.models.snek.application_commands import (
@ -11,10 +11,11 @@ from dis_snek.models.snek.command import check
from jarvis_core.db.models import Kick
from jarvis.utils import build_embed
from jarvis.utils.cogs import ModcaseCog
from jarvis.utils.permissions import admin_or_permissions
class KickCog(Scale):
class KickCog(ModcaseCog):
"""J.A.R.V.I.S. KickCog."""
@slash_command(name="kick", description="Kick a user")

View file

@ -1,7 +1,7 @@
"""J.A.R.V.I.S. MuteCog."""
from datetime import datetime
from dis_snek import InteractionContext, Permissions, Scale, Snake
from dis_snek import InteractionContext, Permissions
from dis_snek.models.discord.embed import EmbedField
from dis_snek.models.discord.user import Member
from dis_snek.models.snek.application_commands import (
@ -14,15 +14,13 @@ from dis_snek.models.snek.command import check
from jarvis_core.db.models import Mute
from jarvis.utils import build_embed
from jarvis.utils.cogs import ModcaseCog
from jarvis.utils.permissions import admin_or_permissions
class MuteCog(Scale):
class MuteCog(ModcaseCog):
"""J.A.R.V.I.S. MuteCog."""
def __init__(self, bot: Snake):
self.bot = bot
@slash_command(name="mute", description="Mute a user")
@slash_option(name="user", description="User to mute", opt_type=OptionTypes.USER, required=True)
@slash_option(

View file

@ -1,5 +1,5 @@
"""J.A.R.V.I.S. WarningCog."""
from dis_snek import InteractionContext, Permissions, Scale
from dis_snek import InteractionContext, Permissions
from dis_snek.client.utils.misc_utils import get_all
from dis_snek.ext.paginators import Paginator
from dis_snek.models.discord.embed import EmbedField
@ -14,11 +14,12 @@ from dis_snek.models.snek.command import check
from jarvis_core.db.models import Warning
from jarvis.utils import build_embed
from jarvis.utils.cogs import ModcaseCog
from jarvis.utils.embeds import warning_embed
from jarvis.utils.permissions import admin_or_permissions
class WarningCog(Scale):
class WarningCog(ModcaseCog):
"""J.A.R.V.I.S. WarningCog."""
@slash_command(name="warn", description="Warn a user")

View file

@ -1,35 +0,0 @@
"""Cog wrapper for command caching."""
from datetime import datetime, timedelta
from dis_snek import InteractionContext, Scale, Snake
from dis_snek.client.utils.misc_utils import find
from dis_snek.ext.tasks.task import Task
from dis_snek.ext.tasks.triggers import IntervalTrigger
class CacheCog(Scale):
"""Cog wrapper for command caching."""
def __init__(self, bot: Snake):
self.bot = bot
self.cache = {}
self._expire_interaction.start()
def check_cache(self, ctx: InteractionContext, **kwargs: dict) -> dict:
"""Check the cache."""
if not kwargs:
kwargs = {}
return find(
lambda x: x["command"] == ctx.subcommand_name # noqa: W503
and x["user"] == ctx.author.id # noqa: W503
and x["guild"] == ctx.guild.id # noqa: W503
and all(x[k] == v for k, v in kwargs.items()), # noqa: W503
self.cache.values(),
)
@Task.create(IntervalTrigger(minutes=1))
async def _expire_interaction(self) -> None:
keys = list(self.cache.keys())
for key in keys:
if self.cache[key]["timeout"] <= datetime.utcnow() + timedelta(minutes=1):
del self.cache[key]

75
jarvis/utils/cogs.py Normal file
View file

@ -0,0 +1,75 @@
"""Cog wrapper for command caching."""
from datetime import datetime, timedelta
from dis_snek import Context, Scale, Snake
from dis_snek.client.utils.misc_utils import find
from dis_snek.models.snek.tasks.task import Task
from dis_snek.models.snek.tasks.triggers import IntervalTrigger
from jarvis_core.db import q
from jarvis_core.db.models import Action, Ban, Kick, Modlog, Mute, Note, Warning
MODLOG_LOOKUP = {"Ban": Ban, "Kick": Kick, "Mute": Mute, "Warning": Warning}
class CacheCog(Scale):
"""Cog wrapper for command caching."""
def __init__(self, bot: Snake):
self.bot = bot
self.cache = {}
self._expire_interaction.start()
def check_cache(self, ctx: Context, **kwargs: dict) -> dict:
"""Check the cache."""
if not kwargs:
kwargs = {}
return find(
lambda x: x["command"] == ctx.subcommand_name # noqa: W503
and x["user"] == ctx.author.id # noqa: W503
and x["guild"] == ctx.guild.id # noqa: W503
and all(x[k] == v for k, v in kwargs.items()), # noqa: W503
self.cache.values(),
)
@Task.create(IntervalTrigger(minutes=1))
async def _expire_interaction(self) -> None:
keys = list(self.cache.keys())
for key in keys:
if self.cache[key]["timeout"] <= datetime.utcnow() + timedelta(minutes=1):
del self.cache[key]
class ModcaseCog(Scale):
"""Cog wrapper for moderation case logging."""
def __init__(self, bot: Snake):
self.bot = bot
self.add_scale_postrun(self.log)
async def log(self, ctx: Context, *args: list, **kwargs: dict) -> None:
"""
Log a moderation activity in a moderation case.
Args:
ctx: Command context
"""
name = self.__name__.replace("Cog", "")
if name not in ["Lock", "Lockdown", "Purge", "Roleping"]:
user = kwargs.pop("user", None)
if not user:
# Log warning about missing user
return
coll = MODLOG_LOOKUP.get(name, None)
if not coll:
# Log warning about unsupported action
return
action = await coll.find_one(q(user=user.id, guild=ctx.guild_id, active=True))
if not action:
# Log warning about missing action
return
action = Action(action_type=name.lower(), parent=action.id)
note = Note(admin=self.bot.user.id, content="Moderation case opened automatically")
await Modlog(user=user.id, admin=ctx.author.id, actions=[action], notes=[note]).commit()