mirror of
https://github.com/Lilac-Rose/Lacie.git
synced 2026-09-14 12:06:22 -05:00
Finally fixed muting, role gets removed after duration
This commit is contained in:
@@ -1,25 +1,32 @@
|
||||
import discord
|
||||
from discord.ext import commands
|
||||
from discord.ext import commands, tasks
|
||||
from discord.ui import View, Button
|
||||
import asyncio
|
||||
import re
|
||||
from datetime import timedelta
|
||||
import sqlite3
|
||||
import os
|
||||
from datetime import timedelta, datetime
|
||||
from .loader import ModerationBase
|
||||
|
||||
MUTE_ROLE_ID = 982702037517090836
|
||||
|
||||
class MuteCommand(ModerationBase):
|
||||
def __init__(self, bot):
|
||||
super().__init__(bot)
|
||||
self.bot = bot
|
||||
self.check_mutes.start()
|
||||
|
||||
def cog_unload(self):
|
||||
self.check_mutes.cancel()
|
||||
super().cog_unload()
|
||||
|
||||
@commands.command(name="mute")
|
||||
@ModerationBase.is_admin()
|
||||
async def mute(self, ctx, user: discord.Member, duration: str, *, reason: str = None):
|
||||
"""Mute a user for a duration with confirmation and log infraction"""
|
||||
# Parse duration
|
||||
match = re.match(r"(\d+)([wdh])", duration.lower())
|
||||
match = re.match(r"(\d+)([wdhm])", duration.lower())
|
||||
if not match:
|
||||
await ctx.send("Invalid duration format. Use **1w**, **5d**, **48h**, etc.")
|
||||
await ctx.send("Invalid duration format. Use **1w**, **5d**, **12h**, **30m**, etc.")
|
||||
return
|
||||
|
||||
value, unit = match.groups()
|
||||
value = int(value)
|
||||
if unit == "w":
|
||||
@@ -28,6 +35,8 @@ class MuteCommand(ModerationBase):
|
||||
delta = timedelta(days=value)
|
||||
elif unit == "h":
|
||||
delta = timedelta(hours=value)
|
||||
elif unit == "m":
|
||||
delta = timedelta(minutes=value)
|
||||
|
||||
view = View(timeout=30)
|
||||
confirmed = {"value": False}
|
||||
@@ -52,7 +61,6 @@ class MuteCommand(ModerationBase):
|
||||
no_button = Button(label="No", style=discord.ButtonStyle.red)
|
||||
yes_button.callback = yes_callback
|
||||
no_button.callback = no_callback
|
||||
|
||||
view.add_item(yes_button)
|
||||
view.add_item(no_button)
|
||||
|
||||
@@ -67,7 +75,6 @@ class MuteCommand(ModerationBase):
|
||||
return
|
||||
|
||||
await user.add_roles(mute_role, reason=reason)
|
||||
|
||||
try:
|
||||
await user.send(f"You have been muted in **{ctx.guild.name}** for **{duration}**.\nReason: {reason or 'No reason provided'}")
|
||||
except:
|
||||
@@ -76,16 +83,61 @@ class MuteCommand(ModerationBase):
|
||||
await self.log_infraction(ctx.guild.id, user.id, ctx.author.id, "mute", reason)
|
||||
await ctx.send(f"{user.mention} has been muted for **{duration}**.")
|
||||
|
||||
# Schedule unmute
|
||||
async def unmute_later():
|
||||
await asyncio.sleep(delta.total_seconds())
|
||||
try:
|
||||
await user.remove_roles(mute_role, reason="Mute duration expired")
|
||||
await ctx.send(f"{user.mention} has been unmuted (duration expired).")
|
||||
except:
|
||||
pass
|
||||
db_path = os.path.join(os.path.dirname(__file__), "moderation.db")
|
||||
conn = sqlite3.connect(db_path)
|
||||
c = conn.cursor()
|
||||
c.execute("""
|
||||
CREATE TABLE IF NOT EXISTS mutes (
|
||||
user_id INTEGER,
|
||||
guild_id INTEGER,
|
||||
channel_id INTEGER,
|
||||
unmute_time TEXT
|
||||
)
|
||||
""")
|
||||
unmute_time = (datetime.utcnow() + delta).isoformat()
|
||||
c.execute("INSERT INTO mutes (user_id, guild_id, channel_id, unmute_time) VALUES (?, ?, ?, ?)",
|
||||
(user.id, ctx.guild.id, ctx.channel.id, unmute_time))
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
asyncio.create_task(unmute_later())
|
||||
asyncio.create_task(self.schedule_unmute(user.id, ctx.guild.id, ctx.channel.id, delta.total_seconds()))
|
||||
|
||||
async def schedule_unmute(self, user_id, guild_id, channel_id, delay):
|
||||
await asyncio.sleep(delay)
|
||||
db_path = os.path.join(os.path.dirname(__file__), "moderation.db")
|
||||
conn = sqlite3.connect(db_path)
|
||||
c = conn.cursor()
|
||||
c.execute("DELETE FROM mutes WHERE user_id = ? AND guild_id = ?", (user_id, guild_id))
|
||||
conn.commit()
|
||||
conn.close()
|
||||
guild = self.bot.get_guild(guild_id)
|
||||
if not guild:
|
||||
return
|
||||
member = guild.get_member(user_id)
|
||||
if not member:
|
||||
return
|
||||
mute_role = guild.get_role(MUTE_ROLE_ID)
|
||||
if not mute_role:
|
||||
return
|
||||
try:
|
||||
await member.remove_roles(mute_role, reason="Mute duration expired")
|
||||
channel = guild.get_channel(channel_id)
|
||||
if channel:
|
||||
await channel.send(f"{member.mention} has been unmuted (duration expired).")
|
||||
except:
|
||||
pass
|
||||
|
||||
@tasks.loop(minutes=1)
|
||||
async def check_mutes(self):
|
||||
db_path = os.path.join(os.path.dirname(__file__), "moderation.db")
|
||||
conn = sqlite3.connect(db_path)
|
||||
c = conn.cursor()
|
||||
now = datetime.utcnow().isoformat()
|
||||
c.execute("SELECT user_id, guild_id, channel_id, unmute_time FROM mutes WHERE unmute_time <= ?", (now,))
|
||||
expired = c.fetchall()
|
||||
for user_id, guild_id, channel_id, _ in expired:
|
||||
asyncio.create_task(self.schedule_unmute(user_id, guild_id, channel_id, 0))
|
||||
conn.close()
|
||||
|
||||
async def setup(bot: commands.Bot):
|
||||
await bot.add_cog(MuteCommand(bot))
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import discord
|
||||
from discord.ext import commands
|
||||
from discord.ui import View, Button
|
||||
import asyncio
|
||||
import sqlite3
|
||||
import os
|
||||
from .loader import ModerationBase
|
||||
|
||||
MUTE_ROLE_ID = 982702037517090836
|
||||
@@ -11,7 +12,6 @@ class UnmuteCommand(ModerationBase):
|
||||
@commands.command(name="unmute")
|
||||
@ModerationBase.is_admin()
|
||||
async def unmute(self, ctx, user: discord.Member):
|
||||
"""Unmute a user with confirmation and log infraction"""
|
||||
view = View(timeout=30)
|
||||
confirmed = {"value": False}
|
||||
|
||||
@@ -31,11 +31,10 @@ class UnmuteCommand(ModerationBase):
|
||||
await interaction.response.edit_message(content="❌ Cancelled.", view=None)
|
||||
view.stop()
|
||||
|
||||
yes_button = Button(label="Yes", style=discord.ButtonStyle.green)
|
||||
no_button = Button(label="No", style=discord.ButtonStyle.red)
|
||||
yes_button = discord.ui.Button(label="Yes", style=discord.ButtonStyle.green)
|
||||
no_button = discord.ui.Button(label="No", style=discord.ButtonStyle.red)
|
||||
yes_button.callback = yes_callback
|
||||
no_button.callback = no_callback
|
||||
|
||||
view.add_item(yes_button)
|
||||
view.add_item(no_button)
|
||||
|
||||
@@ -50,7 +49,13 @@ class UnmuteCommand(ModerationBase):
|
||||
return
|
||||
|
||||
if mute_role in user.roles:
|
||||
await user.remove_roles(mute_role, reason="Unmute issued by command")
|
||||
await user.remove_roles(mute_role, reason="Manual unmute issued")
|
||||
db_path = os.path.join(os.path.dirname(__file__), "moderation.db")
|
||||
conn = sqlite3.connect(db_path)
|
||||
c = conn.cursor()
|
||||
c.execute("DELETE FROM mutes WHERE user_id = ? AND guild_id = ?", (user.id, ctx.guild.id))
|
||||
conn.commit()
|
||||
conn.close()
|
||||
try:
|
||||
await user.send(f"You have been **unmuted** in **{ctx.guild.name}**.")
|
||||
except:
|
||||
|
||||
Reference in New Issue
Block a user