jarvis-bot/jarvis/cogs/admin/lock.py
2021-07-26 19:10:07 -06:00

134 lines
4.2 KiB
Python

from typing import Union
from discord import Role, TextChannel, User, VoiceChannel
from discord.ext import commands
from discord_slash import SlashContext, cog_ext
from discord_slash.utils.manage_commands import create_option
from jarvis.db.types import Lock
from jarvis.utils.cachecog import CacheCog
from jarvis.utils.permissions import admin_or_permissions
class LockCog(CacheCog):
def __init__(self, bot: commands.Bot):
super().__init__(bot)
async def _lock_channel(
self,
channel: Union[TextChannel, VoiceChannel],
role: Role,
admin: User,
reason: str,
allow_send=False,
):
overrides = channel.overwrites_for(role)
if isinstance(channel, TextChannel):
overrides.send_messages = allow_send
elif isinstance(channel, VoiceChannel):
overrides.speak = allow_send
await channel.set_permissions(role, overwrite=overrides, reason=reason)
async def _unlock_channel(
self,
channel: Union[TextChannel, VoiceChannel],
role: Role,
admin: User,
):
overrides = channel.overwrites_for(role)
if isinstance(channel, TextChannel):
overrides.send_messages = None
elif isinstance(channel, VoiceChannel):
overrides.speak = None
await channel.set_permissions(role, overwrite=overrides)
@cog_ext.cog_slash(
name="lock",
description="Locks a channel",
options=[
create_option(
name="reason",
description="Lock Reason",
option_type=3,
required=True,
),
create_option(
name="duration",
description="Lock duration in minutes (default 10)",
option_type=4,
required=False,
),
create_option(
name="channel",
description="Channel to lock",
option_type=7,
required=False,
),
],
)
@admin_or_permissions(manage_channels=True)
async def _lock(
self,
ctx: SlashContext,
reason: str,
duration: int = 10,
channel: Union[TextChannel, VoiceChannel] = None,
):
await ctx.defer(hidden=True)
if duration <= 0:
await ctx.send("Duration must be > 0", hidden=True)
return
elif duration >= 300:
await ctx.send("Duration must be < 5 hours", hidden=True)
return
if len(reason) > 100:
await ctx.send("Reason must be < 100 characters", hidden=True)
return
if not channel:
channel = ctx.channel
for role in ctx.guild.roles:
try:
await self._lock_channel(channel, role, ctx.author, reason)
except Exception:
continue # Just continue on error
_ = Lock(
channel=channel.id,
guild=ctx.guild.id,
admin=ctx.author.id,
reason=reason,
duration=duration,
).insert()
await ctx.send(f"{channel.mention} locked for {duration} minute(s)")
@cog_ext.cog_slash(
name="unlock",
description="Unlocks a channel",
options=[
create_option(
name="channel",
description="Channel to lock",
option_type=7,
required=False,
),
],
)
@admin_or_permissions(manage_channels=True)
async def _unlock(
self,
ctx: SlashContext,
channel: Union[TextChannel, VoiceChannel] = None,
):
if not channel:
channel = ctx.channel
lock = Lock.get(guild=ctx.guild.id, channel=channel.id, active=True)
if not lock:
await ctx.send(f"{channel.mention} not locked.", hidden=True)
return
for role in ctx.guild.roles:
try:
await self._unlock_channel(channel, role, ctx.author)
except Exception:
continue # Just continue on error
lock.active = False
lock.update()
await ctx.send(f"{channel.mention} unlocked")