예제 #1
0
    def __init__(self, fp, line_span=None, language_hints=(), **kwargs):
        language = ''

        for hint in language_hints:
            language = get_language(hint)

            if language:
                break

        if not language:
            try:
                language = get_language(fp.name)
            except AttributeError:
                pass

        content, _, file_language = guess_file_traits(fp.read())

        language = file_language or language
        lines = content.split('\n')

        super().__init__(prefix=f'```{language}', suffix='```', **kwargs)

        if line_span:
            line_span = sorted(line_span)

            if min(line_span) < 1 or max(line_span) > len(lines):
                raise ValueError("Linespan goes out of bounds.")

            lines = lines[line_span[0] - 1:line_span[1]]

        for line in lines:
            self.add_line(line)
예제 #2
0
    async def jsk_cat(self, ctx: commands.Context, argument: str):  # pylint: disable=too-many-locals
        """
        Read out a file, using syntax highlighting if detected.

        Lines and linespans are supported by adding '#L12' or '#L12-14' etc to the end of the filename.
        """

        match = self.__cat_line_regex.search(argument)

        if not match:  # should never happen
            return await ctx.send("Couldn't parse this input.")

        path = match.group(1)

        line_span = None

        if match.group(2):
            start = int(match.group(2))
            line_span = (start, int(match.group(3) or start))

        if not os.path.exists(path) or os.path.isdir(path):
            return await ctx.send(f"`{path}`: No file by that name.")

        size = os.path.getsize(path)

        if size <= 0:
            return await ctx.send(f"`{path}`: Cowardly refusing to read a file with no size stat"
                                  f" (it may be empty, endless or inaccessible).")

        if size > 128 * (1024 ** 2):
            return await ctx.send(f"`{path}`: Cowardly refusing to read a file >128MB.")

        try:
            with open(path, "rb") as file:
                if use_file_check(ctx, size):
                    if line_span:
                        content, *_ = guess_file_traits(file.read())

                        lines = content.split('\n')[line_span[0] - 1:line_span[1]]

                        await ctx.send(file=discord.File(
                            filename=pathlib.Path(file.name).name,
                            fp=io.BytesIO('\n'.join(lines).encode('utf-8'))
                        ))
                    else:
                        await ctx.send(file=discord.File(
                            filename=pathlib.Path(file.name).name,
                            fp=file
                        ))
                else:
                    paginator = WrappedFilePaginator(file, line_span=line_span, max_size=1985)
                    interface = PaginatorInterface(ctx.bot, paginator, owner=ctx.author)
                    await interface.send_to(ctx)
        except UnicodeDecodeError:
            return await ctx.send(f"`{path}`: Couldn't determine the encoding of this file.")
        except ValueError as exc:
            return await ctx.send(f"`{path}`: Couldn't read this file, {exc}")