Пример #1
0
    async def _eval(self, ctx: commands.Context, *,
                    argument: codeblock_converter):
        """
        Direct evaluation of Python code.
        """
        if ctx.author.id in ownerid:

            arg_dict = get_var_dict_from_ctx(ctx, SCOPE_PREFIX)
            arg_dict["_"] = self.last_result

            scope = self.scope

            try:
                async with ReplResponseReactor(ctx.message):
                    with self.submit(ctx):
                        executor = AsyncCodeExecutor(argument.content,
                                                     scope,
                                                     arg_dict=arg_dict)
                        async for send, result in AsyncSender(executor):
                            if result is None:
                                continue

                            self.last_result = result

                            if isinstance(result, discord.File):
                                send(await ctx.send(file=result))
                            elif isinstance(result, discord.Embed):
                                send(await ctx.send(embed=result))
                            elif isinstance(result, PaginatorInterface):
                                send(await result.send_to(ctx))
                            else:
                                if not isinstance(result, str):
                                    # repr all non-strings
                                    result = repr(result)

                                if len(result) > 2000:
                                    # inconsistency here, results get wrapped in codeblocks when they are too large
                                    #  but don't if they're not. probably not that bad, but noting for later review
                                    paginator = WrappedPaginator(
                                        prefix='```py',
                                        suffix='```',
                                        max_size=1985)

                                    paginator.add_line(result)

                                    interface = PaginatorInterface(
                                        ctx.bot, paginator, owner=ctx.author)
                                    send(await interface.send_to(ctx))
                                else:
                                    if result.strip() == '':
                                        result = "\u200b"

                                    send(await ctx.send(
                                        result.replace(self.bot.http.token,
                                                       "[token omitted]")))
            finally:
                scope.clear_intersection(arg_dict)
Пример #2
0
    async def jsk_python_inspect(self, ctx: commands.Context, *,
                                 argument: codeblock_converter):
        """
        Evaluation of Python code with inspect information.
        """

        arg_dict = get_var_dict_from_ctx(ctx, Flags.SCOPE_PREFIX)
        arg_dict["_"] = self.last_result

        scope = self.scope

        try:
            async with ReplResponseReactor(ctx.message):
                with self.submit(ctx):
                    executor = AsyncCodeExecutor(argument.content,
                                                 scope,
                                                 arg_dict=arg_dict)
                    async for send, result in AsyncSender(executor):
                        self.last_result = result

                        header = repr(result).replace("``",
                                                      "`\u200b`").replace(
                                                          self.bot.http.token,
                                                          "[token omitted]")

                        if len(header) > 485:
                            header = header[0:482] + "..."

                        lines = [f"=== {header} ===", ""]

                        for name, res in all_inspections(result):
                            lines.append(f"{name:16.16} :: {res}")

                        docstring = (inspect.getdoc(result) or '').strip()

                        if docstring:
                            lines.append(f"\n=== Help ===\n\n{docstring}")

                        text = "\n".join(lines)

                        if use_file_check(ctx, len(
                                text)):  # File "full content" preview limit
                            send(await ctx.send(file=discord.File(
                                filename="inspection.prolog",
                                fp=io.BytesIO(text.encode('utf-8')))))
                        else:
                            paginator = WrappedPaginator(prefix="```prolog",
                                                         max_size=1985)

                            paginator.add_line(text)

                            interface = PaginatorInterface(ctx.bot,
                                                           paginator,
                                                           owner=ctx.author)
                            send(await interface.send_to(ctx))
        finally:
            scope.clear_intersection(arg_dict)
Пример #3
0
    async def jsk_python(self, ctx: SubContext, *,
                         argument: codeblock_converter):
        arg_dict = get_var_dict_from_ctx(ctx, SCOPE_PREFIX)
        arg_dict["_"] = self.last_result

        scope = self.scope

        try:
            async with ReplResponseReactor(ctx.message):
                with self.submit(ctx):
                    executor = AsyncCodeExecutor(argument.content,
                                                 scope,
                                                 arg_dict=arg_dict)
                    async for send, result in AsyncSender(executor):
                        if result is None:
                            continue

                        self.last_result = result

                        if isinstance(result, discord.File):
                            send(await ctx.send(file=result))
                        elif isinstance(result, discord.Embed):
                            send(await ctx.send(embed=result))
                        elif isinstance(result, PaginatorInterface):
                            send(await result.send_to(ctx))
                        elif isinstance(result, DCMenuPages):
                            send(await result.start(ctx))
                        else:
                            if not isinstance(result, str):
                                # repr all non-strings
                                result = repr(result)

                            result = result.replace(self.bot.http.token,
                                                    "[token omitted]")
                            if result.strip() == "":
                                result = "[empty string]"

                            if len(result) > 2000:
                                paginator = PartitionPaginator(prefix="```py")

                                paginator.add_line(result)

                                source = NormalPageSource(paginator.pages)

                                menu = DCMenuPages(source)

                                send(await menu.start(ctx))

                            else:
                                send(await ctx.send(f"```py\n{result}```"))

        finally:
            scope.clear_intersection(arg_dict)
