コード例 #1
0
ファイル: cog.py プロジェクト: Peppermint777/jishaku
    async def jsk_cat(self, ctx: commands.Context, argument: str):
        """
        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 > 50 * (1024**2):
            return await ctx.send(
                f"`{path}`: Cowardly refusing to read a file >50MB.")

        try:
            with open(path, "rb") as file:
                paginator = FilePaginator(file,
                                          line_span=line_span,
                                          max_size=1985)
        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}")

        interface = PaginatorInterface(ctx.bot, paginator, owner=ctx.author)
        await interface.send_to(ctx)
コード例 #2
0
def test_file_paginator():

    base_text = inspect.cleandoc("""
    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    pass  # \u3088\u308d\u3057\u304f
    """)

    # test standard encoding
    pages = FilePaginator(BytesIO(base_text.encode("utf-8"))).pages

    assert len(pages) == 1
    assert pages[0] == f"```python\n{base_text}\n```"

    # test linespan
    pages = FilePaginator(BytesIO(base_text.encode("utf-8")),
                          line_span=(2, 2)).pages

    assert len(pages) == 1
    assert pages[0] == "```python\n# -*- coding: utf-8 -*-\n```"

    # test reception to encoding hint
    base_text = inspect.cleandoc("""
    #!/usr/bin/env python
    # -*- coding: cp932 -*-
    pass  # \u3088\u308d\u3057\u304f
    """)

    pages = FilePaginator(BytesIO(base_text.encode("cp932"))).pages

    assert len(pages) == 1
    assert pages[0] == f"```python\n{base_text}\n```"

    # test without encoding hint
    with pytest.raises(UnicodeDecodeError):
        FilePaginator(BytesIO("\u3088\u308d\u3057\u304f".encode("cp932")))

    # test with wrong encoding hint
    with pytest.raises(UnicodeDecodeError):
        FilePaginator(
            BytesIO("-*- coding: utf-8 -*-\n\u3088\u308d\u3057\u304f".encode(
                "cp932")))

    # test OOB
    with pytest.raises(ValueError):
        FilePaginator(BytesIO("one\ntwo\nthree\nfour".encode('utf-8')),
                      line_span=(-1, 20))
コード例 #3
0
async def test_paginator_interface():
    bot = commands.Bot('?')

    with open(__file__, 'rb') as file:
        paginator = FilePaginator(file, max_size=200)

    interface = PaginatorInterface(bot, paginator)

    assert interface.pages == paginator.pages
    assert interface.page_count == len(paginator.pages)

    assert interface.page_size > 200
    assert interface.page_size < interface.max_page_size

    send_kwargs = interface.send_kwargs

    assert isinstance(send_kwargs, dict)
    assert 'content' in send_kwargs

    content = send_kwargs['content']

    assert isinstance(content, str)
    assert len(content) <= interface.page_size

    assert interface.display_page == 0

    # pages have been closed, so adding a line should make a new page
    old_page_count = interface.page_count

    await interface.add_line('a' * 150)

    assert interface.page_count > old_page_count

    # push the page to the end (rounded into bounds)
    interface.display_page = 999
    old_display_page = interface.display_page

    assert interface.pages == paginator.pages

    # page closed, so create new page
    await interface.add_line('b' * 150)

    # ensure page has followed tail
    assert interface.display_page > old_display_page

    # testing with embed interface
    embed_interface = PaginatorEmbedInterface(bot, paginator)

    assert embed_interface.pages[0] == interface.pages[0]

    send_kwargs = embed_interface.send_kwargs

    assert isinstance(send_kwargs, dict)
    assert 'embed' in send_kwargs

    embed = send_kwargs['embed']

    assert isinstance(embed, discord.Embed)

    description = embed.description

    assert content.startswith(description)

    # check for raise on too large page size
    with pytest.raises(ValueError):
        PaginatorInterface(None, commands.Paginator(max_size=2000))

    # check for raise on not-paginator
    with pytest.raises(TypeError):
        PaginatorInterface(None, 4)

    paginator = commands.Paginator(max_size=100)
    for _ in range(100):
        paginator.add_line("test text")

    # test interfacing
    with utils.mock_ctx(bot) as ctx:
        interface = PaginatorInterface(bot, paginator)

        assert not interface.closed

        await interface.send_to(ctx)

        await asyncio.sleep(0.1)
        await interface.add_line("test text")

        assert interface.page_count > 1
        assert not interface.closed

        interface.message.id = utils.sentinel()

        current_page = interface.display_page

        payload = {
            'message_id': interface.message.id,
            'user_id': ctx.author.id,
            'channel_id': ctx.channel.id,
            'guild_id': ctx.guild.id
        }

        # push right button
        emoji = discord.PartialEmoji(
            animated=False,
            name="\N{BLACK RIGHT-POINTING TRIANGLE}",
            id=None
        )
        bot.dispatch(
            'raw_reaction_add',
            discord.RawReactionActionEvent(payload, emoji, 'REACTION_ADD')
            if discord.version_info >= (1, 3) else
            discord.RawReactionActionEvent(payload, emoji)
        )

        await asyncio.sleep(0.1)

        assert interface.display_page > current_page
        assert not interface.closed

        current_page = interface.display_page

        # push left button
        emoji = discord.PartialEmoji(
            animated=False,
            name="\N{BLACK LEFT-POINTING TRIANGLE}",
            id=None
        )
        bot.dispatch(
            'raw_reaction_add',
            discord.RawReactionActionEvent(payload, emoji, 'REACTION_ADD')
            if discord.version_info >= (1, 3) else
            discord.RawReactionActionEvent(payload, emoji)
        )

        await asyncio.sleep(0.1)

        assert interface.display_page < current_page
        assert not interface.closed

        # push last page button
        emoji = discord.PartialEmoji(
            animated=False,
            name="\N{BLACK RIGHT-POINTING DOUBLE TRIANGLE WITH VERTICAL BAR}",
            id=None
        )
        bot.dispatch(
            'raw_reaction_add',
            discord.RawReactionActionEvent(payload, emoji, 'REACTION_ADD')
            if discord.version_info >= (1, 3) else
            discord.RawReactionActionEvent(payload, emoji)
        )

        await asyncio.sleep(0.1)

        assert interface.display_page == interface.page_count - 1
        assert not interface.closed

        # push first page button
        emoji = discord.PartialEmoji(
            animated=False,
            name="\N{BLACK LEFT-POINTING DOUBLE TRIANGLE WITH VERTICAL BAR}",
            id=None
        )
        bot.dispatch(
            'raw_reaction_add',
            discord.RawReactionActionEvent(payload, emoji, 'REACTION_ADD')
            if discord.version_info >= (1, 3) else
            discord.RawReactionActionEvent(payload, emoji)
        )

        await asyncio.sleep(0.1)

        assert interface.display_page == 0
        assert not interface.closed

        # push close button
        emoji = discord.PartialEmoji(
            animated=False,
            name="\N{BLACK SQUARE FOR STOP}",
            id=None
        )
        bot.dispatch(
            'raw_reaction_add',
            discord.RawReactionActionEvent(payload, emoji, 'REACTION_ADD')
            if discord.version_info >= (1, 3) else
            discord.RawReactionActionEvent(payload, emoji)
        )

        await asyncio.sleep(0.1)

        assert interface.closed
        ctx.send.coro.return_value.delete.assert_called_once()

    # test resend, no delete
    with utils.mock_ctx(bot) as ctx:
        interface = PaginatorInterface(bot, paginator)

        assert not interface.closed

        await interface.send_to(ctx)

        await asyncio.sleep(0.1)
        await interface.add_line("test text")

        assert interface.page_count > 1
        assert not interface.closed

        # resend
        await interface.send_to(ctx)

        await asyncio.sleep(0.1)
        await interface.add_line("test text")

        ctx.send.coro.return_value.delete.assert_not_called()

        interface.task.cancel()
        await asyncio.sleep(0.1)

        assert interface.closed

    # test resend, delete
    with utils.mock_ctx(bot) as ctx:
        interface = PaginatorInterface(bot, paginator, delete_message=True)

        assert not interface.closed

        await interface.send_to(ctx)

        await asyncio.sleep(0.1)
        await interface.add_line("test text")

        assert interface.page_count > 1
        assert not interface.closed

        # resend
        await interface.send_to(ctx)

        await asyncio.sleep(0.1)
        await interface.add_line("test text")

        ctx.send.coro.return_value.delete.assert_called_once()

        interface.task.cancel()
        await asyncio.sleep(0.1)

        assert interface.closed
コード例 #4
0
    def test_paginator_interface(self):
        bot = commands.Bot('?')

        with open(__file__, 'rb') as fp:
            paginator = FilePaginator(fp, max_size=200)

        interface = PaginatorInterface(bot, paginator)

        self.assertEqual(interface.pages, paginator.pages)
        self.assertEqual(interface.page_count, len(paginator.pages))

        self.assertGreater(interface.page_size, 200)
        self.assertLess(interface.page_size, interface.max_page_size)

        send_kwargs = interface.send_kwargs

        self.assertIsInstance(send_kwargs, dict)
        self.assertIn('content', send_kwargs)

        content = send_kwargs['content']

        self.assertIsInstance(content, str)
        self.assertLessEqual(len(content), interface.page_size)

        self.assertEqual(interface.display_page, 0)

        # pages have been closed, so adding a line should make a new page
        old_page_count = interface.page_count

        bot.loop.run_until_complete(interface.add_line('a' * 150))

        self.assertGreater(interface.page_count, old_page_count)

        # push the page to the end (rounded into bounds)
        interface.display_page = 999
        old_display_page = interface.display_page

        self.assertEqual(interface.pages, paginator.pages)

        # page closed, so create new page
        bot.loop.run_until_complete(interface.add_line('b' * 150))

        # ensure page has followed tail
        self.assertGreater(interface.display_page, old_display_page)

        # testing with embed interface
        embed_interface = PaginatorEmbedInterface(bot, paginator)

        self.assertEqual(embed_interface.pages[0], interface.pages[0])

        send_kwargs = embed_interface.send_kwargs

        self.assertIsInstance(send_kwargs, dict)
        self.assertIn('embed', send_kwargs)

        embed = send_kwargs['embed']

        self.assertIsInstance(embed, discord.Embed)

        description = embed.description

        self.assertTrue(content.startswith(description))

        # check for raise on too large page size
        raised = False

        try:
            PaginatorInterface(None, commands.Paginator(max_size=2000))
        except ValueError:
            raised = True

        self.assertTrue(raised)

        # check for raise on not-paginator
        raised = False

        try:
            PaginatorInterface(None, 4)
        except TypeError:
            raised = True

        self.assertTrue(raised)

        bot.loop.run_until_complete(bot.close())
コード例 #5
0
    def test_file_paginator(self):

        base_text = inspect.cleandoc("""
        #!/usr/bin/env python
        # -*- coding: utf-8 -*-
        pass  # \u3088\u308d\u3057\u304f
        """)

        # test standard encoding
        pages = FilePaginator(BytesIO(base_text.encode("utf-8"))).pages

        self.assertEqual(len(pages), 1)
        self.assertEqual(pages[0], f"```python\n{base_text}\n```")

        # test linespan
        pages = FilePaginator(BytesIO(base_text.encode("utf-8")),
                              line_span=(2, 2)).pages

        self.assertEqual(len(pages), 1)
        self.assertEqual(pages[0], f"```python\n# -*- coding: utf-8 -*-\n```")

        # test reception to encoding hint
        base_text = inspect.cleandoc("""
        #!/usr/bin/env python
        # -*- coding: cp932 -*-
        pass  # \u3088\u308d\u3057\u304f
        """)

        pages = FilePaginator(BytesIO(base_text.encode("cp932"))).pages

        self.assertEqual(len(pages), 1)
        self.assertEqual(pages[0], f"```python\n{base_text}\n```")

        # test without encoding hint
        raised = False

        try:
            FilePaginator(BytesIO("\u3088\u308d\u3057\u304f".encode("cp932")))
        except UnicodeDecodeError:
            raised = True

        self.assertTrue(raised)

        # test with wrong encoding hint
        raised = False

        try:
            FilePaginator(
                BytesIO(
                    "-*- coding: utf-8 -*-\n\u3088\u308d\u3057\u304f".encode(
                        "cp932")))
        except UnicodeDecodeError:
            raised = True

        self.assertTrue(raised)

        # test OOB
        raised = False

        try:
            FilePaginator(BytesIO("one\ntwo\nthree\nfour".encode('utf-8')),
                          line_span=(-1, 20))
        except ValueError:
            raised = True

        self.assertTrue(raised)