import jarvis from datetime import datetime, timedelta from discord import User, Member from discord.ext import commands from discord.utils import get from discord_slash import cog_ext from discord_slash.utils.manage_commands import create_option, create_choice from jarvis.utils.db import DBManager from jarvis.utils.permissions import admin_or_permissions class AdminCog(commands.Cog): """ Guild admin functions Used to manage guilds """ def __init__(self, bot): self.bot = bot config = jarvis.config.get_config() self.db = DBManager(config.mongo).mongo async def _ban( self, ctx, user: User = None, type: str = "perm", reason: str = None, length: int = 4, ): if not user or user == ctx.author: await ctx.send("You cannot ban yourself.") return if type == "temp" and length < 0: await ctx.send("You cannot set a temp ban to < 0 hours.") return if not reason: reason = ( "Mr. Stark is displeased with your presence. Please leave." ) mtype = type if mtype == "perm": mtype = "perma" guild_name = ctx.guild.name user_message = ( f"You have been {mtype}banned from {guild_name}." + " Reason:\n{reason}" ) time = datetime.now() expiry = None if mtype == "temp": user_message += f"\nDuration: {length} hours" expiry = time + timedelta(hours=length) await user.send(user_message) await ctx.guild.ban(user, reason=reason) if mtype == "soft": await ctx.guild.unban(user, reason="Ban was softban") await ctx.send( f"{user.name} has been {mtype}banned from {guild_name}." + f"Reason:\n{reason}" ) if type != "temp": length = None active = True if type == "soft": active = False self.db.jarvis.bans.insert_one( { "user": user.id, "reason": reason, "admin": ctx.author.id, "time": datetime.now(), "guild": ctx.guild.id, "type": type, "length": length, "expiry": expiry, "active": active, } ) @cog_ext.cog_slash( name="ban", description="Ban a user", guild_ids=[418094694325813248, 578757004059738142], options=[ create_option( name="user", description="User to ban", option_type=6, required=True, ), create_option( name="type", description="Ban type", option_type=3, required=False, choices=[ create_choice("Permanent", "perm"), create_choice("Temporary", "temp"), create_choice("Soft", "soft"), ], ), create_option( name="reason", description="Ban reason", required=False, option_type=3, ), create_option( name="duration", description="Ban duration in hours if temporary", required=False, option_type=4, ), ], ) @admin_or_permissions(ban_members=True) async def _ban_slash( self, ctx, user: User = None, type: str = "perm", reason: str = None, length: int = 12, ): await self._ban(ctx, user, type, reason, length) async def _kick(self, ctx, user: User, reason=None): if not user or user == ctx.author: await ctx.send("You cannot kick yourself.") return if not reason: reason = ( "Mr. Stark is displeased with your presence. Please leave." ) guild_name = ctx.guild.name try: await user.send( f"You have been kicked from {guild_name}. Reason:\n{reason}" ) except Exception: await ctx.send("Unable to message user.") await ctx.guild.kick(user, reason=reason) await ctx.send( f"{user.name} has been kicked from {guild_name}." + f"Reason:\n{reason}" ) self.db.jarvis.kicks.insert_one( { "user": user.id, "reason": reason, "admin": ctx.authod.id, "time": datetime.now(), "guild": ctx.guild.id, } ) @cog_ext.cog_slash( name="kick", description="Kick a user", guild_ids=[418094694325813248, 578757004059738142], options=[ create_option( name="user", description="User to kick", option_type=6, required=True, ), create_option( name="reason", description="Kick reason", required=False, option_type=3, ), ], ) @admin_or_permissions(kick_members=True) async def _kick_slash(self, ctx, user: User, reason=None): await self._kick(ctx, user, reason) async def _purge(self, ctx, amount: int = 10): channel = ctx.channel messages = [] async for message in channel.history(limit=amount + 1): messages.append(message) await channel.delete_messages(messages) self.db.jarvis.purges.insert_one( { "channel": ctx.channel.id, "guild": ctx.guild.id, "admin": ctx.author.id, "count": amount, "time": datetime.now(), } ) @cog_ext.cog_slash( name="purge", description="Purge messages from channel", guild_ids=[578757004059738142], options=[ create_option( name="amount", description="Amount of messages to purge", required=False, option_type=4, ) ], ) @admin_or_permissions(manage_messages=True) async def _purge_slash(self, ctx, amount: int = 10): if amount < 1: await ctx.send("Amount must be >= 1") return await ctx.defer() await self._purge(ctx, amount) @cog_ext.cog_slash( name="mute", description="Mute a user", guild_ids=[418094694325813248, 578757004059738142], options=[ create_option( name="user", description="User to mute", option_type=6, required=True, ), create_option( name="reason", description="Reason for mute", option_type=3, required=True, ), create_option( name="length", description="Mute length", option_type=4, required=False, ), ], ) @admin_or_permissions(mute_members=True) async def _mute(self, ctx, user: Member, reason: str, length: int = 30): ctx.defer() if user == ctx.author: await ctx.send("You cannot mute yourself.") return mute_setting = self.db.jarvis.settings.find_one( {"guild": ctx.guild.id, "setting": "mute"} ) if not mute_setting: await ctx.send( "Please configure a mute role with /settings mute first" ) return role = get(ctx.guild.roles, id=mute_setting["value"]) await user.add_roles(role, reason=reason) time = datetime.now() expiry = None if length < 0: length = -1 if length >= 0: expiry = time + timedelta(minutes=length) self.db.jarvis.mutes.insert_one( { "user": user.id, "reason": reason, "admin": ctx.author.id, "time": time, "guild": ctx.guild.id, "length": length, "expiry": expiry, "active": True if length >= 0 else False, } ) self.db.jarvis.mutes.update_many( { "guild": ctx.guild.id, "user": user.id, "expiry": {"$lt": expiry}, }, {"$set": {"active": False}}, ) await ctx.send(f"{user.mention} has been muted.\nReason: {reason}") @cog_ext.cog_slash( name="unmute", description="Unmute a user", guild_ids=[418094694325813248, 578757004059738142], options=[ create_option( name="user", description="User to unmute", option_type=6, required=True, ) ], ) @admin_or_permissions(mute_members=True) async def _unmute(self, ctx, user: Member): ctx.defer() mute_setting = self.db.jarvis.settings.find_one( {"guild": ctx.guild.id, "setting": "mute"} ) if not mute_setting: await ctx.send( "Please configure a mute role with /settings mute first." ) return role = get(ctx.guild.roles, id=mute_setting["value"]) if role in user.roles: await user.remove_roles(role, reason="Unmute") else: await ctx.send("User is not muted.") return self.db.jarvis.mutes.update_many( { "guild": ctx.guild.id, "user": user.id, }, {"$set": {"active": False}}, ) await ctx.send(f"{user.mention} has been unmuted.") def setup(bot): bot.add_cog(AdminCog(bot))