async def reloadAPI(self, ctx, specificAPI: str = None): embed = None try: import importlib if specificAPI is None: importlib.reload(api) elif specificAPI is "vars": importlib.reload(api.vars) elif specificAPI is "easystyle": importlib.reload(api.easystyle) elif specificAPI is "blacklist": importlib.reload(api.blacklist) except Exception: tb = traceback.format_exc() embed = easystyle.embed(title="Reloading APIs failed!", description=f"```py\n{tb}```", color=discord.Color.red()) else: embed = easystyle.embed( title="APIs have reloaded successfully!", description= "You might need to reload cogs that import any of the APIs.", color=discord.Color.green()) finally: await ctx.send(ctx.author.mention, embed=embed) logging.info(f"{str(ctx.author)} reloaded APIs.")
async def _eval(self, ctx, *, command): placeholder = "async def flexExec():\n{}" cmds = [ f" {cmd}" for cmd in command.replace("```py", "").replace( "```", "").split("\n") ] executeData = placeholder.format("\n".join(cmds)) execGlobals = { "ctx": ctx, "client": self.client, "discord": discord, "commands": commands, "sellf": self } execLocals = {} try: exec(executeData, execGlobals, execLocals) ret = await execLocals['flexExec']() except Exception as e: embed = easystyle.embed(title=str(type(e).__name__), color=discord.Color.red()) tb = ''.join( traceback.format_exception(type(e), e, e.__traceback__)) embed.add_field(name="Traceback", value=f"```py\n{tb}\n```") await ctx.send(ctx.author.mention, embed=embed) else: embed = easystyle.embed(title="Success!", color=discord.Color.green()) embed.add_field(name="Result", value=f"```py\n{str(ret)}\n```") await ctx.send(ctx.author.mention, embed=embed)
async def screenshot(self, ctx: commands.Context, *, url: str): if not url.startswith("https://"): raise commands.UserInputError( "The URL must be HTTPS. Check if you have typed the URL correctly." ) message = await ctx.send(embed=easystyle.embed( title="Give us a while, please!", description= "Give us up to 30 seconds to properly load and screenshot the site, please!" )) quitFlag = False driver = webdriver.Chrome(options=self.options) try: driver.set_page_load_timeout(30) driver.set_window_size(1280, 720) driver.get(url) S = lambda X: driver.execute_script( 'return document.body.parentNode.scroll' + X) if S('Height') > 720 or S('Width') > 1280: driver.set_window_size(S('Width'), S('Height')) driver.save_screenshot(f"/tmp/{ctx.message.id}") except TimeoutException: await ctx.send( ctx.author.mention, embed=easystyle.embed( title="Oops!", description="Sorry, but the page took too long to load. Are " "you sure the site isn't malicious?", color=discord.Color.red())) quitFlag = True except WebDriverException: await ctx.send( ctx.author.mention, embed=easystyle.embed( title="Oops!", description="Sorry, but it seems like the page has crashed. " "Check if you have typed the URL correctly.", color=discord.Color.red())) quitFlag = True finally: await message.delete() # https://cdn.discordapp.com/attachments/724368480685523038/742284917089763368/unknown.png driver.quit() if quitFlag: return file = discord.File(f"/tmp/{ctx.message.id}", filename="ss.png") embed = easystyle.embed( title="Here is your screenshot!", description=f"The page you screenshotted is: {url}") embed.set_image(url="attachment://ss.png") await ctx.send(file=file, embed=embed) os.remove(f"/tmp/{ctx.message.id}")
async def load(self, ctx, cog: str): try: self.client.load_extension(f"cogs.{cog}") except: embed = easystyle.embed( title=f"Failed to load `cogs.{cog}`!", description=f"```py\n{traceback.format_exc()}\n```", color=discord.Color.red()) await ctx.send(ctx.author.mention, embed=embed) else: self.log.info(f"cogs.{cog} loaded by {str(ctx.author)}.") embed = easystyle.embed(title=f"Loaded `cogs.{cog}` successfully!", color=discord.Color.green()) await ctx.send(ctx.author.mention, embed=embed)
async def rextester(self, ctx, lang: str, *, code: str): code = code.replace("```", "") if lang.lower() not in languages: raise commands.UserInputError( f"Language {lang} is not recognized.") data = { "LanguageChoice": languages.get(lang.lower()), "Program": code, "Input": "", "CompilerArgs": compiler_args.get(lang.lower(), "") } async with aiohttp.ClientSession() as session: response = await self.__fetch(session, data) if response['Errors']: embed = easystyle.embed(title="Finished with errors.", description=response['Stats'], color=discord.Color.red()) embed.add_field(name="Errors", value=f"```\n{response['Errors']}\n```", inline=False) if response['Warnings']: embed.add_field(name="Warnings", value=f"```\n{response['Warnings']}\n```", inline=False) embed.add_field(name="Result", value=f"```\n{response['Result']}\n```", inline=False) return await ctx.send(ctx.author.mention, embed=embed) elif response['Warnings']: embed = easystyle.embed(title="Finished with warnings.", description=response['Stats'], color=discord.Color.gold()) embed.add_field(name="Warnings", value=f"```\n{response['Warnings']}\n```", inline=False) embed.add_field(name="Result", value=f"```\n{response['Result']}\n```", inline=False) return await ctx.send(ctx.author.mention, embed=embed) else: embed = easystyle.embed(title="Finished.", description=response['Stats'], color=discord.Color.green()) embed.add_field(name="Result", value=f"```\n{response['Result']}\n```", inline=False) return await ctx.send(ctx.author.mention, embed=embed)
async def serverinfo(self, ctx, *, guild: discord.Guild = None): if guild is None: guild = ctx.guild if guild.unavailable: raise commands.CheckFailure( "Server is unavailable at this time. Sorry!") embed = easystyle.embed(title=f"Details about {guild.name}") embed.add_field(name="Created at", value=guild.created_at.strftime("%Y-%m-%d %H:%M:%S")) member = ctx.guild.get_member(ctx.author.id) if member is not None: if member.joined_at is not None: embed.add_field( name="You joined at", value=member.joined_at.strftime("%Y-%m-%d %H:%M:%S")) embed.add_field(name="ID", value=str(guild.id)) embed.add_field(name="Owner", value=str(guild.owner)) embed.add_field(name="Region", value=str(guild.region)) if guild.afk_timeout != 0 and guild.afk_channel is not None: embed.add_field(name="Voice AFK timeout", value=str(guild.afk_timeout)) embed.add_field(name="Member count", value=str(guild.member_count)) embed.add_field(name="Server boosters", value=str(guild.premium_subscription_count)) embed.add_field(name="Nitro Boost level", value=str(guild.premium_tier)) embed.add_field(name="Do moderators require 2FA?", value="Yes" if guild.mfa_level == 1 else "No") embed.set_thumbnail(url=guild.icon_url) if guild.banner is not None: embed.set_image(url=guild.banner_url) await ctx.send(ctx.author.mention, embed=embed)
async def makeQR(self, ctx, *, data: str): img = qrcode.make(data) path = f"/tmp/kitty-qr{str(ctx.message.id)}" img.save(path, format="png") embed = easystyle.embed(title="Here is your QR code!", description=data) embed.set_image(url="attachment://qr.png") await ctx.send(ctx.author.mention, embed=embed, file=discord.File(path, filename="qr.png")) os.remove(path)
async def on_command(ctx): channel = client.get_channel(746317661696163932) embed = easystyle.embed( title= f"{str(ctx.author)} ({str(ctx.author.id)}) used command in {ctx.guild.name} ({str(ctx.guild.id)})", description=ctx.message.content) if len(ctx.message.attachments) > 0: embed.set_image(url=ctx.message.attachments[0].url) embed.set_author(name=str(ctx.author), icon_url=ctx.author.avatar_url) await channel.send(embed=embed)
async def rng(self, ctx: commands.Context, start: int = 1000, end: int = None): if end is None: end = start start = 1 if start > end: raise commands.UserInputError( "The start number cannot be higher than the end number.") number = await self.getRandomNumber(start, end) embed = easystyle.embed(title="Here's your random number!", description=f"`{str(number)}`") await ctx.send(ctx.author.mention, embed=embed)
async def stats(self, ctx): embed = easystyle.embed( title="Statistics" # description=f"System statistics that Kitty is running on currently." ) try: disk = subprocess.check_output(["df", "/", "--output=pcent"]) except: disk = None embed.add_field(name="System", value=platform.system()) embed.add_field(name="Python", value=platform.python_version()) embed.add_field(name="Discord.py version", value=discord.__version__) embed.add_field(name="CPU usage", value=str(round(psutil.cpu_percent(), 1)) + "%") embed.add_field(name="Memory usage", value=str(round(psutil.virtual_memory().percent, 1)) + "%") embed.add_field( name="Disk usage", value=disk.decode().split("\n")[1] if disk is not None else "N/A") embed.add_field(name="Hostname", value=platform.node()) chart = { 'type': 'line', 'data': { 'labels': [i['timestamp'] for i in self.counterData], 'datasets': [{ 'label': "CPU usage", 'data': [i['cpu'] for i in self.counterData], 'fill': False, 'borderColor': 'green' }, { 'label': "RAM usage", 'data': [i['mem'] for i in self.counterData], 'fill': False, 'borderColor': 'blue' }] }, 'options': { 'legend': { 'labels': { 'fontColor': 'white' } } } } r = requests.post("https://quickchart.io/chart/create", json={"chart": chart}) embed.set_image(url=r.json()['url']) await ctx.send(embed=embed)
async def readQR(self, ctx, *, imageURL: str = None): if imageURL is None: if len(ctx.message.attachments) == 0: raise commands.UserInputError("You need to supply an image (either as URL or attachment).") else: imageURL = ctx.message.attachments[0].url imageData = await self.__fetch(imageURL) if imageData is None: raise commands.UserInputError("The URL/attachment sent is not an image.") npData = np.frombuffer(imageData, np.uint8) img = cv2.imdecode(npData, flags=1) detector = cv2.QRCodeDetector() data, _, _ = detector.detectAndDecode(img) embed = easystyle.embed(title="Here's the QR code's data!", description=data) await ctx.send(ctx.author.mention, embed=embed)
async def internalCall(): try: async with ctx.channel.typing(): await func() except Exception as e: await self.client.get_cog("CommandExceptionHandler").on_command_error(ctx, e) else: embed = easystyle.embed( title=f"Your {filename} is ready!" ) if embedded: embed.set_image(url=f"attachment://{filename}.{fileext}") await ctx.send( ctx.author.mention, embed=embed, file=discord.File(f"/tmp/{str(ctx.message.id)}", filename=f"{filename}.{fileext}") ) os.remove(f"/tmp/{str(ctx.message.id)}")
async def help(self, ctx, *, argsStr: str = None): embed = easystyle.embed(title=f"{vars.botname} Help" # description = "PROTOTYPE | INTERNAL USE ONLY" ) if argsStr is None: # show categories cts = categories.getCategories() ctsList = [] for ctsKey, _ in cts.items(): ctsList.append( f"`k.help {ctsKey}` » {categories.getCategoryDesc(ctsKey)}" ) embed.add_field(name="Categories", value="\n".join(sorted(ctsList))) del ctsList return await ctx.send(ctx.author.mention, embed=embed) else: args = argsStr.split(" ") requested = args[0] # determine if user requested category details or command help isCategory = False category = None command = None cts = categories.getCategories() for ctsKey, _ in cts.items(): if requested == ctsKey: isCategory = True category = requested break if isCategory: # show category cmds ctsCogs = categories.getCategoryCogs(category) cmds = {} for _, cog in ctsCogs.items(): for cmd in cog.get_commands(): if cmd.name.startswith("_"): continue cmds.update({ cmd.name: cmd.description if cmd.description else 'None' }) commandStrs = [] for cmd in sorted(cmds.keys()): commandStrs.append(f"`k.{cmd}` » {cmds[cmd]}") embed.add_field(name=categories.getCategoryDesc(category), value="\n".join(commandStrs)) return await ctx.send(ctx.author.mention, embed=embed) else: command = requested category = None foundCmd = None # find cog this command belongs to cts = categories.getCategories() for ctsCategory, ctsCogs in cts.items(): for _, cog in ctsCogs.items(): for cmd in cog.get_commands(): if cmd.name == command: foundCmd = cmd category = ctsCategory break if foundCmd is None: raise commands.UserInputError("Command not found.") else: # display cmd info embed.description = f"`k.{foundCmd.name}`" if len(foundCmd.aliases) > 0: aliases = [f"`{alias}`" for alias in foundCmd.aliases] embed.add_field(name="Aliases", value="\n".join(aliases)) embed.add_field(name="Description", value=foundCmd.description if foundCmd.description else "None") if foundCmd.usage is not None: embed.add_field(name="Usage", value=f"`{foundCmd.usage}`") return await ctx.send(ctx.author.mention, embed=embed)
async def on_command_error(self, ctx, error): if hasattr(ctx.command, 'on_error'): return error = getattr(error, 'original', error) ignored = (commands.CommandNotFound, commands.NotOwner) if isinstance(error, ignored): return if isinstance(error, commands.MissingPermissions): return await ctx.send(ctx.author.mention, embed=easystyle.embed( title="Hold up!", description="You're not allowed to use this command, sorry!", color=discord.Color.red() )) if isinstance(error, commands.NSFWChannelRequired): return await ctx.send(ctx.author.mention, embed=easystyle.embed( title="Hold up!", description="This command can be used **only** in NSFW channels or DMs, sorry!", color=discord.Color.red() )) if isinstance(error, commands.CommandOnCooldown): return await ctx.send(ctx.author.mention, embed=easystyle.embed( title="Hold up!", description=f"This command is on cooldown! Please wait {str(round(error.retry_after, 1))} seconds " f"before retrying.", color=discord.Color.red() )) if isinstance(error, commands.BotMissingPermissions): permslist = '\n - '.join(error.missing_perms) return await ctx.send(ctx.author.mention, embed=easystyle.embed( title="Hold up!", description=f"The bot is missing the following permissions: {permslist}\nPlease make sure the bot " f"either has the Administrator permission or the permissions listed above.", color=discord.Color.red() )) if isinstance(error, commands.CheckFailure): return await ctx.send(ctx.author.mention, embed=easystyle.embed( title="Hold up!", description=f"One of our checks seem to have failed.\nHere's some more info: {error.message}", color=discord.Color.red() )) if isinstance(error, commands.UserInputError): return await ctx.send(ctx.author.mention, embed=easystyle.embed( title="Hold up!", description=f"I think you're missing some arguments! If you need help, remember you can use the " f"`k.help` command to quickly check what command does what!\nHere's some more info: " f"{str(error)}", color=discord.Color.red() )) if isinstance(error, aiohttp.client_exceptions.InvalidURL): return await ctx.send(ctx.author.mention, embed=easystyle.embed( title="Hold up!", description="It looks like you've entered an incorrect URL! Make sure the URL is correct, then try " "again!", color=discord.Color.red() )) if isinstance(error, aiohttp.client_exceptions.ClientPayloadError): return await ctx.send(ctx.author.mention, embed=easystyle.embed( title="Oops!", description="The server didn't send all the data properly!\nHere's some more info: " f"{str(error)}", color=discord.Color.red() )) if isinstance(error, discord.NotFound): errorText = "" if error.text: errorText = f"\nHere's some more info: {error.text}" return await ctx.send(ctx.author.mention, embed=easystyle.embed( title="Oops!", description=f"We couldn't find what you asked for!{errorText}" )) await ctx.send(ctx.author.mention, embed=easystyle.embed( title="Oops!", description="We're terribly sorry, but we've encountered an unexpected error!\nWe're sending the error " "log to one of our developers, don't worry!", color=discord.Color.red() )) tb = ''.join(traceback.format_exception(type(error), error, error.__traceback__)) msg = f"<@&701031325615915078>\n```py\n{tb}\n```" tracebackhell = self.client.get_channel(725880924788490281) if len(msg) > 2000: await tracebackhell.send("<@&701031325615915078> Here's the latest traceback!", file=discord.File(io.BytesIO(tb.encode()))) else: await tracebackhell.send(msg)
async def userinfo(self, ctx, *, user: Union[discord.User, int] = None): if isinstance(user, int): user = await self.client.fetch_user(user) if user is None: user = self.client.get_user(ctx.author.id) suffix = " (BOT)" if user.bot else "" embed = easystyle.embed(title=f"Details about {str(user)}{suffix}") embed.add_field(name="Created at", value=user.created_at.strftime("%Y-%m-%d %H:%M:%S")) member: discord.Member = ctx.guild.get_member(user.id) if member is None: for guild in self.client.guilds: temp = guild.get_member(user.id) if temp is not None: member = temp break if member is not None: if isinstance(member.status, discord.Status): statusName = "" if member.status == discord.Status.dnd: statusName = "Do Not Disturb" if member.status == discord.Status.online: statusName = "Online" if member.status == discord.Status.idle: statusName = "Idle" if member.status == discord.Status.offline: statusName = "Offline" embed.add_field( name="Status", value=f"{vars.emojis[member.status.value]} {statusName}") for activity in member.activities: if activity is not None: if activity.name is not None or activity.emoji is not None: if isinstance(activity, discord.CustomActivity): status = [] if activity.emoji is not None: status.append(str(activity.emoji)) if activity.name is not None: status.append(activity.name) embed.add_field(name="Custom Activity", value=" ".join(status)) elif isinstance(activity, discord.Streaming): embed.add_field( name=f"Streaming on {activity.platform}", value=f"[{activity.name}]" f"({activity.url})") elif isinstance(activity, discord.Spotify): artists = ', '.join(activity.artists) embed.add_field( name="Listening on Spotify", value=f"{artists} - {activity.title}") elif isinstance(activity, discord.Game): embed.add_field(name="Playing", value=activity.name) elif isinstance(activity, discord.Activity): if activity.type == discord.ActivityType.playing: embed.add_field(name="Playing", value=activity.name) elif activity.type == discord.ActivityType.streaming: embed.add_field(name="Streaming", value=activity.name) elif activity.type == discord.ActivityType.listening: embed.add_field(name="Listening to", value=activity.name) elif activity.type == discord.ActivityType.watching: embed.add_field(name="Watching", value=activity.name) if member.guild.id == ctx.guild.id: if member.joined_at is not None: embed.add_field( name="Joined at", value=member.joined_at.strftime("%Y-%m-%d %H:%M:%S")) embed.add_field(name="ID", value=str(user.id)) publicFlags = [] if user.public_flags.hypesquad_balance: publicFlags.append( "<:balance:737641844732592178> Hypesquad Balance") elif user.public_flags.hypesquad_bravery: publicFlags.append( "<:bravery:737641275624521779> Hypesquad Bravery") elif user.public_flags.hypesquad_brilliance: publicFlags.append( "<:brilliance:737641844661420112> Hypesquad Brilliance") if user.public_flags.staff: publicFlags.append("<:staff:737642960568582194> Discord Staff") if user.public_flags.partner: publicFlags.append("<:partner:737642666573168710> Discord Partner") if user.public_flags.hypesquad: publicFlags.append( "<:hypesquad:737645193838329876> Hypesquad Events") if user.public_flags.bug_hunter: publicFlags.append("<:bughunter:737643281789354045> Bug Hunger") if user.public_flags.verified_bot: publicFlags.append( "<:verifiedBot:737647956261601331> Verified Bot") if user.public_flags.verified_bot_developer: publicFlags.append( "<:verifiedDev:737645193406185503> Verified Bot Developer") if len(publicFlags) != 0: embed.add_field(name="Badges", value="\n".join(publicFlags)) embed.set_thumbnail(url=user.avatar_url) await ctx.send(ctx.author.mention, embed=embed)
async def avatar(self, ctx, *, user: discord.User = None): if user is None: user = self.client.get_user(ctx.author.id) embed = easystyle.embed(title=f"{str(user)}'s avatar") embed.set_image(url=user.avatar_url) await ctx.send(ctx.author.mention, embed=embed)