示例#1
0
	async def exec(self, ctx, *, command):
		'Execute or evaluate code in python'
		binder = bookbinding.StringBookBinder(ctx, max_lines=50,prefix='```py', suffix='```')
		command = self.cleanup_code(command)
		
		try:
			binder.add_line('# Output:')
			if command.count('\n') == 0:
				with async_timeout.timeout(10):
					if command.startswith('await '):
						command = command[6:]
					result = eval(command)
					if inspect.isawaitable(result):
						binder.add_line(
							f'# automatically awaiting result {result}')
						result = await result
					binder.add(str(result))
			else:
				with async_timeout.timeout(60):
					with io.StringIO() as output_stream:
						with contextlib.redirect_stdout(output_stream):
							with contextlib.redirect_stderr(output_stream):
								wrapped_command = (
										'async def _aexec(ctx):\n' +
										'\n'.join(f'	{line}'
												  for line in command.split('\n')) +
										'\n')
								exec(wrapped_command)
								result = await (locals()['_aexec'](ctx))
						binder.add(output_stream.getvalue())
						binder.add('# Returned ' + str(result))
		except:
			binder.add(traceback.format_exc())
		finally:
			binder.start()
示例#2
0
    async def list(self, ctx):
        langs = [
            f"`{code}` - {lang.title()}" for code, lang in googletrans.LANGUAGES.items()
        ]

        book = bookbinding.StringBookBinder(ctx)
        for line in langs:
            book.add_line(line)

        await book.start()
示例#3
0
    async def bind_book_ex1(self, ctx):
        binder = bookbinding.StringBookBinder(ctx)

        binder.add(lipsum.lorem_ipsum)
        binder.with_prefix("```css")
        binder.with_suffix("```")
        binder.with_respond_to_author_only(False)
        binder.with_timeout(100)
        binder.with_open_on_number(5)
        binder.with_max_lines(7)

        await binder.start()
示例#4
0
    async def inspect_emoji(self, ctx, *, emoji: discord.Emoji = None):
        """
        Note that this will only work for custom emojis.
        If no emoji name is provided, we list all emojis available in this
        guild.
        """
        if emoji:

            desc = f'Created on {emoji.created_at.strftime("%c")}\n\n'

            if emoji.animated:
                desc += "Animated emoji\n"
            if emoji.require_colons:
                desc += "Must be wrapped in colons\n"
            if emoji.managed:
                desc += "Managed as part of a Twitch integration\n"
            if not emoji.roles:
                desc += "Emoji is usable by everyone here\n"

            rc = emoji.require_colons

            embed = discord.Embed(
                title=rc and f"`:{emoji.name}:`" or f"`{emoji}`",
                description=desc,
                url=emoji.url,
                colour=0xab19cf or emoji.animated and 0xd1851b,
            )

            if emoji.roles:
                embed.add_field(
                    name="Usable by",
                    value=string.trunc(", ".join(map(str, emoji.roles)), 1024),
                )

            embed.set_thumbnail(url=emoji.url)

            embed.set_author(name=f'Emoji in "{emoji.guild}"',
                             icon_url=emoji.url)
            embed.set_footer(text=str(emoji.id), icon_url=emoji.url)
            await ctx.send(embed=embed)
        elif len(ctx.guild.emojis) == 0:
            await ctx.send("This server has no emojis yet...", delete_after=10)
        else:
            binder = bookbinding.StringBookBinder(ctx, max_lines=None)

            def key(e):
                return e.name

            for i, e in enumerate(sorted(ctx.guild.emojis, key=key)):
                binder.add_line(f"`{i + 1:03}`\t{e} \t `{e}`")

            binder.start()
