diff --git a/seautils/seautils.py b/seautils/seautils.py index e4468ca..897baf5 100644 --- a/seautils/seautils.py +++ b/seautils/seautils.py @@ -7,10 +7,14 @@ import inspect import operator +from functools import partial, partialmethod +from typing import Any -from discord import Embed +from discord import Embed, app_commands +from discord.utils import CachedSlotProperty, cached_property from redbot.core import commands from redbot.core.bot import Red +from redbot.core.dev_commands import cleanup_code from redbot.core.utils import chat_formatting as cf from redbot.core.utils.views import SimpleMenu @@ -34,13 +38,34 @@ class SeaUtils(commands.Cog): ] return "\n".join(text) + def format_src(self, ctx: commands.Context, obj: Any) -> str: + """A large portion of this code is repurposed from Zephyrkul's RTFS cog. + https://github.com/Zephyrkul/FluffyCogs/blob/master/rtfs/rtfs.py""" + obj = inspect.unwrap(obj) + src: Any = getattr(obj, "__func__", obj) + if isinstance(obj, (commands.Command, app_commands.Command)): + src = obj.callback + elif isinstance(obj, (partial, partialmethod)): + src = obj.func + elif isinstance(obj, property): + src = obj.fget + elif isinstance(obj, (cached_property, CachedSlotProperty)): + src = obj.function + return inspect.getsource(src) + @commands.command(aliases=["source", "src", "code", "showsource"]) @commands.is_owner() - async def showcode(self, ctx: commands.Context, *, command: str): - """Show the code for a particular command.""" + async def showcode(self, ctx: commands.Context, *, object: str): + """Show the code for a particular object.""" try: + if object.startswith("/") and (obj := ctx.bot.tree.get_command(object[1:])): + text = self.format_src(ctx, obj) + elif obj := ctx.bot.get_cog(object): + text = self.format_src(ctx, type(obj)) + elif obj:= ctx.bot.get_command(object): + text = self.format_src(ctx, obj) temp_content = cf.pagify( - text=inspect.getsource(self.bot.get_command(command).callback), + text=cleanup_code(text), escape_mass_mentions=True, page_length = 1977 ) @@ -53,7 +78,7 @@ class SeaUtils(commands.Cog): await SimpleMenu(pages=content, disable_after_timeout=True, timeout=180).start(ctx) except (OSError, AttributeError): if ctx.embed_requested(): - embed = Embed(title="Command not found!", color=await ctx.embed_color()) + embed = Embed(title="Object not found!", color=await ctx.embed_color()) await ctx.send(embed=embed, reference=ctx.message.to_reference(fail_if_not_exists=False)) else: - await ctx.send(content="Command not found!", reference=ctx.message.to_reference(fail_if_not_exists=False)) + await ctx.send(content="Object not found!", reference=ctx.message.to_reference(fail_if_not_exists=False))