Пример #4
0
    async def jsk_disassemble(self, ctx: commands.Context, *, argument: codeblock_converter):
        """
        Disassemble Python code into bytecode.
        """

        arg_dict = get_var_dict_from_ctx(ctx, SCOPE_PREFIX)

        async with ReplResponseReactor(ctx.message):
            paginator = WrappedPaginator(prefix='```py', suffix='```', max_size=1985)

            for line in disassemble(argument.content, arg_dict=arg_dict):
                paginator.add_line(line)

            interface = PaginatorInterface(ctx.bot, paginator, owner=ctx.author)
            await interface.send_to(ctx)
Пример #5
0
    async def jsk_python_inspect(self, ctx: commands.Context, *, argument: codeblock_converter):  # pylint: disable=too-many-locals
        """
        Evaluation of Python code with inspect information.
        """

        arg_dict = get_var_dict_from_ctx(ctx, SCOPE_PREFIX)
        arg_dict["_"] = self.last_result

        scope = self.scope

        try:
            async with ReplResponseReactor(ctx.message):
                with self.submit(ctx):
                    executor = AsyncCodeExecutor(argument.content, scope, arg_dict=arg_dict)
                    async for send, result in AsyncSender(executor):
                        self.last_result = result

                        header = repr(result).replace("``", "`\u200b`").replace(self.bot.http.token, "[token omitted]")

                        if len(header) > 485:
                            header = header[0:482] + "..."

                        lines = [f"=== {header} ===", ""]

                        for name, res in all_inspections(result):
                            lines.append(f"{name:16.16} :: {res}")

                        text = "\n".join(lines)

                        # Guild's advertised limit minus 1KiB for the HTTP content
                        filesize_threshold = (ctx.guild.filesize_limit if ctx.guild else 8 * 1024 * 1024) - 1024

                        if len(text) < filesize_threshold:
                            send(await ctx.send(file=discord.File(
                                filename="inspection.prolog",
                                fp=io.BytesIO(text.encode('utf-8'))
                            )))
                        else:
                            paginator = WrappedPaginator(prefix="```prolog", max_size=1985)

                            paginator.add_line(text)

                            interface = PaginatorInterface(ctx.bot, paginator, owner=ctx.author)
                            send(await interface.send_to(ctx))
        finally:
            scope.clear_intersection(arg_dict)
Пример #6
0
    async def jsk_python_inspect(
        self, ctx: commands.Context, *, argument: codeblock_converter
    ):
        """
        Evaluation of Python code with inspect information.
        """

        arg_dict = get_var_dict_from_ctx(ctx, SCOPE_PREFIX)
        arg_dict["_"] = self.last_result

        scope = self.scope

        try:
            async with ReplResponseReactor(ctx.message):
                with self.submit(ctx):
                    executor = AsyncCodeExecutor(
                        argument.content, scope, arg_dict=arg_dict
                    )
                    async for send, result in AsyncSender(executor):
                        self.last_result = result

                        header = (
                            repr(result)
                            .replace("``", "`\u200b`")
                            .replace(self.bot.http.token, "[token omitted]")
                        )

                        if len(header) > 485:
                            header = header[0:482] + "..."

                        paginator = WrappedPaginator(
                            prefix=f"```prolog\n=== {header} ===\n",
                            max_size=1985,
                        )

                        for name, res in all_inspections(result):
                            paginator.add_line(f"{name:16.16} :: {res}")

                        interface = PaginatorInterface(
                            ctx.bot, paginator, owner=ctx.author
                        )
                        send(await interface.send_to(ctx))
        finally:
            scope.clear_intersection(arg_dict)
Пример #7
0
    async def jsk_python(self, ctx: commands.Context, *, argument: CodeblockConverter):
        """
        Direct evaluation of Python code.
        """

        arg_dict = get_var_dict_from_ctx(ctx)

        scope = self.scope

        scope.clean()
        arg_dict["_"] = self.last_result

        async with ReplResponseReactor(ctx.message):
            with self.submit(ctx):
                async for result in AsyncCodeExecutor(
                    argument.content, scope, arg_dict=arg_dict
                ):
                    if result is None:
                        continue

                    self.last_result = result

                    if isinstance(result, discord.File):
                        await ctx.send(file=result)
                    elif isinstance(result, discord.Embed):
                        await ctx.send(embed=result)
                    else:
                        if not isinstance(result, str):
                            # repr all non-strings
                            result = repr(result)

                        if len(result) > 2000:
                            result = result[0:1997] + "..."
                        elif result.strip() == "":
                            result = "\u200b"

                        await ctx.send(
                            result.replace(self.bot.http.token, "[token omitted]")
                        )
