async def cmd_kick( self, args, src: discord.Message, _reason: str = None, _noconfirm: bool = False, **_, ): """Kick a user from a guild. Syntax: `{p}kick [OPTIONS] <user tag/id>` Options: `--reason <str>` :: Provide a reason immediately, rather than typing a reason in a subsequent message. `--noconfirm` :: Perform the action immediately, without asking to make sure. ***This can get you in trouble if you mess up with it.*** """ if not args: raise CommandArgsError("No User specified.") if not lambdall(args, lambda x: x.isdigit()): raise CommandInputError("All IDs must be positive Integers.") guild: discord.Guild = self.client.main_guild target: discord.Member = guild.get_member(int(args[0])) if target is None: raise CommandInputError("Could not get user with that ID.") elif target.id == self.client.user.id: raise CommandOperationError( f"I'm sorry, {src.author.mention}. I'm afraid I can't let you do that." ) if _reason is None: await self.client.send_message( src.author, src.channel, "Please give a reason (just reply below): ") try: reason = await self.client.wait_for( "message", check=checks.all_checks( checks.Messages.by_user(src.author), checks.Messages.in_channel(src.channel), ), timeout=30, ) except asyncio.TimeoutError: raise CommandOperationError( "Timed out while waiting for reason.") _reason = reason.content targline: str = mono(userline(target)) if not _noconfirm: confirm = await confirm_action( self.client, src, "Member Kick", f"Confirm kicking {targline} from {target.guild.name}?", ) if confirm is not True: if confirm is False: raise CommandExit("Kick was cancelled.") else: raise CommandExit("Confirmation timed out.") try: await target.kick(reason=_reason) except discord.errors.Forbidden: raise CommandOperationError( "It seems I don't have perms to kick this user.") else: logEmbed = (discord.Embed( title="User Kick", description=_reason, colour=0xFF7900).set_author( name=src.author.display_name, icon_url=src.author.avatar_url).add_field( name="Issuer", value=mono(userline(src.author))).add_field( name="Recipient", value=targline).add_field( name="Guild", value=target.guild.name).add_field( name="Timestamp", value=str(dt.utcnow())[:-7]).set_thumbnail( url=target.avatar_url)) await self.client.log_moderation(embed=logEmbed) return f"Successfully Kicked: {targline}"
async def cmd_mute(self, args, src: discord.Message, **_): """Toggle the mute tag on a user if your guild supports that role. Syntax: `{p}mute <user tag/id>` """ if not args: raise CommandArgsError("Must provide User ID.") if not lambdall(args, lambda x: x.isdigit()): raise CommandArgsError("All IDs must be positive Integers.") target: discord.Member = self.client.main_guild.get_member(int( args[0])) if target is None: raise CommandInputError( f"Could not get user with ID `{int(args[0])}`.") elif target.id == self.client.user.id: raise CommandInputError( f"I'm sorry, {src.author.mention}. I'm afraid I can't let you do that." ) await self.client.send_message( src.author, src.channel, "Please give a reason for the mute (just reply below): ", ) try: reason = await self.client.wait_for( "message", check=checks.all_checks( checks.Messages.by_user(src.author), checks.Messages.in_channel(src.channel), ), timeout=30, ) except asyncio.TimeoutError: raise CommandOperationError("Timed out while waiting for reason.") role_mute: discord.Role = discord.utils.get(src.guild.roles, name="mute") if role_mute is None: raise CommandOperationError( "This guild does not have a `mute` role. To enable the mute " "function, set up the roles and name one `mute`.") else: try: if role_mute in target.roles: await target.remove_roles(role_mute, reason) # await self.client.guild_voice_state(target, mute=False) warnEmbed = discord.Embed( title="User Unmute", description= f"You have been unmuted by {src.author.name}.", colour=0x00FF11, ) warnEmbed.set_author( name=self.client.user.name, icon_url="https://puu.sh/tB2KH/cea152d8f5.png", ) # warnEmbed.add_field(name="Reason", value=reason.content) warnEmbed.add_field(name="Issuing Server", value=src.guild.name, inline=False) muteswitch = "Unmute" else: await target.add_roles(role_mute, reason) # await self.client.guild_voice_state(target, mute=True) warnEmbed = discord.Embed( title="User Mute", description= f"You have been muted by {src.author.name}.", colour=0xFF0000, ) warnEmbed.set_author( name=self.client.user.name, icon_url="https://puu.sh/tB2KH/cea152d8f5.png", ) warnEmbed.add_field(name="Reason", value=reason.content) warnEmbed.add_field(name="Issuing Server", value=src.guild.name, inline=False) muteswitch = "Mute" except discord.errors.Forbidden: raise CommandOperationError( "It seems I don't have permission to mute this user.") else: yield f"{target.name} (ID: {target.id}) was successfully {muteswitch}d" try: await target.send(embed=warnEmbed) except discord.errors.Forbidden: yield ( f" (FAILED to send a DM notification to user `{target.id}`.)", True, ) else: yield ( f" (A notification was sent in DM to user `{target.id}`.)", True, ) logEmbed = discord.Embed( title=f"User {muteswitch}", description=reason.content, colour=0x1200FF, ) logEmbed.add_field(name="Issuer", value=src.author.name + "\n" + src.author.id) logEmbed.add_field(name="Recipient", value=target.name + "\n" + target.id) logEmbed.add_field(name="Server", value=target.guild.name) logEmbed.add_field(name="Timestamp", value=str(dt.utcnow())[:-7]) logEmbed.set_thumbnail(url=target.avatar_url) await self.client.log_moderation(embed=logEmbed)
async def cmd_tempban( self, args, src: discord.Message, _reason: str = None, _purge: int = 1, _days: int = None, **_, ): """Temporarily ban a user. Syntax: `{p}tempban [OPTIONS] <user tag/id>` Options: `--reason <str>` :: Provide a reason immediately, rather than typing a reason in a subsequent message. `--purge <int>` :: Determine how many days of messages by the banned user to delete. Default is 1. Can be between 0 and 7, inclusive. `--days <int>` :: Provide a ban duration immediately, rather than typing a number of days in a subsequent message. """ if not args: return if not lambdall(args, lambda x: x.isdigit()): return "All IDs must be positive Integers." guild = self.client.main_guild userToBan = guild.get_member(int(args[0])) if userToBan is None: return "Could not get user with that ID." elif userToBan.id == self.client.user.id: return ( f"I'm sorry, {src.author.mention}. I'm afraid I can't let you do that." ) if not 0 <= _purge <= 7: return "Can only purge between 0 and 7 days of messages, inclusive." if _reason is None: await self.client.send_message( src.author, src.channel, "Please give a reason (just reply below): ") try: reason = await self.client.wait_for( "message", check=checks.all_checks( checks.Messages.by_user(src.author), checks.Messages.in_channel(src.channel), ), timeout=30, ) except asyncio.TimeoutError: return "Timed out while waiting for reason." _reason = reason.content if not _days: await self.client.send_message(src.author, src.channel, "How long? (days) ") try: msg2 = await self.client.wait_for( "message", check=(lambda x: checks.all_checks( checks.Messages.by_user(src.author), checks.Messages.in_channel(src.channel), )(x) and x.content.isdigit()), timeout=30, ) except asyncio.TimeoutError: return "Timed out while waiting for input" _days = int(msg2.content) try: # petal.logLock = True timex = time.time() + timedelta(days=int(_days)).total_seconds() self.client.db.update_member( userToBan, { "banned": True, "bannedFrom": userToBan.guild.id, "banExpires": str(timex).split(".")[0], "tempBanned": True, }, ) await userToBan.ban(reason=_reason, delete_message_days=_purge) except discord.errors.Forbidden: return "It seems I don't have perms to ban this user" else: logEmbed = discord.Embed(title="User Ban", description=_reason, colour=0xFF0000) logEmbed.add_field(name="Issuer", value=src.author.name + "\n" + str(src.author.id)) logEmbed.add_field(name="Recipient", value=userToBan.name + "\n" + str(userToBan.id)) logEmbed.add_field(name="Server", value=userToBan.guild.name) logEmbed.add_field(name="Timestamp", value=str(dt.utcnow())[:-7]) logEmbed.set_thumbnail(url=userToBan.avatar_url) await self.client.embed( self.client.get_channel(self.config.modChannel), logEmbed) return ( userToBan.name + " (ID: " + str(userToBan.id) + ") was successfully temp-banned.\n\nThey will be unbanned on " + str(dt.utcnow() + timedelta(days=_days))[:-7])
async def cmd_warn(self, args, src: discord.Message, **_): """Send an official and logged warning to a user. Syntax: `{p}warn <user tag/id>` """ if not args: return if not lambdall(args, lambda x: x.isdigit()): return "All IDs must be positive Integers." guild = self.client.main_guild userToWarn = guild.get_member(int(args[0])) if userToWarn is None: return "Could not get user with that ID." elif userToWarn.id == self.client.user.id: return ( f"I'm sorry, {src.author.mention}. I'm afraid I can't let you do that." ) await self.client.send_message( src.author, src.channel, "Please give a message to send (just reply below):") try: msg = await self.client.wait_for( "message", check=checks.all_checks( checks.Messages.by_user(src.author), checks.Messages.in_channel(src.channel), ), timeout=30, ) except asyncio.TimeoutError: return "Timed out while waiting for message." else: try: warnEmbed = discord.Embed( title="Official Warning", description="The guild has sent you an official warning", colour=0xFFF600, ) warnEmbed.add_field(name="Reason", value=msg.content) warnEmbed.add_field(name="Issuing Server", value=src.guild.name, inline=False) await self.client.embed(userToWarn, warnEmbed) except discord.errors.Forbidden: return "It seems I don't have perms to warn this user" else: logEmbed = discord.Embed(title="User Warn", description=msg.content, colour=0xFF600) logEmbed.set_author( name=self.client.user.name, icon_url="https://puu.sh/tADFM/dc80dc3a5d.png", ) logEmbed.add_field(name="Issuer", value=src.author.name + "\n" + str(src.author.id)) logEmbed.add_field(name="Recipient", value=userToWarn.name + "\n" + str(userToWarn.id)) logEmbed.add_field(name="Server", value=userToWarn.guild.name) logEmbed.add_field(name="Timestamp", value=str(dt.utcnow())[:-7]) logEmbed.set_thumbnail(url=userToWarn.avatar_url) await self.client.embed( self.client.get_channel(self.config.modChannel), logEmbed) return (userToWarn.name + " (ID: " + str(userToWarn.id) + ") was successfully warned")
async def cmd_ban( self, args, src: discord.Message, _reason: str = None, _purge: int = 1, _noconfirm: bool = False, **_, ): """Ban a user permanently. Syntax: `{p}ban [OPTIONS] <user tag/id>` Options: `--reason <str>` :: Provide a reason immediately, rather than typing a reason in a subsequent message. `--purge <int>` :: Determine how many days of messages by the banned user to delete. Default is 1. Can be between 0 and 7, inclusive. `--noconfirm` :: Perform the action immediately, without asking to make sure. ***This can get you in trouble if you mess up with it.*** """ if not args: return if not lambdall(args, lambda x: x.isdigit()): return "All IDs must be positive Integers." guild = self.client.main_guild userToBan = guild.get_member(int(args[0])) if userToBan is None: return "Could not get user with that ID." elif userToBan.id == self.client.user.id: return ( f"I'm sorry, {src.author.mention}. I'm afraid I can't let you do that." ) if not 0 <= _purge <= 7: return "Can only purge between 0 and 7 days of messages, inclusive." if _reason is None: await self.client.send_message( src.author, src.channel, "Please give a reason (just reply below): ") try: reason = await self.client.wait_for( "message", check=checks.all_checks( checks.Messages.by_user(src.author), checks.Messages.in_channel(src.channel), ), timeout=30, ) except asyncio.TimeoutError: return "Timed out while waiting for reason." _reason = reason.content if not _noconfirm: await self.client.send_message( src.author, src.channel, "You are about to ban: " + userToBan.name + ". If this is correct, type `yes`.", ) try: msg = await self.client.wait_for( "message", check=checks.all_checks( checks.Messages.by_user(src.author), checks.Messages.in_channel(src.channel), ), timeout=30, ) except asyncio.TimeoutError: return "Timed out... user was not banned." if msg.content.lower() != "yes": return userToBan.name + " was not banned." try: # petal.logLock = True self.client.db.update_member(userToBan, { "banned": True, "tempBanned": False, "banExpires": None }) await userToBan.ban(reason=_reason, delete_message_days=_purge) except discord.errors.Forbidden: return "It seems I don't have perms to ban this user." else: logEmbed = (discord.Embed( title="User Ban", description=_reason, colour=0xFF0000).set_author( name=self.client.user.name, icon_url="https://" + "puu.sh/tACjX/fc14b56458.png", ).add_field(name="Issuer", value=src.author.name + "\n" + str(src.author.id)).add_field( name="Recipient", value=userToBan.name + "\n" + str(userToBan.id)).add_field( name="Server", value=userToBan.guild.name).add_field( name="Timestamp", value=str( dt.utcnow())[:-7]).set_thumbnail( url=userToBan.avatar_url)) await self.client.embed( self.client.get_channel(self.config.modChannel), logEmbed) await asyncio.sleep(4) # petal.logLock = False response = await self.client.send_message( src.author, src.channel, userToBan.name + " (ID: " + str(userToBan.id) + ") was successfully banned.", ) try: # Post-processing webhook for ban command return self.generate_post_process_URI( src.author.name + src.author.discriminator, _reason, response.content, userToBan.name + userToBan.discriminator, ) except Exception as e: self.log.err( "Could not generate post_process_message for ban: " + str(e)) return "Error occurred trying to generate webhook URI"