async def mute( self, ctx: commands.Context, member: discord.Member, *, time: UserFriendlyTime(default='No reason', assume_reason=True) = None ) -> None: """Mutes a user""" if get_perm_level(member, await self.bot.db.get_guild_config( ctx.guild.id))[0] >= get_perm_level( ctx.author, await self.bot.db.get_guild_config(ctx.guild.id ))[0]: await ctx.send('User has insufficient permissions') else: duration = None reason = None if not time: duration = None else: if time.dt: duration = time.dt - ctx.message.created_at if time.arg: reason = time.arg await self.bot.mute(member, duration, reason=reason) await ctx.send(self.bot.accept)
async def slowmode(self, ctx: commands.Context, *, time: UserFriendlyTime(converter=commands.TextChannelConverter, default=False, assume_reason=True)) -> None: """Enables slowmode, max 6h Examples: !!slowmode 2h !!slowmode 2h #general !!slowmode off !!slowmode 0s #general """ duration = timedelta() channel = ctx.channel if time.dt: duration = time.dt - ctx.message.created_at if time.arg: if isinstance(time.arg, str): try: channel = await commands.TextChannelConverter().convert(ctx, time.arg) except commands.BadArgument: if time.arg != 'off': raise else: channel = time.arg seconds = int(duration.total_seconds()) if seconds > 21600: await ctx.send('Slowmode only supports up to 6h max at the moment') else: fmt = format_timedelta(duration, assume_forever=False) await channel.edit(slowmode_delay=int(duration.total_seconds())) await self.send_log(ctx, channel, fmt) if duration.total_seconds(): await ctx.send(f'Enabled `{fmt}` slowmode on {channel.mention}') else: await ctx.send(f'Disabled slowmode on {channel.mention}')
async def unban( self, ctx: commands.Context, member: MemberOrID, *, time: UserFriendlyTime(default='No reason', assume_reason=True) = None ) -> None: """Unswing the banhammer""" if get_perm_level(member, await self.bot.db.get_guild_config( ctx.guild.id))[0] >= get_perm_level( ctx.author, await self.bot.db.get_guild_config(ctx.guild.id ))[0]: await ctx.send('User has insufficient permissions') else: duration = None reason = None if not time: duration = None else: if time.dt: duration = time.dt - ctx.message.created_at if time.arg: reason = time.arg if duration is None: try: await ctx.guild.unban(member, reason=reason) except discord.NotFound as e: await ctx.send(f'Unable to unban user: {e}') else: await ctx.send(self.bot.accept) await self.send_log(ctx, member, reason) else: await ctx.send(self.bot.accept) seconds = duration.total_seconds() seconds += unixs() await self.bot.db.update_guild_config(ctx.guild.id, { '$push': { 'tempbans': { 'member': str(member.id), 'time': seconds } } }) self.bot.loop.create_task( self.bot.unban(ctx.guild.id, member.id, seconds))
async def ban( self, ctx: commands.Context, member: MemberOrID, *, time: UserFriendlyTime(default='No reason', assume_reason=True) = None ) -> None: """Swings the banhammer""" if get_perm_level(member, await self.bot.db.get_guild_config( ctx.guild.id))[0] >= get_perm_level( ctx.author, await self.bot.db.get_guild_config(ctx.guild.id ))[0]: await ctx.send('User has insufficient permissions') else: duration = None reason = None if not time: duration = None else: if time.dt: duration = time.dt - ctx.message.created_at if time.arg: reason = time.arg await self.alert_user(ctx, member, reason) await self.send_log(ctx, member, reason, duration) await ctx.guild.ban(member, reason=reason) if ctx.author != ctx.guild.me: await ctx.send(self.bot.accept) # log complete, save to DB if duration is not None: seconds = duration.total_seconds() seconds += unixs() await self.bot.db.update_guild_config(ctx.guild.id, { '$push': { 'tempbans': { 'member': str(member.id), 'time': seconds } } }) self.bot.loop.create_task( self.bot.unban(ctx.guild.id, member.id, seconds))
async def add_(self, ctx: commands.Context, member: MemberOrID, *, reason: CannedStr) -> None: """Warn a user Can also be used as `warn <member> [reason]`""" if get_perm_level(member, await self.bot.db.get_guild_config( ctx.guild.id))[0] >= get_perm_level( ctx.author, await self.bot.db.get_guild_config(ctx.guild.id ))[0]: await ctx.send('User has insufficient permissions') else: guild_config = await self.bot.db.get_guild_config(ctx.guild.id) guild_warns = guild_config.warns warn_punishments = guild_config.warn_punishments warn_punishment_limits = [i.warn_number for i in warn_punishments] warns = list( filter(lambda w: w['member_id'] == str(member.id), guild_warns)) cmd = None punish = False num_warns = len(warns) + 1 fmt = f'You have been warned in **{ctx.guild.name}**, reason: {reason}. This is warning #{num_warns}.' if warn_punishments: punishments = list( filter(lambda x: int(x) == num_warns, warn_punishment_limits)) if not punishments: punish = False above = list( filter(lambda x: int(x) > num_warns, warn_punishment_limits)) if above: closest = min(map(int, above)) cmd = warn_punishments.get_kv('warn_number', closest).punishment if cmd == 'ban': cmd = 'bann' if cmd == 'mute': cmd = 'mut' fmt += f' You will be {cmd}ed on warning {closest}.' else: punish = True punishment = warn_punishments.get_kv( 'warn_number', max(map(int, punishments))) cmd = punishment.punishment if cmd == 'ban': cmd = 'bann' if cmd == 'mute': cmd = 'mut' fmt += f' You have been {cmd}ed from the server.' try: await member.send(fmt) except discord.Forbidden: if ctx.author != ctx.guild.me: await ctx.send( 'The user has PMs disabled or blocked the bot.') finally: guild_config = await self.bot.db.get_guild_config(ctx.guild.id) current_date = (ctx.message.created_at + timedelta( hours=guild_config.time_offset)).strftime('%Y-%m-%d') if len(guild_warns) == 0: case_number = 1 else: case_number = guild_warns[-1]['case_number'] + 1 push = { 'case_number': case_number, 'date': current_date, 'member_id': str(member.id), 'moderator_id': str(ctx.author.id), 'reason': reason } await self.bot.db.update_guild_config( ctx.guild.id, {'$push': { 'warns': push }}) if ctx.author != ctx.guild.me: await ctx.send(self.bot.accept) await self.send_log(ctx, member, reason, case_number) # apply punishment if punish: if cmd == 'bann': cmd = 'ban' if cmd == 'mut': cmd = 'mute' ctx.command = self.bot.get_command(cmd) ctx.author = ctx.guild.me if punishment.get('duration'): time = UserFriendlyTime(default=False) time.dt = ctx.message.created_at + timedelta( seconds=punishment.duration) time.arg = f'Hit warn limit {num_warns}' kwargs = {'time': time} else: kwargs = {'reason': f'Hit warn limit {num_warns}'} await ctx.invoke(ctx.command, member, **kwargs)
async def setwarnpunishment( self, ctx: commands.Context, limit: int, punishment: str = None, *, time: UserFriendlyTime(default=False) = None) -> None: """Sets punishment after certain number of warns. Punishments can be "mute", "kick", "ban" or "none". Example: !!setwarnpunishment 5 kick !!setwarnpunishment mute !!setwarnpunishment mute 5h It is highly encouraged to add a final "ban" condition """ if punishment not in ('kick', 'ban', 'mute', 'none'): raise commands.BadArgument( 'Invalid punishment, pick from "mute", "kick", "ban", "none".') if punishment == 'none' or punishment is None: await self.bot.db.update_guild_config( ctx.guild.id, {'$pull': { 'warn_punishments': { 'warn_number': limit } }}) else: duration = None if time is not None and time.dt: duration = (time.dt - ctx.message.created_at).total_seconds() guild_config = await self.bot.db.get_guild_config(ctx.guild.id) if limit in [ i['warn_number'] for i in guild_config['warn_punishments'] ]: # overwrite await self.bot.db.update_guild_config(ctx.guild.id, { '$set': { 'warn_punishments.$[elem].punishment': punishment, 'warn_punishments.$[elem].duration': duration } }, array_filters=[{ 'elem.warn_number': limit }]) else: # push await self.bot.db.update_guild_config( ctx.guild.id, { '$push': { 'warn_punishments': { 'warn_number': limit, 'punishment': punishment, 'duration': duration } } }) await ctx.send(self.bot.accept)