Пример #8
0
    async def jsk_disassemble(self, ctx: commands.Context, *,
                              argument: codeblock_converter):
        """
        Disassemble Python code into bytecode.
        """

        arg_dict = get_var_dict_from_ctx(ctx, SCOPE_PREFIX)

        async with ReplResponseReactor(ctx.message):
            text = "\n".join(disassemble(argument.content, arg_dict=arg_dict))

            if len(text) < 50_000:  # File "full content" preview limit
                await ctx.send(file=discord.File(
                    filename="dis.py", fp=io.BytesIO(text.encode('utf-8'))))
            else:
                paginator = WrappedPaginator(prefix='```py', max_size=1985)

                paginator.add_line(text)

                interface = PaginatorInterface(ctx.bot,
                                               paginator,
                                               owner=ctx.author)
                await interface.send_to(ctx)
Пример #9
0
    async def jsk_python(self, ctx: commands.Context, *, argument: codeblock_converter):
        """
        Direct evaluation of Python code.
        """

        arg_dict = get_var_dict_from_ctx(ctx, SCOPE_PREFIX)
        arg_dict["_"] = self.last_result

        scope = self.scope

        try:
            async with ReplResponseReactor(ctx.message):
                with self.submit(ctx):
                    executor = AsyncCodeExecutor(argument.content, scope, arg_dict=arg_dict)
                    async for send, result in AsyncSender(executor):
                        if result is None:
                            continue

                        self.last_result = result

                        if isinstance(result, discord.File):
                            send(await ctx.send(file=result))
                        elif isinstance(result, discord.Embed):
                            send(await ctx.send(embed=result))
                        elif isinstance(result, PaginatorInterface):
                            send(await result.send_to(ctx))
                        else:
                            if not isinstance(result, str):
                                # repr all non-strings
                                result = repr(result)

                            # Guild's advertised limit minus 1KiB for the HTTP content
                            filesize_threshold = (ctx.guild.filesize_limit if ctx.guild else 8 * 1024 * 1024) - 1024

                            if len(result) <= 2000:
                                if result.strip() == '':
                                    result = "\u200b"

                                send(await ctx.send(result.replace(self.bot.http.token, "[token omitted]")))

                            elif len(result) < filesize_threshold:
                                # Discord's desktop and web client now supports an interactive file content
                                #  display for files encoded in UTF-8.
                                # Since this avoids escape issues and is more intuitive than pagination for
                                #  long results, it will now be prioritized over PaginatorInterface if the
                                #  resultant content is below the filesize threshold
                                send(await ctx.send(file=discord.File(
                                    filename="output.py",
                                    fp=io.BytesIO(result.encode('utf-8'))
                                )))

                            else:
                                # inconsistency here, results get wrapped in codeblocks when they are too large
                                #  but don't if they're not. probably not that bad, but noting for later review
                                paginator = WrappedPaginator(prefix='```py', suffix='```', max_size=1985)

                                paginator.add_line(result)

                                interface = PaginatorInterface(ctx.bot, paginator, owner=ctx.author)
                                send(await interface.send_to(ctx))

        finally:
            scope.clear_intersection(arg_dict)
Пример #10
0
    async def _dev_python(self, ctx, *, code: codeblock_converter):
        '''
        Evaluate python code
        '''
        arg_dict = get_var_dict_from_ctx(ctx, "")
        arg_dict["_"] = self.last_result

        scope = self._scope

        try:
            async with ReplResponseReactor(ctx.message):
                with self.submit(ctx):
                    executor = AsyncCodeExecutor(code.content,
                                                 scope,
                                                 arg_dict=arg_dict)
                    async for send, result in AsyncSender(executor):
                        if result is None:
                            continue

                        self.last_result = result

                        if isinstance(result, discord.File):
                            send(await ctx.reply(file=result))
                        elif isinstance(result, discord.Embed):
                            send(await ctx.reply(embed=result))
                        elif isinstance(result, PaginatorInterface):
                            send(await result.send_to(ctx))
                        else:
                            if not isinstance(result, str):
                                result = repr(result)

                            if len(result) > 2000:
                                result = result.replace("`", "`\u200b")
                                width = 2000
                                pages = [
                                    result[i:i + width]
                                    for i in range(0, len(result), width)
                                ]

                                for page in pages:
                                    embed = discord.Embed(
                                        description=f"```py\n{page}```",
                                        colour=discord.Colour.teal())
                                    pages[pages.index(page)] = embed

                                embedpaginator = paginator(
                                    ctx, remove_reactions=True)
                                embedpaginator.add_reaction(
                                    "\U000023ea", "first")
                                embedpaginator.add_reaction(
                                    "\U000025c0", "back")
                                embedpaginator.add_reaction(
                                    "\U0001f5d1", "delete")
                                embedpaginator.add_reaction(
                                    "\U000025b6", "next")
                                embedpaginator.add_reaction(
                                    "\U000023e9", "last")
                                send(await embedpaginator.send(pages))

                            else:
                                if result.strip() == '':
                                    result = "\u200b"

                                embed = discord.Embed(
                                    description=
                                    f"```py\n{result.replace(self.bot.http.token, '[token]')}```",
                                    colour=discord.Colour.teal())

                                send(await ctx.reply(embed=embed,
                                                     mention_author=False))
        finally:
            scope.clear_intersection(arg_dict)