first commit

This commit is contained in:
RayExo
2026-07-12 15:16:07 +05:30
commit 2289301f26
915 changed files with 69400 additions and 0 deletions

View File

@@ -0,0 +1,803 @@
import discord
from utils.emoji import CROSS, DISABLE, ENABLE, TICK, TICK_ALT
from discord.ext import commands
import aiosqlite
from utils.Tools import *
from utils.cv2 import CV2, build_container
from discord.ui import LayoutView, TextDisplay, Separator, Container, ActionRow
from utils.config import *
class CV2(LayoutView):
def __init__(self, title, *sections):
super().__init__(timeout=None)
items = [TextDisplay(f"**{title}**")]
for s in sections:
if s:
items.append(Separator(visible=True))
items.append(TextDisplay(str(s)))
self.add_item(build_container(*items))
class ShowRules(LayoutView):
def __init__(self, author, selected_events, title, *sections):
super().__init__(timeout=60)
self.author = author
self.selected_events = selected_events
show_rules_btn = discord.ui.Button(label="Show Rules", style=discord.ButtonStyle.secondary)
show_rules_btn.callback = self._show_rules_callback
items = [TextDisplay(f"**{title}**")]
for s in sections:
if s:
items.append(Separator(visible=True))
items.append(TextDisplay(str(s)))
items.append(ActionRow(show_rules_btn))
self.add_item(build_container(*items))
async def _show_rules_callback(self, interaction: discord.Interaction):
if interaction.user != self.author:
await interaction.response.send_message("You are not allowed to interact with this button.", ephemeral=True)
return
rules = {
"Anti NSFW link": "__**Anti NSFW Link**__:\n• Takes action if the message contains a NSFW link.\n• Default punishment: Block message (unchangeable)",
"Anti caps": "__**Anti Caps**__:\n• Takes action if the message contains >70% caps.\n• Messages under 45 characters are bypassed\n• Default punishment: Mute (1 minutes)",
"Anti link": "__**Anti Link**__:\n• Takes action if the message contains a link.\n• Server invites, Spotify Music and GIF links are bypassed\n• Default punishment: Mute (7 minutes)",
"Anti invites": "__**Anti Invites**__:\n• Takes action if the message contains a Discord server invite.\n• Invites from the current server are bypassed\n• Default punishment: Mute (12 minutes)",
"Anti emoji spam": "__**Anti Emoji Spam**__:\n• Takes action if a message contains more than 5 emojis.\n• Default punishment: Mute (1 minute)",
"Anti mass mention": "__**Anti Mass Mention**__:\n• Takes action if a message contains more than 4 mentions.\n• Default punishment: Mute (3 minutes)",
"Anti spam": "__**Anti Spam**__:\n• Takes action if more than 5 messages are sent rapidly in a short time.\n• Default punishment: Mute (12 minutes)",
}
enabled_rules = "\n\n".join([rules[event] for event in self.selected_events if event in rules])
view = CV2("Enabled Automod Rules", enabled_rules, "Punishment type of each event is changeable except for Anti NSFW.")
await interaction.response.send_message(view=view, ephemeral=True)
class ConfirmDisable(LayoutView):
def __init__(self, author, title, *sections):
super().__init__(timeout=30)
self.author = author
self.value = None
yes_btn = discord.ui.Button(label="Yes", style=discord.ButtonStyle.danger)
yes_btn.callback = self._confirm_callback
no_btn = discord.ui.Button(label="No", style=discord.ButtonStyle.secondary)
no_btn.callback = self._cancel_callback
items = [TextDisplay(f"**{title}**")]
for s in sections:
if s:
items.append(Separator(visible=True))
items.append(TextDisplay(str(s)))
items.append(ActionRow(yes_btn, no_btn))
self.add_item(build_container(*items))
async def _confirm_callback(self, interaction: discord.Interaction):
if interaction.user != self.author:
await interaction.response.send_message("You are not allowed to interact with this button.", ephemeral=True)
return
await interaction.response.defer()
self.value = True
self.stop()
async def _cancel_callback(self, interaction: discord.Interaction):
if interaction.user != self.author:
await interaction.response.send_message("You are not allowed to interact with this button.", ephemeral=True)
return
await interaction.response.defer()
self.value = False
self.stop()
class Automod(commands.Cog):
def __init__(self, bot):
self.bot = bot
self.default_punishment = "Mute"
self.bot.loop.create_task(self.init_db())
async def get_exempt_roles_channels(self, guild_id):
async with aiosqlite.connect("db/automod.db") as db:
roles_cursor = await db.execute("SELECT id FROM automod_ignored WHERE guild_id = ? AND type = 'role'", (guild_id,))
channels_cursor = await db.execute("SELECT id FROM automod_ignored WHERE guild_id = ? AND type = 'channel'", (guild_id,))
exempt_roles = [discord.Object(id) for (id,) in await roles_cursor.fetchall()]
exempt_channels = [discord.Object(id) for (id,) in await channels_cursor.fetchall()]
return exempt_roles, exempt_channels
async def is_automod_enabled(self, guild_id):
async with aiosqlite.connect("db/automod.db") as db:
cursor = await db.execute("SELECT enabled FROM automod WHERE guild_id = ?", (guild_id,))
result = await cursor.fetchone()
return result is not None and result[0] == 1
async def update_punishments(self, guild_id, event, punishment):
async with aiosqlite.connect("db/automod.db") as db:
await db.execute("INSERT OR REPLACE INTO automod_punishments (guild_id, event, punishment) VALUES (?, ?, ?)", (guild_id, event, punishment))
await db.commit()
async def get_current_punishments(self, guild_id):
async with aiosqlite.connect("db/automod.db") as db:
async with db.execute(
"SELECT event, punishment FROM automod_punishments WHERE guild_id = ? AND event != 'Anti NSFW link'",
(guild_id,)
) as cursor:
return await cursor.fetchall()
async def is_anti_nsfw_enabled(self, guild_id):
async with aiosqlite.connect("db/automod.db") as db:
cursor = await db.execute("SELECT punishment FROM automod_punishments WHERE guild_id = ? AND event = 'Anti NSFW link'", (guild_id,))
result = await cursor.fetchone()
return result is not None
async def init_db(self):
async with aiosqlite.connect("db/automod.db") as db:
await db.execute("""
CREATE TABLE IF NOT EXISTS automod (
guild_id INTEGER PRIMARY KEY,
enabled INTEGER DEFAULT 0
)
""")
await db.execute("""
CREATE TABLE IF NOT EXISTS automod_punishments (
guild_id INTEGER,
event TEXT,
punishment TEXT,
PRIMARY KEY (guild_id, event)
)
""")
await db.execute("""
CREATE TABLE IF NOT EXISTS automod_ignored (
guild_id INTEGER,
type TEXT,
id INTEGER,
PRIMARY KEY (guild_id, type, id)
)
""")
await db.execute("""
CREATE TABLE IF NOT EXISTS automod_logging (
guild_id INTEGER,
log_channel INTEGER,
PRIMARY KEY (guild_id)
)
""")
await db.commit()
@commands.hybrid_group(invoke_without_command=True)
@blacklist_check()
@ignore_check()
@commands.cooldown(1, 4, commands.BucketType.user)
async def automod(self, ctx):
if ctx.subcommand_passed is None:
await ctx.send_help(ctx.command)
ctx.command.reset_cooldown(ctx)
@automod.command(name="enable", help="Enable Automod on the server.")
@blacklist_check()
@ignore_check()
@commands.cooldown(1, 5, commands.BucketType.user)
@commands.max_concurrency(1, per=commands.BucketType.default, wait=False)
@commands.guild_only()
@commands.has_permissions(administrator=True)
@commands.bot_has_permissions(manage_guild=True)
async def enable(self, ctx):
guild_id = ctx.guild.id
if ctx.author != ctx.guild.owner and ctx.author.top_role.position < ctx.guild.me.top_role.position:
await ctx.send(view=CV2(f"{CROSS} Access Denied", "Your top role must be at the **same** position or **higher** than my top role."))
return
if await self.is_automod_enabled(guild_id):
await ctx.send(view=CV2(f"Automod Settings for {ctx.guild.name}", f"**{CROSS} Your Server already has Automoderation Enabled.**\n\nCurrent Status: {ENABLE} Enabled\nTo Disable use `{ctx.prefix}automod disable`"))
return
events = [
"Anti spam",
"Anti caps",
"Anti link",
"Anti invites",
"Anti mass mention",
"Anti emoji spam",
"Anti NSFW link",
]
select_menu = discord.ui.Select(placeholder="Select events to enable", min_values=1, max_values=len(events), options=[
discord.SelectOption(label=event, value=event) for event in events
])
async def select_callback(interaction):
if interaction.user != ctx.author:
await interaction.response.send_message("You are not allowed to interact with this menu.", ephemeral=True)
return
await interaction.response.defer()
selected_events = select_menu.values
await self.enable_automod(ctx, guild_id, selected_events, interaction)
select_menu.callback = select_callback
enable_all_button = discord.ui.Button(label="Enable for All Events", style=discord.ButtonStyle.primary)
async def enable_all_callback(interaction):
if interaction.user != ctx.author:
await interaction.response.send_message("You are not allowed to interact with this button.", ephemeral=True)
return
await interaction.response.defer()
await self.enable_automod(ctx, guild_id, events, interaction)
enable_all_button.callback = enable_all_callback
cancel_button = discord.ui.Button(label="Cancel", style=discord.ButtonStyle.danger)
async def cancel_callback(interaction):
if interaction.user != ctx.author:
await interaction.response.send_message("You are not allowed to interact with this button.", ephemeral=True)
return
cancel_view = CV2("Automod Setup Cancelled", "The automod setup has been cancelled.")
await interaction.response.edit_message(view=cancel_view)
cancel_button.callback = cancel_callback
events_text = "\n".join([f"{DISABLE} : {event}" for event in events])
view = LayoutView(timeout=60)
view.add_item(build_container(
TextDisplay(f"**{ctx.guild.name}'s Automod Setup**"),
Separator(visible=True),
TextDisplay(events_text),
ActionRow(select_menu),
ActionRow(enable_all_button, cancel_button)
))
await ctx.send(view=view)
async def enable_automod(self, ctx, guild_id, selected_events, interaction):
async with aiosqlite.connect("db/automod.db") as db:
await db.execute("INSERT OR REPLACE INTO automod (guild_id, enabled) VALUES (?, 1)", (guild_id,))
for event in selected_events:
await db.execute("INSERT OR REPLACE INTO automod_punishments (guild_id, event, punishment) VALUES (?, ?, ?)", (guild_id, event, self.default_punishment))
await db.commit()
if "Anti NSFW link" in selected_events:
exempt_roles, exempt_channels = await self.get_exempt_roles_channels(guild_id)
nsfw_keywords = ["porn", "xxx", "adult", "sex", "nsfw", "xnxx", "onlyfans", "brazzers", "xhamster", "xvideos", "pornhub", "redtube", "livejasmin", "youporn" , "tube8", "pornhat", "swxvid", "ixxx", "pornhat"]
try:
await interaction.guild.create_automod_rule(
name="Anti NSFW Links",
event_type=discord.AutoModRuleEventType.message_send,
trigger=discord.AutoModTrigger(
type=discord.AutoModRuleTriggerType.keyword,
keyword_filter=nsfw_keywords,
),
actions=[
discord.AutoModRuleAction(type=discord.AutoModRuleActionType.block_message),
],
enabled=True,
exempt_roles=exempt_roles,
exempt_channels=exempt_channels,
reason="Automod - Anti NSFW Link setup"
)
except discord.Forbidden:
pass
except discord.HTTPException as e:
print(f"Automod rule-create error: {e}")
enable_logging_button = discord.ui.Button(label="Enable Automod Logging", style=discord.ButtonStyle.success)
async def enable_logging_callback(interaction):
if interaction.user != ctx.author:
await interaction.response.send_message("You are not allowed to interact with this button.", ephemeral=True)
return
if not interaction.guild.me.guild_permissions.manage_channels:
await interaction.response.send_message("I do not have permission to create channels.", ephemeral=True)
return
overwrites = {
interaction.guild.default_role: discord.PermissionOverwrite(view_channel=False),
interaction.guild.me: discord.PermissionOverwrite(view_channel=True)
}
try:
for channel in interaction.guild.channels:
if channel.name == f"{BRAND_NAME.lower()}-automod":
await interaction.response.send_message(f"A logging channel with the name \"{BRAND_NAME.lower()}-automod\" already exists.", ephemeral=True)
return
log_channel = await interaction.guild.create_text_channel(f"{BRAND_NAME.lower()}-automod", overwrites=overwrites)
guild_id = interaction.guild.id
async with aiosqlite.connect("db/automod.db") as db:
await db.execute("INSERT OR REPLACE INTO automod_logging (guild_id, log_channel) VALUES (?, ?)", (guild_id, log_channel.id))
await db.commit()
await interaction.response.send_message(f"Logging channel {log_channel.mention} created and set successfully.", ephemeral=True)
except discord.HTTPException as e:
await interaction.response.send_message(f"Failed to create logging channel: {e}", ephemeral=True)
enable_logging_button.callback = enable_logging_callback
events_text = "\n".join([f"{ENABLE} : {event}" for event in selected_events] + [f"{CROSS}{TICK} : {event}" for event in ["Anti spam", "Anti caps", "Anti link", "Anti invites", "Anti mass mention", "Anti emoji spam", "Anti NSFW link"] if event not in selected_events])
view = ShowRules(ctx.author, selected_events, "Automod Enabled Successfully", events_text)
await interaction.edit_original_response(content=None, view=view)
@automod.command(name="punishment", aliases=["punish"], help="Set the punishment for automod events.")
@blacklist_check()
@ignore_check()
@commands.cooldown(1, 5, commands.BucketType.user)
@commands.max_concurrency(1, per=commands.BucketType.default, wait=False)
@commands.guild_only()
@commands.has_permissions(administrator=True)
async def punishment(self, ctx):
guild_id = ctx.guild.id
if ctx.author != ctx.guild.owner and ctx.author.top_role.position < ctx.guild.me.top_role.position:
await ctx.send(view=CV2(f"{CROSS} Access Denied", "Your top role must be at the **same** position or **higher** than my top role."))
return
if not await self.is_automod_enabled(guild_id):
await ctx.send(view=CV2(f"Automod Settings for {ctx.guild.name}", f"Uhh, looks like your server hasn\'t enabled Automoderation.\n\nCurrent Status: {DISABLE} Disabled\nTo Enable use `{ctx.prefix}automod enable`"))
return
current_punishments = await self.get_current_punishments(guild_id)
punishments_list = "\n".join([f"**{event}**: {punishment or 'None'}" for event, punishment in current_punishments])
view_title = f"Current Automod Punishments for {ctx.guild.name}"
view_desc = punishments_list + "\n\nKeep the default punishment (Mute) to prevent server raids without kicking or banning raiders"
events = [event for event, _ in current_punishments]
select = discord.ui.Select(placeholder="Select events to update punishment", options=[
discord.SelectOption(label=event) for event in events
], min_values=1, max_values=len(events))
async def select_callback(interaction):
if interaction.user != ctx.author:
await interaction.response.send_message("You cannot interact with this menu.", ephemeral=True)
return
selected_events = select.values
await interaction.response.send_message("You selected: " + ", ".join(selected_events))
punishment_buttons = discord.ui.View()
for punishment in ["Mute", "Kick", "Ban"]:
button = discord.ui.Button(label=punishment, style=discord.ButtonStyle.danger)
async def punishment_callback(button_interaction, selected_events=selected_events, punishment=punishment):
if button_interaction.user != ctx.author:
await button_interaction.response.send_message("You cannot interact with this button.", ephemeral=True)
return
for event in selected_events:
await self.update_punishments(guild_id, event, punishment)
updated_punishments = await self.get_current_punishments(guild_id)
updated_list = "\n".join([f"**{event}**: {punishment or 'None'}" for event, punishment in updated_punishments])
await button_interaction.response.edit_message(view=CV2(f"Updated Automod Punishments for {ctx.guild.name}", updated_list, "You can modify the punishments by running the command again."))
button.callback = punishment_callback
punishment_buttons.add_item(button)
await interaction.edit_original_response(view=punishment_buttons)
select.callback = select_callback
view = CV2(view_title, view_desc)
view.add_item(select)
await ctx.send(view=view)
@automod.group(name="ignore", aliases=["exempt", "whitelist", "wl"], help="Manage whitelisted roles and channels for Automod.")
@blacklist_check()
@ignore_check()
@commands.cooldown(1, 4, commands.BucketType.user)
async def ignore(self, ctx):
if ctx.subcommand_passed is None:
await ctx.send_help(ctx.command)
ctx.command.reset_cooldown(ctx)
@ignore.command(name="channel", help="Add a channel to the whitelist.")
@blacklist_check()
@ignore_check()
@commands.cooldown(1, 5, commands.BucketType.user)
@commands.max_concurrency(1, per=commands.BucketType.default, wait=False)
@commands.guild_only()
@commands.has_permissions(administrator=True)
async def ignore_channel(self, ctx, channel: discord.TextChannel):
guild_id = ctx.guild.id
if ctx.author != ctx.guild.owner and ctx.author.top_role.position < ctx.guild.me.top_role.position:
await ctx.send(view=CV2(f"{CROSS} Access Denied", "Your top role must be at the **same** position or **higher** than my top role."))
return
if not await self.is_automod_enabled(guild_id):
await ctx.send(view=CV2(f"Automod Settings for {ctx.guild.name}", f"Uhh, looks like your server hasn\'t enabled Automoderation.\n\nCurrent Status: {DISABLE} Disabled\nTo Enable use `{ctx.prefix}automod enable`"))
return
async with aiosqlite.connect("db/automod.db") as db:
cursor = await db.execute("SELECT 1 FROM automod_ignored WHERE guild_id = ? AND type = 'channel' AND id = ?", (guild_id, channel.id))
if await cursor.fetchone() is not None:
await ctx.send(view=CV2("__Channel Already Whitelisted!__", f"{CROSS} The channel {channel.mention} is already in the ignore list.\n\n➜ Use **{ctx.prefix}automod unignore channel {channel.mention}** to remove it."))
return
count_cursor = await db.execute("SELECT COUNT(*) FROM automod_ignored WHERE guild_id = ? AND type = 'channel'", (guild_id,))
count = await count_cursor.fetchone()
if count[0] >= 10:
await ctx.send("You can only ignore up to 10 channels.")
return
await db.execute("INSERT OR REPLACE INTO automod_ignored (guild_id, type, id) VALUES (?, 'channel', ?)", (guild_id, channel.id))
await db.commit()
if await self.is_anti_nsfw_enabled(guild_id):
try:
rules = await ctx.guild.fetch_automod_rules()
for rule in rules:
if rule.name == "Anti NSFW Links":
exempt_channels = list(rule.exempt_channels)
exempt_channels.append(channel)
await rule.edit(
exempt_channels=exempt_channels,
reason="Channel exempted from Anti NSFW Links via automod ignore command"
)
break
except discord.HTTPException:
pass
await ctx.send(view=CV2(f"{TICK} Channel Whitelisted", f"The channel {channel.mention} has been added to the ignore list \n\n➜ Use `{ctx.prefix}automod ignore show` to view the ignore list."))
@ignore.command(name="role", help="Add a role to the whitelist.")
@blacklist_check()
@ignore_check()
@commands.cooldown(1, 5, commands.BucketType.user)
@commands.max_concurrency(1, per=commands.BucketType.default, wait=False)
@commands.guild_only()
@commands.has_permissions(administrator=True)
async def ignore_role(self, ctx, role: discord.Role):
guild_id = ctx.guild.id
if ctx.author != ctx.guild.owner and ctx.author.top_role.position < ctx.guild.me.top_role.position:
await ctx.send(view=CV2(f"{CROSS} Access Denied", "Your top role must be at the **same** position or **higher** than my top role."))
return
if not await self.is_automod_enabled(guild_id):
await ctx.send(view=CV2(f"Automod Settings for {ctx.guild.name}", f"Uhh, looks like your server hasn\'t enabled Automoderation.\n\nCurrent Status: {DISABLE} Disabled\nTo Enable use `{ctx.prefix}automod enable`"))
return
async with aiosqlite.connect("db/automod.db") as db:
cursor = await db.execute("SELECT 1 FROM automod_ignored WHERE guild_id = ? AND type = 'role' AND id = ?", (guild_id, role.id))
if await cursor.fetchone() is not None:
await ctx.send(view=CV2("__Role Already Whitelisted!__", f"{CROSS} The role {role.mention} is already in the ignore list.\n\n➜ Use **{ctx.prefix}automod unignore role {role.mention}** to remove it."))
return
count_cursor = await db.execute("SELECT COUNT(*) FROM automod_ignored WHERE guild_id = ? AND type = 'role'", (guild_id,))
count = await count_cursor.fetchone()
if count[0] >= 10:
await ctx.send("You can only ignore up to 10 roles.")
return
await db.execute("INSERT OR REPLACE INTO automod_ignored (guild_id, type, id) VALUES (?, 'role', ?)", (guild_id, role.id))
await db.commit()
if await self.is_anti_nsfw_enabled(guild_id):
try:
rules = await ctx.guild.fetch_automod_rules()
for rule in rules:
if rule.name == "Anti NSFW Links":
exempt_roles = list(rule.exempt_roles)
exempt_roles.append(role)
await rule.edit(
exempt_roles=exempt_roles,
reason="Role exempted from Anti NSFW Links via automod ignore command"
)
break
except discord.HTTPException:
pass
await ctx.send(view=CV2(f"{TICK} Role Whitelisted", f"The role {role.mention} has been added to the ignore list \n\n➜ Use `{ctx.prefix}automod ignore show` to view the ignore list."))
@ignore.command(name="show", aliases=["view", "list", "config"], help="Show the whitelisted roles and channels.")
@blacklist_check()
@ignore_check()
@commands.cooldown(1, 5, commands.BucketType.user)
@commands.max_concurrency(1, per=commands.BucketType.default, wait=False)
@commands.guild_only()
@commands.has_permissions(administrator=True)
async def ignore_show(self, ctx):
guild_id = ctx.guild.id
if ctx.author != ctx.guild.owner and ctx.author.top_role.position < ctx.guild.me.top_role.position:
await ctx.send(view=CV2(f"{CROSS} Access Denied", "Your top role must be at the **same** position or **higher** than my top role."))
return
if not await self.is_automod_enabled(guild_id):
await ctx.send(view=CV2(f"Automod Settings for {ctx.guild.name}", f"Uhh, looks like your server hasn\'t enabled Automoderation.\n\nCurrent Status: {DISABLE} Disabled\nTo Enable use `{ctx.prefix}automod enable`"))
return
async with aiosqlite.connect("db/automod.db") as db:
cursor = await db.execute("SELECT type, id FROM automod_ignored WHERE guild_id = ?", (guild_id,))
ignored_items = await cursor.fetchall()
if not ignored_items:
await ctx.reply("No ignored channels or roles found.")
return
ignored_channels = []
ignored_roles = []
for item_type, item_id in ignored_items:
if item_type == "channel":
channel = ctx.guild.get_channel(item_id)
if channel:
ignored_channels.append(f"{channel.mention} (ID: {channel.id})")
else:
ignored_channels.append(f"Deleted Channel (ID: {item_id})")
elif item_type == "role":
role = ctx.guild.get_role(item_id)
if role:
ignored_roles.append(f"{role.mention} (ID: {role.id})")
else:
ignored_roles.append(f"Deleted Role (ID: {item_id})")
ch_str = "\n".join(ignored_channels) if ignored_channels else "None"
rl_str = "\n".join(ignored_roles) if ignored_roles else "None"
await ctx.send(view=CV2("Ignored Channels & Roles for Automod", f"__Ignored Channels:__\n{ch_str}", f"__Ignored Roles:__\n{rl_str}"))
@ignore.command(name="reset", help="Reset the whitelist.")
@blacklist_check()
@ignore_check()
@commands.cooldown(1, 5, commands.BucketType.user)
@commands.max_concurrency(1, per=commands.BucketType.default, wait=False)
@commands.guild_only()
@commands.has_permissions(administrator=True)
async def ignore_reset(self, ctx):
guild_id = ctx.guild.id
if ctx.author != ctx.guild.owner and ctx.author.top_role.position < ctx.guild.me.top_role.position:
await ctx.send(view=CV2(f"{CROSS} Access Denied", "Your top role must be at the **same** position or **higher** than my top role."))
return
if not await self.is_automod_enabled(guild_id):
await ctx.send(view=CV2(f"Automod Settings for {ctx.guild.name}", f"Uhh, looks like your server hasn\'t enabled Automoderation.\n\nCurrent Status: {DISABLE} Disabled\nTo Enable use `{ctx.prefix}automod enable`"))
return
async with aiosqlite.connect("db/automod.db") as db:
await db.execute("DELETE FROM automod_ignored WHERE guild_id = ?", (guild_id,))
await db.commit()
await ctx.send(view=CV2(f"Automod Settings for {ctx.guild.name}", f"** {TICK} | All ignored channels and roles have been reset!**\n\nTo view current Automod settings use `{ctx.prefix}automod config`"))
@automod.group(name="unignore", aliases=["unwhitelist", "unwl"], invoke_without_command=True, help="Remove channels and roles from the whitelist.")
@blacklist_check()
@ignore_check()
@commands.cooldown(1, 5, commands.BucketType.user)
async def unignore(self, ctx):
if ctx.subcommand_passed is None:
await ctx.send_help(ctx.command)
ctx.command.reset_cooldown(ctx)
@unignore.command(name="channel", help="Remove a channel from the whitelist.")
@blacklist_check()
@ignore_check()
@commands.cooldown(1, 5, commands.BucketType.user)
@commands.max_concurrency(1, per=commands.BucketType.default, wait=False)
@commands.guild_only()
@commands.has_permissions(administrator=True)
async def unignore_channel(self, ctx, channel: discord.TextChannel):
guild_id = ctx.guild.id
if ctx.author != ctx.guild.owner and ctx.author.top_role.position < ctx.guild.me.top_role.position:
await ctx.send(view=CV2(f"{CROSS} Access Denied", "Your top role must be at the **same** position or **higher** than my top role."))
return
if not await self.is_automod_enabled(guild_id):
await ctx.send(view=CV2(f"Automod Settings for {ctx.guild.name}", f"Uhh, looks like your server hasn\'t enabled Automoderation.\n\nCurrent Status: {DISABLE} Disabled\nTo Enable use `{ctx.prefix}automod enable`"))
return
if await self.is_anti_nsfw_enabled(guild_id):
try:
rules = await ctx.guild.fetch_automod_rules()
for rule in rules:
if rule.name == "Anti NSFW Links":
exempt_channels = list(rule.exempt_channels)
exempt_channels = [ch for ch in exempt_channels if ch.id != channel.id]
await rule.edit(
exempt_channels=exempt_channels,
reason="Channel removed from Anti NSFW Links exemption via automod unignore command"
)
break
except discord.HTTPException:
pass
async with aiosqlite.connect("db/automod.db") as db:
result = await db.execute("DELETE FROM automod_ignored WHERE guild_id = ? AND type = 'channel' AND id = ?", (guild_id, channel.id))
await db.commit()
if result.rowcount > 0:
await ctx.send(view=CV2(f"{TICK} Success", f"{channel.mention} has been removed from the automod ignore list."))
else:
await ctx.send(view=CV2(f"{CROSS} Error", f"{channel.mention} is not in the automod ignore list."))
@unignore.command(name="role", help="Remove a role from the whitelist.")
@blacklist_check()
@ignore_check()
@commands.cooldown(1, 5, commands.BucketType.user)
@commands.max_concurrency(1, per=commands.BucketType.default, wait=False)
@commands.guild_only()
@commands.has_permissions(administrator=True)
async def unignore_role(self, ctx, role: discord.Role):
guild_id = ctx.guild.id
if ctx.author != ctx.guild.owner and ctx.author.top_role.position < ctx.guild.me.top_role.position:
await ctx.send(view=CV2(f"{CROSS} Access Denied", "Your top role must be at the **same** position or **higher** than my top role."))
return
if not await self.is_automod_enabled(guild_id):
await ctx.send(view=CV2(f"Automod Settings for {ctx.guild.name}", f"Uhh, looks like your server hasn\'t enabled Automoderation.\n\nCurrent Status: {DISABLE} Disabled\nTo Enable use `{ctx.prefix}automod enable`"))
return
if await self.is_anti_nsfw_enabled(guild_id):
try:
rules = await ctx.guild.fetch_automod_rules()
for rule in rules:
if rule.name == "Anti NSFW Links":
exempt_roles = list(rule.exempt_roles)
exempt_roles = [ch for ch in exempt_roles if ch.id != role.id]
await rule.edit(
exempt_roles=exempt_roles,
reason="Role removed from Anti NSFW Links exemption via automod unignore command"
)
break
except discord.HTTPException:
pass
async with aiosqlite.connect("db/automod.db") as db:
result = await db.execute("DELETE FROM automod_ignored WHERE guild_id = ? AND type = 'role' AND id = ?", (guild_id, role.id))
await db.commit()
if result.rowcount > 0:
await ctx.send(view=CV2(f"{TICK} Success", f"{role.mention} has been removed from the automod ignore list."))
else:
await ctx.send(view=CV2(f"{CROSS} Error", f"{role.mention} is not in the automod ignore list."))
@automod.command(name="disable", help="Disable Automod in the server.")
@blacklist_check()
@ignore_check()
@commands.cooldown(1, 5, commands.BucketType.user)
@commands.max_concurrency(1, per=commands.BucketType.default, wait=False)
@commands.guild_only()
@commands.has_permissions(administrator=True)
async def disable(self, ctx):
guild_id = ctx.guild.id
if ctx.author != ctx.guild.owner and ctx.author.top_role.position < ctx.guild.me.top_role.position:
await ctx.send(view=CV2(f"{CROSS} Access Denied", "Your top role must be at the **same** position or **higher** than my top role."))
return
if not await self.is_automod_enabled(guild_id):
await ctx.send(view=CV2(f"Automod Settings for {ctx.guild.name}", f"Uhh, looks like your server hasn\'t enabled Automoderation.\n\nCurrent Status: {DISABLE} Disabled\nTo Enable use `{ctx.prefix}automod enable`"))
return
view = ConfirmDisable(ctx.author, "Disable Automod Confirmation", "**Are you sure you want to disable Automod?**\n\nThis will remove all custom event settings, punishments, ignored roles/channels, & logging channel data.", "Click 'Yes' to disable Automod or 'No' to cancel.")
message = await ctx.send(view=view)
await view.wait()
if view.value is None:
await message.edit(view=CV2("Automod Disable Cancelled", "You took too long to respond. Automod disable process has been canceled."))
elif view.value:
async with aiosqlite.connect("db/automod.db") as db:
await db.execute("DELETE FROM automod WHERE guild_id = ?", (guild_id,))
await db.execute("DELETE FROM automod_punishments WHERE guild_id = ?", (guild_id,))
await db.execute("DELETE FROM automod_ignored WHERE guild_id = ?", (guild_id,))
await db.execute("DELETE FROM automod_logging WHERE guild_id = ?", (guild_id,))
await db.commit()
rules = await ctx.guild.fetch_automod_rules()
for rule in rules:
if rule.name == "Anti NSFW Links":
try:
await rule.delete(reason="Automod disabled - removing Anti NSFW Link rule")
except discord.Forbidden:
pass
except discord.HTTPException:
pass
await message.edit(view=CV2(f"{TICK_ALT} Automod Disabled", f"Automod has been successfully disabled for **{ctx.guild.name}.** \nAll settings, punishments, and logs have been removed.\n\nCurrent Status: {DISABLE} Disabled\n➜ To Re-enable use `{ctx.prefix}automod enable`."))
else:
await message.edit(view=CV2("Automod Disable Cancelled", "Automod disable process has been canceled."))
@automod.command(name="config", aliases=["settings", "show", "view"], help="View Automod settings.")
@blacklist_check()
@ignore_check()
@commands.cooldown(1, 5, commands.BucketType.user)
@commands.max_concurrency(1, per=commands.BucketType.default, wait=False)
@commands.guild_only()
@commands.has_permissions(administrator=True)
async def config(self, ctx):
guild_id = ctx.guild.id
if ctx.author != ctx.guild.owner and ctx.author.top_role.position < ctx.guild.me.top_role.position:
await ctx.send(view=CV2(f"{CROSS} Access Denied", "Your top role must be at the **same** position or **higher** than my top role."))
return
if not await self.is_automod_enabled(guild_id):
await ctx.send(view=CV2(f"Automod Settings for {ctx.guild.name}", f"Uhh, looks like your server hasn\'t enabled Automoderation.\n\nCurrent Status: {DISABLE} Disabled\nTo Enable use `{ctx.prefix}automod enable`"))
return
current_punishments = await self.get_current_punishments(guild_id)
items_str = []
for event, punishment in current_punishments:
items_str.append(f"**{event}**: {punishment or 'None'}")
if await self.is_anti_nsfw_enabled(guild_id):
items_str.append("**Anti NSFW Links**: Block Message")
async with aiosqlite.connect("db/automod.db") as db:
cursor = await db.execute("SELECT log_channel FROM automod_logging WHERE guild_id = ?", (guild_id,))
log_channel_id = await cursor.fetchone()
if log_channel_id and log_channel_id[0]:
log_channel = ctx.guild.get_channel(log_channel_id[0])
if log_channel:
items_str.append(f"**Logging Channel**: {log_channel.mention}")
else:
items_str.append("**Logging Channel**: Deleted Channel")
else:
items_str.append("**Logging Channel**: No logging channel")
await ctx.send(view=CV2(f"Enabled Automod Events & their punishment type for {ctx.guild.name}", "\n".join(items_str), "Manage punishment type for events by executing `automod punishment` command."))
@automod.command(name="logging", help="Set the logging channel for Automod events.")
@blacklist_check()
@ignore_check()
@commands.cooldown(1, 5, commands.BucketType.user)
@commands.max_concurrency(1, per=commands.BucketType.default, wait=False)
@commands.guild_only()
@commands.has_permissions(administrator=True)
async def logging(self, ctx, channel: discord.TextChannel):
guild_id = ctx.guild.id
if ctx.author != ctx.guild.owner and ctx.author.top_role.position < ctx.guild.me.top_role.position:
await ctx.send(view=CV2(f"{CROSS} Access Denied", "Your top role must be at the **same** position or **higher** than my top role."))
return
if not await self.is_automod_enabled(guild_id):
await ctx.send(view=CV2(f"Automod Settings for {ctx.guild.name}", f"Uhh, looks like your server hasn\'t enabled Automoderation.\n\nCurrent Status: {DISABLE} Disabled\nTo Enable use `{ctx.prefix}automod enable`"))
return
async with aiosqlite.connect("db/automod.db") as db:
await db.execute("INSERT OR REPLACE INTO automod_logging (guild_id, log_channel) VALUES (?, ?)", (guild_id, channel.id))
await db.commit()
await ctx.send(view=CV2(f"Automod Settings for {ctx.guild.name}", f"**{TICK} | Automoderation Logging channel set to {channel.mention}.**\n\n➜ Use `{ctx.prefix}automod config` to view current Automod settings."))
@commands.Cog.listener()
async def on_guild_remove(self, guild):
guild_id = guild.id
async with aiosqlite.connect("db/automod.db") as db:
await db.execute("DELETE FROM automod WHERE guild_id = ?", (guild_id,))
await db.execute("DELETE FROM automod_punishments WHERE guild_id = ?", (guild_id,))
await db.execute("DELETE FROM automod_ignored WHERE guild_id = ?", (guild_id,))
await db.execute("DELETE FROM automod_logging WHERE guild_id = ?", (guild_id,))
await db.commit()