jarvis-bot/jarvis/cogs/settings.py

278 lines
9.5 KiB
Python

"""J.A.R.V.I.S. Settings Management Cog."""
from typing import Any
from discord import Role
from discord import TextChannel
from discord.ext import commands
from discord.utils import find
from discord_slash import cog_ext
from discord_slash import SlashContext
from discord_slash.utils.manage_commands import create_option
from jarvis.db.models import Setting
from jarvis.utils import build_embed
from jarvis.utils.field import Field
from jarvis.utils.permissions import admin_or_permissions
class SettingsCog(commands.Cog):
"""J.A.R.V.I.S. Settings Management Cog."""
def __init__(self, bot: commands.Bot):
self.bot = bot
def update_settings(self, setting: str, value: Any, guild: int) -> bool:
"""Update a guild setting."""
existing = Setting.objects(setting=setting, guild=guild).first()
if not existing:
existing = Setting(setting=setting, guild=guild, value=value)
existing.value = value
updated = existing.save()
return updated is not None
def delete_settings(self, setting: str, guild: int) -> bool:
"""Delete a guild setting."""
return Setting.objects(setting=setting, guild=guild).delete()
@cog_ext.cog_subcommand(
base="settings",
base_desc="Settings management",
subcommand_group="set",
subcommand_group_description="Set a setting",
name="mute",
description="Set mute role",
options=[
create_option(
name="role",
description="Mute role",
option_type=8,
required=True,
)
],
)
@admin_or_permissions(manage_guild=True)
async def _set_mute(self, ctx: SlashContext, role: Role) -> None:
await ctx.defer()
self.update_settings("mute", role.id, ctx.guild.id)
await ctx.send(f"Settings applied. New mute role is `{role.name}`")
@cog_ext.cog_subcommand(
base="settings",
subcommand_group="set",
name="modlog",
description="Set modlog channel",
options=[
create_option(
name="channel",
description="Modlog channel",
option_type=7,
required=True,
)
],
)
@admin_or_permissions(manage_guild=True)
async def _set_modlog(self, ctx: SlashContext, channel: TextChannel) -> None:
if not isinstance(channel, TextChannel):
await ctx.send("Channel must be a TextChannel", hidden=True)
return
self.update_settings("modlog", channel.id, ctx.guild.id)
await ctx.send(f"Settings applied. New modlog channel is {channel.mention}")
@cog_ext.cog_subcommand(
base="settings",
subcommand_group="set",
name="userlog",
description="Set userlog channel",
options=[
create_option(
name="channel",
description="Userlog channel",
option_type=7,
required=True,
)
],
)
@admin_or_permissions(manage_guild=True)
async def _set_userlog(self, ctx: SlashContext, channel: TextChannel) -> None:
if not isinstance(channel, TextChannel):
await ctx.send("Channel must be a TextChannel", hidden=True)
return
self.update_settings("userlog", channel.id, ctx.guild.id)
await ctx.send(f"Settings applied. New userlog channel is {channel.mention}")
@cog_ext.cog_subcommand(
base="settings",
subcommand_group="set",
name="massmention",
description="Set massmention amount",
options=[
create_option(
name="amount",
description="Amount of mentions (0 to disable)",
option_type=4,
required=True,
)
],
)
@admin_or_permissions(manage_guild=True)
async def _set_massmention(self, ctx: SlashContext, amount: int) -> None:
await ctx.defer()
self.update_settings("massmention", amount, ctx.guild.id)
await ctx.send(f"Settings applied. New massmention limit is {amount}")
@cog_ext.cog_subcommand(
base="settings",
subcommand_group="set",
name="verified",
description="Set verified role",
options=[
create_option(
name="role",
description="verified role",
option_type=8,
required=True,
)
],
)
@admin_or_permissions(manage_guild=True)
async def _set_verified(self, ctx: SlashContext, role: Role) -> None:
await ctx.defer()
self.update_settings("verified", role.id, ctx.guild.id)
await ctx.send(f"Settings applied. New verified role is `{role.name}`")
@cog_ext.cog_subcommand(
base="settings",
subcommand_group="set",
name="unverified",
description="Set unverified role",
options=[
create_option(
name="role",
description="Unverified role role",
option_type=8,
required=True,
)
],
)
@admin_or_permissions(manage_guild=True)
async def _set_unverified(self, ctx: SlashContext, role: Role) -> None:
await ctx.defer()
self.update_settings("unverified", role.id, ctx.guild.id)
await ctx.send(f"Settings applied. New unverified role is `{role.name}`")
@cog_ext.cog_subcommand(
base="settings",
subcommand_group="unset",
subcommand_group_description="Unset a setting",
name="mute",
description="Unset mute role",
)
@admin_or_permissions(manage_guild=True)
async def _unset_mute(self, ctx: SlashContext) -> None:
await ctx.defer()
self.delete_settings("mute", ctx.guild.id)
await ctx.send("Setting removed.")
@cog_ext.cog_subcommand(
base="settings",
subcommand_group="unset",
name="modlog",
description="Unset modlog channel",
)
@admin_or_permissions(manage_guild=True)
async def _unset_modlog(self, ctx: SlashContext) -> None:
self.delete_settings("modlog", ctx.guild.id)
await ctx.send("Setting removed.")
@cog_ext.cog_subcommand(
base="settings",
subcommand_group="unset",
name="userlog",
description="Unset userlog channel",
)
@admin_or_permissions(manage_guild=True)
async def _unset_userlog(self, ctx: SlashContext) -> None:
self.delete_settings("userlog", ctx.guild.id)
await ctx.send("Setting removed.")
@cog_ext.cog_subcommand(
base="settings",
subcommand_group="unset",
name="massmention",
description="Unet massmention amount",
)
@admin_or_permissions(manage_guild=True)
async def _massmention(self, ctx: SlashContext) -> None:
await ctx.defer()
self.delete_settings("massmention", ctx.guild.id)
await ctx.send("Setting removed.")
@cog_ext.cog_subcommand(
base="settings",
subcommand_group="unset",
name="verified",
description="Unset verified role",
)
@admin_or_permissions(manage_guild=True)
async def _verified(self, ctx: SlashContext) -> None:
await ctx.defer()
self.delete_settings("verified", ctx.guild.id)
await ctx.send("Setting removed.")
@cog_ext.cog_subcommand(
base="settings",
subcommand_group="unset",
name="unverified",
description="Unset unverified role",
)
@admin_or_permissions(manage_guild=True)
async def _unverified(self, ctx: SlashContext) -> None:
await ctx.defer()
self.delete_settings("unverified", ctx.guild.id)
await ctx.send("Setting removed.")
@cog_ext.cog_subcommand(base="settings", name="view", description="View settings")
@admin_or_permissions(manage_guild=True)
async def _view(self, ctx: SlashContext) -> None:
settings = Setting.objects(guild=ctx.guild.id)
fields = []
for setting in settings:
value = setting.value
if setting.setting in ["unverified", "verified", "mute"]:
value = find(lambda x: x.id == value, ctx.guild.roles)
if value:
value = value.mention
else:
value = "||`[redacted]`||"
elif setting.setting in ["userlog", "modlog"]:
value = find(lambda x: x.id == value, ctx.guild.text_channels)
if value:
value = value.mention
else:
value = "||`[redacted]`||"
elif setting.setting == "rolegiver":
value = ""
for role in setting.value:
nvalue = find(lambda x: x.id == value, ctx.guild.roles)
if value:
value += "\n" + nvalue.mention
else:
value += "\n||`[redacted]`||"
fields.append(Field(name=setting.setting, value=value or "N/A"))
embed = build_embed(title="Current Settings", description="", fields=fields)
await ctx.send(embed=embed)
@cog_ext.cog_subcommand(base="settings", name="clear", description="Clear all settings")
@admin_or_permissions(manage_guild=True)
async def _clear(self, ctx: SlashContext) -> None:
deleted = Setting.objects(guild=ctx.guild.id).delete()
await ctx.send(f"Guild settings cleared: `{deleted is not None}`")
def setup(bot: commands.Bot) -> None:
"""Add SettingsCog to J.A.R.V.I.S."""
bot.add_cog(SettingsCog(bot))