示例#5
0
    async def _send_table(ctx, *unicodes):
        """Creates a markdown formatted table of results for characters."""

        book = bookbinding.StringBookBinder(ctx, max_lines=None)

        preamble = (
            f"**Character info (Unicode v{unicodedata.unidata_version})**",
            "__**`##  Ct UTF-CODE DECIMAL DESCRIPTION`**__",
        )

        # Categories for current page
        categories = set()
        current_page = []

        def dump_page():
            nonlocal current_page
            # Define the categories used.
            category_amble = ""
            for category in sorted(categories):
                desc = _char2category.get(category, "Unknown")
                category_amble += f"\n`{category}` - {desc}"

            page = "\n".join((*preamble, *current_page, category_amble))
            book.add_break()
            book.add_raw(page)
            categories.clear()
            current_page = []

        for i, char in enumerate(unicodes):
            decimal = char.raw
            hexd = f"U+{hex(decimal)[2:]}"
            category = char.category
            name = char.name
            lit = chr(char.raw)

            current_page.append(
                f"`{i+1:02}  {category} {hexd:>8} {decimal:>7} "
                f"{name}  {lit}`  {lit}")

            categories.add(category)

            if i % 16 == 15:
                dump_page()

        if current_page:
            dump_page()

        booklet = book.build()
        if len(booklet) > 1:
            await book.start()
        else:
            await ctx.send(booklet.current_page)
示例#6
0
    async def view_binds(self, ctx):
        if ctx.guild.me.guild_permissions.manage_webhooks:
            binder = bookbinding.StringBookBinder(ctx)
            for bind_command, value in self.binds.items():
                if isinstance(value, tuple):
                    value = ", ".join(value)

                binder.add_line(f"• `{bind_command}`: {value}")
            binder.start()
        else:
            await ctx.send("I don't seem to have the MANAGE_WEBHOOKS "
                           "permission required for this to work. Please "
                           "grant me that ")
示例#7
0
    async def bind_book_ex3(self, ctx):
        binder = bookbinding.StringBookBinder(
            ctx,
            max_lines=7,
            start_page=5,
            timeout=100,
            only_author=True,
            prefix="```css",
            suffix="```",
        )

        binder.add(lipsum.lorem_ipsum)

        await binder.start()
