278 lines
		
	
	
		
			8.4 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			278 lines
		
	
	
		
			8.4 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| import re
 | |
| 
 | |
| import aiohttp
 | |
| import disnake
 | |
| 
 | |
| import arguments
 | |
| import commands
 | |
| import utils
 | |
| from constants import APPLICATION_FLAGS, BADGE_EMOJIS, EMBED_COLOR, PUBLIC_FLAGS
 | |
| from state import client
 | |
| 
 | |
| 
 | |
| async def lookup(message):
 | |
|     tokens = commands.tokenize(message.content)
 | |
|     parser = arguments.ArgumentParser(
 | |
|         tokens[0],
 | |
|         "look up a discord user or application by ID",
 | |
|     )
 | |
|     parser.add_argument(
 | |
|         "-a",
 | |
|         "--application",
 | |
|         action="store_true",
 | |
|         help="look up applications instead of users",
 | |
|     )
 | |
|     parser.add_argument(
 | |
|         "id",
 | |
|         type=int,
 | |
|         help="the ID to perform a search for",
 | |
|     )
 | |
|     if not (args := await parser.parse_args(message, tokens)):
 | |
|         return
 | |
| 
 | |
|     if args.application:
 | |
|         session = aiohttp.ClientSession()
 | |
|         response = await (
 | |
|             await session.get(f"https://discord.com/api/v9/applications/{args.id}/rpc")
 | |
|         ).json()
 | |
|         if "code" in response.keys():
 | |
|             await utils.reply(message, "application not found!")
 | |
|             return
 | |
| 
 | |
|         embed = disnake.Embed(description=response["description"], color=EMBED_COLOR)
 | |
|         embed.set_thumbnail(
 | |
|             url=f"https://cdn.discordapp.com/app-icons/{response['id']}/{response['icon']}.webp",
 | |
|         )
 | |
|         embed.add_field(name="Application Name", value=response["name"])
 | |
|         embed.add_field(name="Application ID", value="`" + response["id"] + "`")
 | |
|         embed.add_field(
 | |
|             name="Public Bot",
 | |
|             value=f"{'`' + str(response['bot_public']) + '`' if 'bot_public' in response else 'No bot'}",
 | |
|         )
 | |
|         embed.add_field(name="Public Flags", value="`" + str(response["flags"]) + "`")
 | |
|         embed.add_field(
 | |
|             name="Terms of Service",
 | |
|             value=(
 | |
|                 "None"
 | |
|                 if "terms_of_service_url" not in response.keys()
 | |
|                 else f"[Link]({response['terms_of_service_url']})"
 | |
|             ),
 | |
|         )
 | |
|         embed.add_field(
 | |
|             name="Privacy Policy",
 | |
|             value=(
 | |
|                 "None"
 | |
|                 if "privacy_policy_url" not in response.keys()
 | |
|                 else f"[Link]({response['privacy_policy_url']})"
 | |
|             ),
 | |
|         )
 | |
|         embed.add_field(
 | |
|             name="Creation Time",
 | |
|             value=f"<t:{utils.snowflake_timestamp(int(response['id']))}:R>",
 | |
|         )
 | |
|         embed.add_field(
 | |
|             name="Default Invite URL",
 | |
|             value=(
 | |
|                 "None"
 | |
|                 if "install_params" not in response.keys()
 | |
|                 else f"[Link](https://discord.com/oauth2/authorize?client_id={response['id']}&permissions={response['install_params']['permissions']}&scope={'%20'.join(response['install_params']['scopes'])})"
 | |
|             ),
 | |
|         )
 | |
|         embed.add_field(
 | |
|             name="Custom Invite URL",
 | |
|             value=(
 | |
|                 "None"
 | |
|                 if "custom_install_url" not in response.keys()
 | |
|                 else f"[Link]({response['custom_install_url']})"
 | |
|             ),
 | |
|         )
 | |
| 
 | |
|         bot_intents = []
 | |
|         for application_flag, intent_name in APPLICATION_FLAGS.items():
 | |
|             if response["flags"] & application_flag == application_flag:
 | |
|                 if intent_name.replace(" (unverified)", "") not in bot_intents:
 | |
|                     bot_intents.append(intent_name)
 | |
|         embed.add_field(
 | |
|             name="Application Flags",
 | |
|             value=", ".join(bot_intents) if bot_intents else "None",
 | |
|         )
 | |
| 
 | |
|         bot_tags = ""
 | |
|         if "tags" in response.keys():
 | |
|             for tag in response["tags"]:
 | |
|                 bot_tags += tag + ", "
 | |
|         embed.add_field(
 | |
|             name="Tags",
 | |
|             value="None" if bot_tags == "" else bot_tags[:-2],
 | |
|             inline=False,
 | |
|         )
 | |
|     else:
 | |
|         try:
 | |
|             user = await client.fetch_user(args.id)
 | |
|         except Exception:
 | |
|             await utils.reply(message, "user not found!")
 | |
|             return
 | |
| 
 | |
|         badges = ""
 | |
|         for flag, flag_name in PUBLIC_FLAGS.items():
 | |
|             if user.public_flags.value & flag == flag:
 | |
|                 if flag_name != "None":
 | |
|                     try:
 | |
|                         badges += BADGE_EMOJIS[PUBLIC_FLAGS[flag]]
 | |
|                     except Exception:
 | |
|                         raise Exception(f"unable to find badge: {PUBLIC_FLAGS[flag]}")
 | |
| 
 | |
|         user_object = await client.fetch_user(user.id)
 | |
|         accent_color = 0x000000
 | |
