async def unban(self, ctx, *args): 'Unbans multiple users. You can specify a reason.' parser = argparse.DiscordFriendlyArgparse(prog=ctx.command.name, add_help=True) parser.add_argument('-u', '--users', nargs='+', metavar='<id>', required=True, help='List of users to unban.') parser.add_argument('-r', '--reason', metavar='Reason', help='A reason for the unban.') try: args = parser.parse_args(args) except argparse.DiscordArgparseError as e: return await ctx.send(e) for i in args.users: if not ctx.author.permissions_in(ctx.channel).ban_members: return await ctx.send( ':no_entry_sign: Not enough permissions. You need Ban Members.' ) if not ctx.me.permissions_in(ctx.channel).ban_members: return await ctx.send( ':no_entry_sign: Grant the bot Ban Members before doing this.' ) await ctx.guild.unban( await self.get_user(i), reason=f'[{str(ctx.author)}] {args.reason}' if args.reason != None else f'Unban by {str(ctx.author)}') await ctx.send(':ok_hand:', delete_after=3)
async def kick(self, ctx, *args): """Kicks a member. You can specify a reason.""" parser = argparse.DiscordFriendlyArgparse(prog=ctx.command.name, add_help=True) parser.add_argument('-u', '--users', nargs='+', metavar='@user', required=True, help='List of users to kick.') parser.add_argument('-r', '--reason', metavar='Reason', help='A reason for the kick.') try: args = parser.parse_args(args) except argparse.DiscordArgparseError as e: return await ctx.send(e) members = [] for i in args.users: try: member = await commands.MemberConverter().convert(ctx, i) except commands.errors.BadArgument as e: return await ctx.send(f':x: | {e}') if ctx.author == member: return await ctx.send('Don\'t kick yourself, please.') if not ctx.author.permissions_in(ctx.channel).kick_members: return await ctx.send( ':no_entry_sign: Not enough permissions. You need Kick Members.' ) if not ctx.me.permissions_in(ctx.channel).kick_members: return await ctx.send( ':no_entry_sign: Grant the bot Kick Members before doing this.' ) if ctx.author.top_role <= member.top_role: return await ctx.send( ':no_entry_sign: You can\'t kick someone with a higher role than you!' ) if ctx.me.top_role <= member.top_role: return await ctx.send( ':no_entry_sign: I can\'t kick someone with a higher role than me!' ) members.append(member) for i in members: await ctx.guild.kick(i, reason=f'[{str(ctx.author)}] {args.reason}' if args.reason else f'Kick by {str(ctx.author)}') msg = await ctx.send(':ok_hand:') await asyncio.sleep(3) await msg.delete()
async def pardon(self, ctx, *args): """Removes a warning""" selfperms = ctx.author.permissions_in(ctx.channel) hasperm = (selfperms.kick_members or selfperms.ban_members or selfperms.manage_roles) if not hasperm: return await ctx.send(':no_entry_sign: Invalid permissions.') parser = argparse.DiscordFriendlyArgparse(prog=ctx.invoked_with, add_help=True) parser.add_argument('-u', '--users', nargs='+', required=True, metavar='@user', help='List of users to warn.') parser.add_argument('-r', '--reason', required=True, metavar='reason', help='Reason for the pardon.') parser.add_argument('-c', '--count', metavar='count', type=int, help='Number of warnings to remove.') try: args = parser.parse_args(args) except Exception as e: return await ctx.send(e) people = [] count = args.count or 1 if count <= 0: return await ctx.send(':x: Count must be 1 or above.') for i in args.users: try: m = await commands.MemberConverter().convert(ctx, i) except commands.errors.BadArgument as e: return await ctx.send(f':x: | {e}') people.append(m) for i in people: c = self._remove_warnings(ctx, i, count) if not c: return await ctx.send( ':x: You cannot pardon a user with no warnings.') await self._send_pardon_embed(ctx, people, args.reason, count) await ctx.send('Okay, pardoned.')
async def ban(self, ctx, *args): """Bans a member. You can specify a reason.""" parser = argparse.DiscordFriendlyArgparse(prog=ctx.command.name, add_help=True) parser.add_argument('-u', '--users', nargs='+', metavar='@user', required=True, help='List of users to ban.') parser.add_argument('-r', '--reason', metavar='Reason', help='A reason for the ban.') parser.add_argument( '-t', '--time', metavar='Time', help= 'A time for temporary bans. Once this is up, the ban will expire and the person will be unbanned. Must be formatted in ISO 8601. Omit for permanent ban.' ) parser.add_argument( '-d', '--days', metavar='Delete days', type=int, help= 'How many days\' worth of messages to delete from the banned user.' ) try: args = parser.parse_args(args) except argparse.DiscordArgparseError as e: return await ctx.send(e) people = [] for i in args.users: try: member = await commands.MemberConverter().convert(ctx, i) except commands.errors.BadArgument as e: return await ctx.send(f':x: | {e}') if ctx.author == member: return await ctx.send('Don\'t ban yourself, please.') if not ctx.author.permissions_in(ctx.channel).ban_members: return await ctx.send(':x: You need Ban Members.', delete_after=3) if ctx.author.top_role <= member.top_role: return await ctx.send( ':x: You can\'t ban someone with a higher role than you!') if ctx.me.top_role <= member.top_role: return await ctx.send( ':x: I can\'t ban someone with a higher role than me!') people.append(member) if args.time != None: for i in people: try: dura = isodate.parse_duration(args.time) except isodate.ISO8601Error as e: return await ctx.send(f':x: | {e}') if type(dura) == isodate.Duration: dura = dura.totimedelta() # make it super-safe expire = (dura + datetime.datetime.utcnow()).timestamp() now = datetime.datetime.utcnow().timestamp() r.table('tempbans').insert({ 'moderator': str(ctx.author.id), 'user': str(i.id), 'timestamp': str(now), 'expiration': str(expire), 'guild': str(ctx.guild.id) }).run(self.bot.conn) for member in people: await ctx.guild.ban( member, reason=f'[{str(ctx.author)}] {args.reason}' if args.reason != None else f'Ban by {str(ctx.author)}', delete_message_days=args.days if args.days != None else 7) msg = await ctx.send(':ok_hand:') await asyncio.sleep(3) await msg.delete()
async def unmute(self, ctx, *args): nosetting = f':x: You have not set up a mute list. Set one up now with `{ctx.prefix}set muted_roles \'Role 1\' \'Role 2\' \'Role 3\'`. You can have an infinite amount of roles in the list.' badsetting = f':x: The muted role list is incomplete. Did you delete a muted role? Please rerun setup with `{ctx.prefix}set muted_roles \'Role 1\' \'Role 2\' \'Role 3\'`. You can have an infinite amount of roles in the list.' parser = argparse.DiscordFriendlyArgparse(prog=ctx.invoked_with, add_help=True) parser.add_argument('-u', '--users', nargs='+', required=True, metavar='@user', help='List of users to unmute.') parser.add_argument('-r', '--reason', metavar='reason', help='The reason for the unmute.') try: args = parser.parse_args(args) except argparse.DiscordArgparseError or argparse.DiscordArgparseMessage as e: return await ctx.send(e) g = ctx.guild exists = (lambda: list( r.table('settings').filter(lambda a: a['guild'] == str(g.id)).run( self.conn)) != [])() if not exists: return await ctx.send(nosetting) settings = list( r.table('settings').filter(lambda a: a['guild'] == str(g.id)).run( self.conn))[0] if 'muted_roles' not in settings.keys(): return await ctx.send(nosetting) def get_role(g, id): for i in g.roles: if i.id == id: return i return None roles = [get_role(g, int(i)) for i in settings['muted_roles']] if any(i == None for i in roles): return await ctx.send(badsetting) # shouldn't happen people = [] for i in args.users: try: m = await commands.MemberConverter().convert(ctx, i) except commands.errors.BadArgument as e: return await ctx.send(f':x: | {e}') people.append(m) if any(ctx.author.top_role <= i.top_role for i in people): return await ctx.send( ':x: You cannot unmute someone with an equal ' 'or greater top role.') if any(ctx.me.top_role <= i.top_role for i in people): return await ctx.send( ':x: I cannot unmute someone with a higher ' 'top role than me. Move my role up.', delete_after=3) any_in = lambda a, b: any(i in b for i in a) a = {} for i in people: a[i.id] = [v for v in i.roles if v in set(roles)] if any(all(i is None for i in x) for x in a.values()): return await ctx.send(':x: One or more people were not muted.', delete_after=3) for person in people: await person.remove_roles( *a[person.id], reason=f'[{ctx.author}] {args.reason}' if args.reason != None else f'Unmute by {ctx.author}') await ctx.send( f':ok_hand: {", ".join([f"**{i.name}**#{i.discriminator}" for i in people])} {"has" if len(people) == 1 else "have"} been unmuted.' )
async def mute(self, ctx, *args): nosetting = f':x: You have not set up a mute list. Set one up now with `{ctx.prefix}set muted_roles \'Role 1\' \'Role 2\' \'Role 3\'`. You can have an infinite amount of roles in the list.' badsetting = f':x: The muted role list is incomplete. Did you delete a muted role? Please rerun setup with `{ctx.prefix}set muted_roles \'Role 1\' \'Role 2\' \'Role 3\'`. You can have an infinite amount of roles in the list.' parser = argparse.DiscordFriendlyArgparse(prog=ctx.invoked_with, add_help=True) parser.add_argument('-u', '--users', nargs='+', required=True, metavar='@user', help='List of users to mute.') parser.add_argument('-t', '--tier', metavar='tier', type=int, help='Tier number for the type of mute.') parser.add_argument('-r', '--reason', metavar='reason', help='The reason for the mute.') try: args = parser.parse_args(args) except argparse.DiscordArgparseError or argparse.DiscordArgparseMessage as e: return await ctx.send(e) tier = args.tier if args.tier != None else 0 g = ctx.guild exists = (lambda: list( r.table('settings').filter(lambda a: a['guild'] == str(g.id)).run( self.conn)) != [])() if not exists: return await ctx.send(nosetting) settings = list( r.table('settings').filter(lambda a: a['guild'] == str(g.id)).run( self.conn))[0] if 'muted_roles' not in settings.keys(): return await ctx.send(nosetting) def get_role(g, id): for i in g.roles: if i.id == id: return i return None roles = [get_role(g, int(i)) for i in settings['muted_roles']] if any(i == None for i in roles): return await ctx.send(badsetting) # shouldn't happen if tier > len(roles) or tier < 0: return await ctx.send( f':x: The tier value must range between 0 and {len(roles)}.', delete_after=3) people = [] for i in args.users: try: m = await commands.MemberConverter().convert(ctx, i) except commands.errors.BadArgument as e: return await ctx.send(f':x: | {e}') people.append(m) if any(ctx.author.top_role <= i.top_role for i in people): return await ctx.send( ':x: You cannot mute someone with an ' 'equal or greater top role.', delete_after=3) if any(ctx.me.top_role <= i.top_role for i in people): return await ctx.send( ':x: I cannot mute someone with a higher top ' 'role than me. Move my role up.', delete_after=3) for i in people: for x in i.roles: if x in roles: return await ctx.send( ':x: One or more people are already muted.', delete_after=3) for i in people: await i.add_roles(roles[tier], reason=f'[{ctx.author}] {args.reason}' if args.reason != None else f'Mute by {ctx.author}') await ctx.send( f':ok_hand: {", ".join([f"**{i.name}**#{i.discriminator}" for i in people])} {"has" if len(people) == 1 else "have"} been muted with tier **{tier}**, which is role {roles[tier]}.' )