示例#8
0
    async def bind_book_ex5(self, ctx):
        binder = bookbinding.StringBookBinder(
            ctx,
            max_lines=7,
            start_page=5,
            timeout=100,
            only_author=True,
            prefix="```css",
            suffix="```",
        )

        super_long_string = ""

        i = 0
        for i in range(0, 10_000, max(i // 10, 1)):
            super_long_string += ". "
            super_long_string += f'{(i//26 + 1) * chr(ord("a") + (i % 26)):}'
示例#9
0
    async def cppref(self, ctx, *terms):

        try:
            async with ctx.typing():
                results = await self.results(*terms)
        except BaseException as ex:
            return await ctx.send(
                "CppReference did something unexpected. If this keeps "
                "happening, contact Esp with the following info: \n\n"
                f"{type(ex).__qualname__}: {ex!s}"
            )

        if not results:
            return await ctx.send("No results were found.", delete_after=10)

        if len(results) > 1:
            # Show an option picker
            result = await userinput.option_picker(ctx, *results, max_lines=20)
            await asyncio.sleep(0.25)

            if not result:
                return
        else:
            result = results[0]

        # Fetch the result page.
        try:
            url, h1, tasters, header, desc = await self.get_information(result.href)
        except:
            return await ctx.send("Rude! Cppreference just hung up on me..!")

        binder = bookbinding.StringBookBinder(ctx, max_lines=50)

        binder.add_line(f"**{h1}**\n<{url}>", dont_alter=True)
        if header:
            binder.add_line(f"\n`{header}`", dont_alter=True)

        if tasters:
            for taster in tasters:
                binder.add_line(f"```cpp\n{taster}\n```", dont_alter=True)

        if desc:
            binder.add_line(desc.replace("*", "∗"))

        binder.start()
示例#10
0
    async def bind_book_ex4(self, ctx):
        binder = bookbinding.StringBookBinder(
            ctx,
            max_lines=7,
            start_page=5,
            timeout=100,
            only_author=True,
            prefix="```css",
            suffix="```",
        )

        binder.add(lipsum.lorem_ipsum)

        booklet = binder.build()

        # Run async without waiting.
        booklet.start()
        await ctx.send("This is async.")
示例#11
0
    async def help(self, ctx, *, language=None):
        """
        Shows all supported languages and their markdown highlighting
        syntax expected to invoke them correctly.
        """
        if not language:
            booklet = bookbinding.StringBookBinder(ctx)
            booklet.add_line("**Supported languages**")

            for lang in sorted(rextester.Language.__members__.keys()):
                lang = lang.lower()
                booklet.add_line(
                    f"- {lang.title()} -- `{ctx.prefix}rxt " f"ˋˋˋ{lang} ...`"
                )
            booklet.start()
        else:
            await ctx.send(
                "There is nothing here yet. The developer has " "been shot as a result."
            )
示例#12
0
文件: py.py 项目: davfsa/nekosquared
    async def pypi(self, ctx, package):
        """
        Input must be two or more characters wide.
        """
        if len(package) < 2:
            return await ctx.send("Please provide at least two characters.",
                                  delete_after=10)

        def executor():
            # https://wiki.python.org/moin/PyPIXmlRpc
            # TODO: find a less shit way to do this
            # This is deprecated.
            client = xmlrpcclient.ServerProxy("https://pypi.python.org/pypi")
            return client.search({"name": package})

        with ctx.typing():
            results = await self.run_in_io_executor(executor)

        book = bookbinding.StringBookBinder(ctx, max_lines=None)

        head = f"**__Search results for `{package}`__**\n"
        for i, result in enumerate(results[:50]):
            if not i % 5:
                book.add_break()
                book.add_line(head)

            name = result["name"]
            link = f"<https://pypi.org/project/{parse.quote(name)}>"
            ver = result["version"]
            summary = result["summary"]
            summary = summary and f"- _{summary}_" or ""
            book.add_line(f"**{name}** ({ver}) {summary}\n\t{link}")

        try:
            booklet = book.build()
            if len(booklet) > 1:
                booklet.start()
            else:
                await ctx.send(booklet[0])
        except IndexError:
            await ctx.send("No results were found...", delete_after=10)
示例#13
0
文件: py.py 项目: davfsa/nekosquared
    async def py(self, ctx, member):
        """Gets some help regarding the given Python member, if it exists..."""
        def executor():
            with io.StringIO() as buff:
                with contextlib.redirect_stdout(buff):
                    with contextlib.redirect_stderr(buff):
                        help(member)
                data = buff.getvalue().splitlines()

                return data

        data = await self.run_in_io_executor(executor)

        bb = bookbinding.StringBookBinder(ctx,
                                          max_lines=20,
                                          prefix="```markdown",
                                          suffix="```")

        for line in data:
            line = line.replace("`", "′")
            bb.add_line(line)

        bb.start()
示例#14
0
    async def rextester_group(self, ctx, *, source):
        """
        Attempts to execute some code by detecting the language in the
        syntax highlighting. You MUST format the code using markdown-formatted
        code blocks. Please, please, PLEASE read this before saying "it is
        broken!"

        This provides many more languages than coliru does, however, it is
        mainly untested and will probably break in a lot of places. It also
        has much less functionality. Many languages have to be formatted
        in a specific way or have specific variable names or namespaces.

        Run `rxt help` to view a list of the supported languages, or
        `rxt help <lang>` to view the help for a specific language.
        """
        code_block = tools.code_block_re.search(source)

        if not code_block or len(code_block.groups()) < 2:
            booklet = bookbinding.StringBookBinder(ctx)
            booklet.add_line(
                "I couldn't detect a valid language in your "
                "syntax highlighting... try again by editing "
                "your initial message."
            )
            booklet = booklet.build()
            booklet.start()

            return await tools.listen_to_edit(ctx, booklet)

        # Extract the code
        language, source = code_block.groups()
        language = language.lower()

        if language not in rextester.Language.__members__:
            booklet = bookbinding.StringBookBinder(ctx)
            booklet.add_line(
                "Doesn't look like I support that language. "
                "Run `rtx help` for a list."
            )

            booklet = booklet.build()
            booklet.start()
            return await tools.listen_to_edit(ctx, booklet)

        booklet = bookbinding.StringBookBinder(ctx, prefix="```markdown", suffix="```")

        lang_no = rextester.Language.__members__[language]

        http = await self.acquire_http()
        response = await rextester.execute(http, lang_no, source)

        if response.errors:
            booklet.add_line("> ERRORS:")
            booklet.add_line(response.errors)

        if response.warnings:
            booklet.add_line("> WARNINGS:")
            booklet.add_line(response.warnings)

        if response.result:
            booklet.add_line("> OUTPUT:")
            booklet.add_line(response.result)

        booklet.add_line(response.stats)

        if response.files:
            booklet.add_line(
                f"- {len(response.files)} file(s) included. Bug "
                "Esp to implement this properly!"
            )

        booklet = booklet.build()
        booklet.start()
        await tools.listen_to_edit(ctx, booklet)
示例#15
0
    async def translate(self, ctx, source_lang, dest_lang, *, phrase):
        """
        Required arguments:

        `source_lang` - ISO 3166 country code or name to translate from.
        `dest_lang` - ISO 3166 country code or name to translate to.
        `phrase` - a string to attempt to translate.

        If you specify `\*`, `.` or `auto` for a language, it will detect
        automatically. The default destination language is English.

        To view a list of supported languages, run `n.t list`

        To translate the previous sent message, you can run `n.t ^`.
        """
        if source_lang in ("*", "."):
            source_lang = "auto"
        if dest_lang in ("*", "."):
            dest_lang = "en"

        def fuzzy_wuzzy_match(input_name):
            match = fuzzy.extract_best(input_name, googletrans.LANGUAGES.values())
            if match is None:
                raise NameError("Not a recognised language")
            else:
                return googletrans.LANGCODES[match[0]]

        try:
            acceptable_langs = (*googletrans.LANGUAGES.keys(), "auto")

            source_lang = source_lang.lower()
            dest_lang = dest_lang.lower()
            if source_lang not in acceptable_langs:
                source_lang = fuzzy_wuzzy_match(source_lang)
            if dest_lang not in acceptable_langs:
                dest_lang = fuzzy_wuzzy_match(dest_lang)

            def pool():
                return googletrans.Translator().translate(
                    phrase, dest_lang, source_lang
                )

            result = await self.run_in_io_executor(pool)

            if result is None:
                await ctx.send("No response...", delete_after=10)
            else:
                source = googletrans.LANGUAGES[result.src].title()
                dest = googletrans.LANGUAGES[result.dest].title()

                book = bookbinding.StringBookBinder(ctx, max_lines=10)
                book.add_line(f"_From **{source}** to **{dest}**_", empty_after=True)

                book.add(result.text)

                book = book.build()

                if len(book) > 1:
                    await book.start()
                else:
                    await ctx.send(book.pages[0])

        except Exception as ex:
            await ctx.send(str(ex).title(), delete_after=10)
示例#16
0
    async def man(self, ctx, page, section: str = None, *, grep=None):
        """
        Searches man pages for the given input.

        Usage:

        - `man page` - gets the given page, from any section.
        - `man page * ` - gets the given page, from any section.
        - `man page 2` - gets the given page from section 2.
        - `man page * 'pattern'` - searches all pages for the
            given pattern (Python regex).

        Sections:
           1   Executable programs or shell commands
           2   System calls (functions provided by the kernel)
           3   Library calls (functions within program libraries)
           4   Special files (usually found in /dev)
           5   File formats and conventions eg /etc/passwd
           6   Games
           7   Miscellaneous (including macro packages and conventions),
                e.g. man(7), groff(7)
           8   System administration commands (usually only for root)
           9   Kernel routines [Non standard]
        """
        if section and section != "*" and not section.isdigit():
            raise commands.BadArgument("Expected a * or integer for section.")
        else:
            if section == "*":
                section = None
            if section is not None:
                section = int(section)

        if section is not None and not (1 <= section <= 9):
            return await ctx.send("Section must be between 1 and 9.", delete_after=10)
        elif page.strip().startswith("-"):
            return await ctx.send(
                "Flag-like arguments are not allowed.", delete_after=10
            )
        else:
            section = str(section) if section else None

        common_args = [page] if not section else [str(section), page]

        # Gets the full manpage content which will be huge.
        main_proc = await asyncio.create_subprocess_exec(
            "man",
            *common_args,
            # encoding='utf-8',
            stdout=asyncio.subprocess.PIPE,
            stderr=asyncio.subprocess.DEVNULL,
            stdin=asyncio.subprocess.DEVNULL,
            env={"COLUMNS": "75"},
        )

        main_stream = b"".join([await main_proc.stdout.read()]).decode("utf-8")

        if main_proc.returncode or not len(main_stream.strip()):
            await ctx.send(
                "Error: the man page might not exist on my system.", delete_after=10
            )
        else:
            book = (
                bookbinding.StringBookBinder(ctx)
                .with_prefix("```")
                .with_suffix("```")
                .with_max_lines(30)
            )

            for line in main_stream.splitlines():
                book.add_line(line, dont_alter=True)

            book = book.build()

            # Find the results
            if grep:
                try:
                    regex = re.compile(grep)
                    matching_pages = []

                    for i, page in enumerate(book.pages):
                        if regex.search(page):
                            matching_pages.append(i + 1)
                            continue

                    if len(matching_pages) >= 1:
                        book.set_starting_page_number(matching_pages[0])

                    if len(matching_pages) > 1:
                        # Metadata to be used later by the regex button.
                        setattr(book, "_regex_matches", matching_pages)
                        # Index in the match list
                        setattr(book, "_current_match", 0)

                        # noinspection PyProtectedMember
                        @button.as_button(name="Next match", reaction="⏯")
                        async def next_match(
                            _unused_btn, machine, _unused_react, _unused_user_
                        ):
                            cm = machine._current_match + 1
                            cm %= len(machine._regex_matches)

                            machine._current_match = cm

                            page = machine._regex_matches[cm]
                            await machine.set_page_number(page)

                        book.buttons[next_match.reaction] = next_match

                except Exception as ex:
                    import traceback

                    traceback.print_exc()
                    await ctx.send(ex, delete_after=10)

            book.start()
示例#17
0
    async def coliru(self, ctx, *, arguments):
        """
        Attempts to execute some code by detecting the language in the
        syntax highlighting. You MUST format the code using markdown-formatted
        code blocks. Please, please, PLEASE read this before saying "it is
        broken!"

        Run `cc help` to view a list of the supported languages, or
        `cc help <lang>` to view the help for a specific language.

        If you want to upload more than one file, or you wish to specify a
        custom build routine or flags, see `cc a`.
        """

        code_block = tools.code_block_re.search(arguments)

        if not code_block or len(code_block.groups()) < 2:
            booklet = bookbinding.StringBookBinder(ctx)
            booklet.add_line("I couldn't detect a valid language in your "
                             "syntax highlighting... try again by editing "
                             "your initial message.")
            booklet = booklet.build()
            booklet.start()

            return await tools.listen_to_edit(ctx, booklet)

        # Extract the code
        language, source = code_block.groups()
        language = language.lower()

        try:
            with ctx.typing():
                output = await coliru.targets[language](source)
        except KeyError:
            booklet = bookbinding.StringBookBinder(ctx)
            booklet.add_line(f"That language ({language}) is not yet supported"
                             " by this toolchain. Feel free to edit your"
                             " message if you wish to do something else.")
            booklet = booklet.build()
            booklet.start()

            await tools.listen_to_edit(ctx, booklet)
        else:
            binder = bookbinding.StringBookBinder(ctx,
                                                  prefix="```markdown",
                                                  suffix="```",
                                                  max_lines=25)

            binder.add_line(f"Interpreting as {language!r} source.")

            for line in output.split("\n"):
                binder.add_line(line)

            if ctx.invoked_with in ("ccd", "colirud"):
                await commands.try_delete(ctx)

            if len(output.strip()) == 0:
                await ctx.send("No output...")
                return

            booklet = binder.build()
            booklet.start()

            await tools.listen_to_edit(ctx, booklet)
示例#18
0
    async def advanced(self, ctx, *, arguments):
        """
        This tool enables you to specify more than one file, in any supported
        language on Coliru. It also lets you upload source code files.

        Advanced code execution will first pool all source files into the
        current working directory in the sandbox. It will then proceed to
        execute the build/run command: this is the first argument, and should
        be enclosed in single back-ticks. The execute command can be something
        as simple as `make`, or as complicated as you like. You must invoke
        all of your logic you wish to perform from this argument, however.

        It is worth noting that this build script WILL be executed as Bash
        commands.

        For small programs, it may be as simple as invoking the interpreter
        or compiler, and then running the output. However, if you have much
        more complicated input, it is advisable to invoke something like a
        Makefile and call your logic from that.

        You can upload source code files as attachments, or specify them
        inline. If you wish to specify them inline, you should use the
        following syntax:

        ˋfile_nameˋ

        ˋˋˋpython

        print('some code goes here')

        ˋˋˋ

        This can be repeated as many times as required (within the limits
        provided by Discord, of course).

        ---

        _A working example_: this should give you a feel for exactly how to
        run this tool.

        n.cc a `make`


        `Makefile`

        ```makefile

        all: a.o b.o c.o
            gcc -Wall -Wextra -Werror $^ -lstdc++

        %.o: %.cpp
            g++ -Wall -Wextra -std=c++14 -c $< -o $@

        %.o: %.c
            gcc -Wall -Wextra -Werror -std=c99 -c $< -o $@
        ```
        `a.c`

        ```c

        extern void printer(const char* const);

        extern const char* const message;

        int main(void) { printer(message); }
        ```
        `b.cpp`

        ```cpp
        #include <iostream>
        #include <string>

        extern "C" {
            void printer(const char* const string) {
                std::cout << std::string(string);
            }
        }
        ```
        `c.c`

        ```c

        const char* const message = "HELLO WORLD!!!!!!!!";
        ```
        """

        try:
            # Get the first block as the command.
            command = tools.inline_block_re.search(arguments)

            if not command:
                raise ValueError("No command was given.")

            command = command.groups()[0]

            rest = arguments[len(command):].lstrip()

            # Get files:
            files = []
            for m in tools.file_name_and_block_re.findall(rest):
                files.append(m)

            for attachment in ctx.message.attachments:
                with io.StringIO() as buff:
                    attachment.save(buff)
                    buff = buff.getvalue()

                files.append((attachment.filename, buff))

            if len(files) == 0:
                raise ValueError("Expected one or more source files.")

            # Map to sourcefile objects
            files = [coliru.SourceFile(*file) for file in files]

            # Main file
            main = coliru.SourceFile(".run.sh", command)

            # Generate the coliru API client instance.
            c = coliru.Coliru("bash .run.sh", main, *files, verbose=True)

            output = await c.execute(await self.acquire_http())

            binder = bookbinding.StringBookBinder(ctx,
                                                  prefix="```markdown",
                                                  suffix="```",
                                                  max_lines=25)

            for line in output.split("\n"):
                binder.add_line(line)

            if ctx.invoked_with in ("ccd", "colirud"):
                await commands.try_delete(ctx)

            if len(output.strip()) == 0:
                await ctx.send("No output...")
                return

            booklet = binder.build()
            booklet.start()

            await tools.listen_to_edit(ctx, booklet)

        except IndexError:
            return await ctx.send("Invalid input format.")
        except ValueError as ex:
            return await ctx.send(str(ex))