|         if user_object.accent_color is not None:
 | |
|             accent_color = user_object.accent_color
 | |
| 
 | |
|         embed = disnake.Embed(color=accent_color)
 | |
|         embed.add_field(
 | |
|             name="User ID",
 | |
|             value=f"`{user.id}`",
 | |
|         )
 | |
|         embed.add_field(
 | |
|             name="Discriminator",
 | |
|             value=f"`{user.name}#{user.discriminator}`",
 | |
|         )
 | |
|         embed.add_field(
 | |
|             name="Creation Time",
 | |
|             value=f"<t:{utils.snowflake_timestamp(int(user.id))}:R>",
 | |
|         )
 | |
|         embed.add_field(
 | |
|             name="Public Flags",
 | |
|             value=f"`{user.public_flags.value}` {badges}",
 | |
|         )
 | |
|         embed.add_field(
 | |
|             name="Bot User",
 | |
|             value=f"`{user.bot}`",
 | |
|         )
 | |
|         embed.add_field(
 | |
|             name="System User",
 | |
|             value=f"`{user.system}`",
 | |
|         )
 | |
|         embed.set_thumbnail(url=user.avatar if user.avatar else user.default_avatar)
 | |
|         if user_object.banner:
 | |
|             embed.set_image(url=user_object.banner)
 | |
| 
 | |
|     await utils.reply(message, embed=embed)
 | |
| 
 | |
| 
 | |
| async def clear(message):
 | |
|     tokens = commands.tokenize(message.content)
 | |
|     parser = arguments.ArgumentParser(
 | |
|         tokens[0],
 | |
|         "bulk delete messages in the current channel matching certain criteria",
 | |
|     )
 | |
|     parser.add_argument(
 | |
|         "count",
 | |
|         type=lambda c: arguments.range_type(c, lower=1, upper=1000),
 | |
|         help="amount of messages to delete",
 | |
|     )
 | |
|     group = parser.add_mutually_exclusive_group()
 | |
|     group.add_argument(
 | |
|         "-r",
 | |
|         "--regex",
 | |
|         required=False,
 | |
|         help="delete messages with content matching this regex",
 | |
|     )
 | |
|     group.add_argument(
 | |
|         "-c",
 | |
|         "--contains",
 | |
|         required=False,
 | |
|         help="delete messages with content containing this substring",
 | |
|     )
 | |
|     parser.add_argument(
 | |
|         "-i",
 | |
|         "--case-insensitive",
 | |
|         action="store_true",
 | |
|         help="ignore case sensitivity when deleting messages",
 | |
|     )
 | |
|     parser.add_argument(
 | |
|         "-a",
 | |
|         "--author-id",
 | |
|         type=int,
 | |
|         action="append",
 | |
|         help="delete messages whose author matches this id",
 | |
|     )
 | |
|     parser.add_argument(
 | |
|         "-o",
 | |
|         "--oldest-first",
 | |
|         action="store_true",
 | |
|         help="delete oldest messages first",
 | |
|     )
 | |
|     parser.add_argument(
 | |
|         "-R",
 | |
|         "--reactions",
 | |
|         action="store_true",
 | |
|         help="delete messages with reactions",
 | |
|     )
 | |
|     parser.add_argument(
 | |
|         "-A",
 | |
|         "--attachments",
 | |
|         action="store_true",
 | |
|         help="delete messages with attachments",
 | |
|     )
 | |
|     parser.add_argument(
 | |
|         "-d",
 | |
|         "--delete-command",
 | |
|         action="store_true",
 | |
|         help="delete the command message as well",
 | |
|     )
 | |
|     parser.add_argument(
 | |
|         "-I",
 | |
|         "--ignore-ids",
 | |
|         type=int,
 | |
|         action="append",
 | |
|         help="ignore messages with this id",
 | |
|     )
 | |
|     if not (args := await parser.parse_args(message, tokens)):
 | |
|         return
 | |
| 
 | |
|     if args.delete_command:
 | |
|         try:
 | |
|             await message.delete()
 | |
|         except Exception:
 | |
|             pass
 | |
| 
 | |
|     regex = None
 | |
|     if r := args.regex:
 | |
|         regex = re.compile(r, re.IGNORECASE if args.case_insensitive else 0)
 | |
| 
 | |
|     def check(m):
 | |
|         if (ids := args.ignore_ids) and m.id in ids:
 | |
|             return False
 | |
|         c = []
 | |
|         if regex:
 | |
|             c.append(regex.search(m.content))
 | |
|         if s := args.contains:
 | |
|             if args.case_insensitive:
 | |
|                 c.append(s.lower() in m.content.lower())
 | |
|             else:
 | |
|                 c.append(s in m.content)
 | |
|         if i := args.author_id:
 | |
|             c.append(m.author.id in i)
 | |
|         if args.reactions:
 | |
|             c.append(len(m.reactions) > 0)
 | |
|         if args.attachments:
 | |
|             c.append(len(m.attachments) > 0)
 | |
|         return all(c)
 | |
| 
 | |
|     messages = len(
 | |
|         await message.channel.purge(
 | |
|             limit=args.count,
 | |
|             check=check,
 | |
|             oldest_first=args.oldest_first,
 | |
|         ),
 | |
|     )
 | |
| 
 | |
|     if not args.delete_command:
 | |
|         try:
 | |
|             await utils.reply(
 | |
|                 message,
 | |
|                 f"purged **{messages}/{args.count} {'message' if args.count == 1 else 'messages'}**",
 | |
|             )
 | |
|         except Exception:
 | |
|             pass
 |