Example #1
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)

                            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)
Example #2
0
    async def jsk_unload(self, ctx: commands.Context,
                         *extensions: ExtensionConverter):
        """
        Unloads the given extension names.

        Reports any extensions that failed to unload.
        """

        paginator = WrappedPaginator(prefix="", suffix="")
        icon = "\N{OUTBOX TRAY}"

        for extension in itertools.chain(*extensions):
            try:
                self.bot.unload_extension(extension)
            except Exception as exc:  # pylint: disable=broad-except
                traceback_data = "".join(
                    traceback.format_exception(type(exc), exc,
                                               exc.__traceback__, 1))

                paginator.add_line(
                    f"{icon}\N{WARNING SIGN} `{extension}`\n```py\n{traceback_data}\n```",
                    empty=True,
                )
            else:
                paginator.add_line(f"{icon} `{extension}`", empty=True)

        for page in paginator.pages:
            await ctx.send(page)
Example #3
0
	async def mcsteams(self, ctx):
		async with aiohttp.ClientSession() as s:
			async with s.get(f'https://minecraftsaturdays.net/api/roster/{self.season}/{self.week}') as r:
				p = await r.text()
				p = json.loads(p)
				teams = p['teams']
		t = []
		for team in teams:
			team["score"] = 0
			for x in team["players"]:
				team["score"] += x["score"]
			players = [f'[{x["name"]}]({x.get("link", "https://minecraftsaturdays.net/")})\nтнР Points: {x["score"]}' for x in team["players"]]
			players = "\n".join(players)
			t.append({
				'text': f'**Team {teams.index(team) + 1}:**\n{players}\n\nЁЯПЕ Wins: {team["players"][0]["wins"]}\nтнР Total Points: {team["score"]}\n',
				'score': team["score"]
			})
		t = sorted(t, key=lambda t: t["score"])
		t.reverse()
		paginator = WrappedPaginator(prefix='**Minecraft Saturdays Teams**', suffix='', max_size=650)
		for team in t:
			paginator.add_line(team["text"])
		embed = discord.Embed(colour=ctx.author.color, timestamp=datetime.datetime.utcnow())
		footer = {'text': 'https://minecraftsaturdays.net/', 'icon_url': 'https://cdn.discordapp.com/icons/618826436299456533/6dfe2d224d8d919cac6bd71dcf7b0955.png'}
		interface = PaginatorEmbedInterface(ctx.bot, paginator, owner=ctx.author, _embed=embed, _footer=footer)
		await interface.send_to(ctx)
Example #4
0
    async def git(self, ctx: commands.Context, pull_push, *, commit_msg=None):
        """
        Executes git statements in the system shell.

        This uses the system shell as defined in $SHELL, or `/bin/bash` otherwise.
        Execution can be cancelled by closing the paginator.
        """
        if pull_push == "push":
            shellcmd = f'sudo git add .&&sudo git commit -m "{commit_msg}"&&sudo git push'
        if pull_push == "pull":
            shellcmd = 'sudo git pull'
        if pull_push not in ['pull', 'push']: 
            return await ctx.send("Invalid option given")

        async with ReplResponseReactor(ctx.message):
            paginator = WrappedPaginator(prefix="```sh", max_size=1985)
            paginator.add_line(f"$ git {pull_push}\n")

            interface = PaginatorInterface(ctx.bot, paginator, owner=ctx.author)
            self.bot.loop.create_task(interface.send_to(ctx))

            if commit_msg is None:
                commit_msg = "File changes"

            with ShellReader(shellcmd) as reader:
                async for line in reader:
                    if interface.closed:
                        return
                    await interface.add_line(line)
    async def git(self, ctx, pull_push, *, message=None):
        """
        Executes git statements in the system shell.
        This uses the system shell as defined in $SHELL, or `/bin/bash` otherwise.
        Execution can be cancelled by closing the paginator.
        """
        message = message if message is not None else "Updated files."

        if pull_push == "push":
            shellcmd = f'sudo git add .&&sudo git commit -m "{message}"&&sudo git push'
        elif pull_push == "pull":
            shellcmd = 'sudo git pull'
        else:
            return await ctx.send("Invalid option given")

        async with ReplResponseReactor(ctx.message):
            paginator = WrappedPaginator(prefix="```sh", max_size=1985)
            paginator.add_line(f"$ git {pull_push}\n")

            interface = PaginatorInterface(ctx.bot, paginator, owner=ctx.author)
            self.bot.loop.create_task(interface.send_to(ctx))

            with ShellReader(shellcmd) as reader:
                async for line in reader:
                    if interface.closed:
                        return
                    await interface.add_line(line)
Example #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)
Example #7
0
    async def source(self, ctx, *, command_name: str):
        """
        Displays the source code for a command.
        """

        command = self.bot.get_command(command_name)
        if not command:
            return await ctx.send(f"Couldn't find command `{command_name}`.")

        try:
            source_lines, _ = inspect.getsourcelines(command.callback)
        except (TypeError, OSError):
            return await ctx.send(
                f"Was unable to retrieve the source for `{command}` for some reason."
            )

        # getsourcelines for some reason returns WITH line endings
        source_lines = "".join(source_lines).split("\n")

        paginator = WrappedPaginator(prefix="```py",
                                     suffix="```",
                                     max_size=1985)
        for num, line in enumerate(source_lines, start=1):
            paginator.add_line(f"{str(num)} {ctx.escape(line)}")

        interface = PaginatorInterface(ctx.bot, paginator, owner=ctx.author)
        await interface.send_to(ctx)
Example #8
0
    async def jsk_shell(self, ctx: commands.Context, *,
                        argument: codeblock_converter):
        """
        Executes statements in the system shell.

        This uses the system shell as defined in $SHELL, or `/bin/bash` otherwise.
        Execution can be cancelled by closing the paginator.
        """

        async with ReplResponseReactor(ctx.message):
            with self.submit(ctx):
                with ShellReader(argument.content) as reader:
                    prefix = "```" + reader.highlight

                    paginator = WrappedPaginator(prefix=prefix, max_size=1975)
                    paginator.add_line(f"{reader.ps1} {argument.content}\n")

                    interface = PaginatorInterface(ctx.bot,
                                                   paginator,
                                                   owner=ctx.author)
                    self.bot.loop.create_task(interface.send_to(ctx))

                    async for line in reader:
                        if interface.closed:
                            return
                        await interface.add_line(line)

                await interface.add_line(
                    f"\n[status] Return code {reader.close_code}")
Example #9
0
    async def jsk_load(self, ctx: commands.Context,
                       *extensions: ExtensionConverter):
        """
        Loads or reloads the given extension names.

        Reports any extensions that failed to load.
        """

        paginator = WrappedPaginator(prefix="", suffix="")

        for extension in itertools.chain(*extensions):
            method, icon = ((
                self.bot.reload_extension,
                "\N{CLOCKWISE RIGHTWARDS AND LEFTWARDS OPEN CIRCLE ARROWS}",
            ) if extension in self.bot.extensions else
                            (self.bot.load_extension, "\N{INBOX TRAY}"))

            try:
                method(extension)
            except Exception as exc:  # pylint: disable=broad-except
                traceback_data = "".join(
                    traceback.format_exception(type(exc), exc,
                                               exc.__traceback__, 1))

                paginator.add_line(
                    f"{icon}\N{WARNING SIGN} `{extension}`\n```py\n{traceback_data}\n```",
                    empty=True,
                )
            else:
                paginator.add_line(f"{icon} `{extension}`", empty=True)

        for page in paginator.pages:
            await ctx.send(page)
Example #10
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))

            # 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:
                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)
Example #11
0
 async def emoji(self, ctx, *, search: str = None):
     lists = []
     paginator = WrappedPaginator(max_size=500, prefix="", suffix="")
     if search != None:
         emojis = finder(search,
                         self.bot.emojis,
                         key=lambda i: i.name,
                         lazy=False)
         if emojis == []:
             return await ctx.send("no emoji found")
         for i in emojis:
             if i.animated == True:
                 lists.append(f"{str(i)} `<a:{i.name}:{i.id}>`")
             else:
                 lists.append(f"{str(i)} `<:{i.name}:{i.id}>`")
         paginator.add_line("\n".join(lists))
         interface = PaginatorInterface(ctx.bot,
                                        paginator,
                                        owner=ctx.author)
         return await interface.send_to(ctx)
     for i in self.bot.emojis:
         if i.animated == True:
             lists.append(f"{str(i)} `<a:{i.name}:{i.id}>`")
         else:
             lists.append(f"{str(i)} `<:{i.name}:{i.id}>`")
     paginator.add_line("\n".join(lists))
     interface = PaginatorInterface(ctx.bot, paginator, owner=ctx.author)
     await interface.send_to(ctx)
Example #12
0
	async def role(self, ctx, *, role: Role = None):
		if not role:
			role = ctx.author.top_role
		embed = discord.Embed(colour=role.color if role.color != discord.Color.default() else ctx.author.color, timestamp=datetime.datetime.now(datetime.timezone.utc))
		embed.add_field(name="» Name", value=role.name, inline=False)
		embed.add_field(name="» ID", value=role.id, inline=False)
		embed.add_field(name="» Mention", value=f'`{role.mention}`', inline=False)
		rgbcolor = role.color.to_rgb()
		hexcolor = rgb2hex(role.color.r, role.color.g, role.color.b).replace('##', '#')
		embed.add_field(name="» Hoisted?", value='Yes' if role.hoist else 'No')
		embed.add_field(name="» Mentionable?", value='Yes' if role.mentionable else 'No')
		embed.add_field(name="» Color", value=f'RGB: {rgbcolor}\nHEX: {hexcolor}')
		perms = []
		if not role.permissions.administrator:
			for perm, value in role.permissions:
				if value and perm in permissions:
					perms.append(permissions[perm])
			if perms:
				embed.add_field(name="» Key Permissions", value=', '.join(perms), inline=False)
		else:
			embed.add_field(name="» Permissions", value='Administrator', inline=False)
		await ctx.send(embed=embed)
		is_cached = len(ctx.guild.members) / ctx.guild.member_count
		if role.members and is_cached > 0.98:
			paginator = WrappedPaginator(prefix='', suffix='', max_size=250)
			for member in role.members:
				paginator.add_line(member.mention)
			membed = discord.Embed(
				colour=role.color if role.color != discord.Color.default() else ctx.author.color,
				timestamp=datetime.datetime.now(datetime.timezone.utc),
				title=f'Members [{len(role.members):,d}]'
			)
			interface = PaginatorEmbedInterface(ctx.bot, paginator, owner=ctx.author, _embed=membed)
			await interface.send_to(ctx)
Example #13
0
    async def a(self, ctx: commands.Context, *, command_name: str):
        """
        Displays the source code for a command.
        """
        import inspect

        command = self.bot.get_command(command_name)
        if not command:
            return await ctx.send(f"Couldn't find command `{command_name}`.")

        try:
            source_lines, _ = inspect.getsourcelines(command.callback)
        except (TypeError, OSError):
            return await ctx.send(
                f"Was unable to retrieve the source for `{command}` for some reason."
            )

        # getsourcelines for some reason returns WITH line endings
        source_lines = ''.join(source_lines).split('\n')

        paginator = WrappedPaginator(prefix='```py',
                                     suffix='```',
                                     max_size=1985)
        for line in source_lines:
            paginator.add_line(line)

        interface = PaginatorInterface(ctx.bot, paginator, owner=ctx.author)
        await interface.send_to(ctx)
Example #14
0
 async def listguilds(self, ctx):
     if not self.bot.isadmin(ctx.author):
         return await ctx.error('no')
     data = [[
         'Name', 'ID', 'Members', 'Channels', 'Boosts', 'Shard', 'Public'
     ]]
     for guild in sorted(self.bot.guilds,
                         key=lambda g: len(g.members),
                         reverse=True):
         data.append([
             shorten(guild.name), guild.id,
             format(len(guild.members), ',d'),
             len(guild.channels), guild.premium_subscription_count,
             guild.shard_id, 'PUBLIC' in guild.features
         ])
     table = AsciiTable(data)
     header = table.table.split('\n')[:3]
     paginator = WrappedPaginator(prefix='```\n' + '\n'.join(header),
                                  suffix='```',
                                  max_size=1950)
     for ln in table.table.split('\n'):
         if ln not in header:
             paginator.add_line(ln)
     interface = PaginatorInterface(ctx.bot, paginator, owner=ctx.author)
     return await interface.send_to(ctx)
Example #15
0
 async def lyrics(self, ctx, *, query: typing.Union[Member, str] = None):
     lyrics = None
     query = ctx.author if not query else query
     if type(query) == discord.Member:
         for activity in query.activities:
             if type(activity) == discord.Spotify:
                 lyrics = await self.bot.ksoft.lyrics_search(
                     f'{", ".join(activity.artists)} {activity.title}')
         if not lyrics:
             raise commands.BadArgument(
                 'That member isn\'t listening to Spotify!')
     elif type(query) == discord.User:
         raise commands.BadArgument('Missing search query')
     else:
         lyrics = await self.bot.ksoft.lyrics_search(query)
     if len(lyrics.results) < 1:
         return await ctx.error('No lyrics found')
     lyrics: ksoftapi.LyricsSearchResp = lyrics.results[0]
     paginator = WrappedPaginator(prefix='', suffix='', max_size=1000)
     for line in lyrics.lyrics.split('\n'):
         paginator.add_line(line)
     embed = discord.Embed(color=ctx.author.color,
                           title=f'{lyrics.name} by {lyrics.artist}',
                           url=lyrics.url)
     footer = {
         'text': 'Powered by KSoft.Si API',
         'icon_url': 'https://cdn.ksoft.si/images/Logo128.png'
     }
     interface = PaginatorEmbedInterface(ctx.bot,
                                         paginator,
                                         owner=ctx.author,
                                         _embed=embed,
                                         _footer=footer)
     await interface.send_to(ctx)
Example #16
0
 async def lyrics(self, ctx, *, query: str = None):
     lyrics = None
     if not query:
         return await ctx.error('Missing search query')
     else:
         lyrics = await self.bot.ksoft.lyrics_search(query)
     if not lyrics or len(lyrics.results) < 1:
         return await ctx.error('No lyrics found')
     lyrics = lyrics.results[0]
     paginator = WrappedPaginator(prefix='', suffix='', max_size=1000)
     for line in lyrics.lyrics.split('\n'):
         paginator.add_line(line)
     embed = discord.Embed(color=ctx.author.color,
                           title=f'{lyrics.name} by {lyrics.artist}',
                           url=lyrics.url)
     embed.set_thumbnail(url=lyrics.album_art)
     footer = {
         'text': 'Powered by KSoft.Si API',
         'icon_url': 'https://cdn.ksoft.si/images/Logo128.png'
     }
     interface = PaginatorEmbedInterface(ctx.bot,
                                         paginator,
                                         owner=ctx.author,
                                         _embed=embed,
                                         _footer=footer)
     await interface.send_to(ctx)
Example #17
0
def test_wrapped_paginator():
    paginator = WrappedPaginator(max_size=200)
    paginator.add_line("abcde " * 50)
    assert len(paginator.pages) == 2

    paginator = WrappedPaginator(max_size=200, include_wrapped=False)
    paginator.add_line("abcde " * 50)
    assert len(paginator.pages) == 2
Example #18
0
 async def nmcnames(self, ctx, name: str):
     async with aiohttp.ClientSession() as s:
         async with s.get(f'https://namemc.com/{name}') as r:
             content = await r.text()
     namecount, names, dates = await getnames(content, name)
     if type(namecount) == dict:
         data = namecount
         embed = discord.Embed(title=f'Name information for {name}',
                               color=ctx.author.color,
                               timestamp=datetime.datetime.utcnow())
         if 'when' in data:
             embed.add_field(name='Availability Status',
                             value=data['when'],
                             inline=False)
         if 'searches' in data:
             embed.add_field(name='Searches',
                             value=data['searches'],
                             inline=False)
         if 'toa' in data and data['toa'] != 'tomorrow':
             date = dateutil.parser.parse(data['toa'])
             date = datetime.datetime.strftime(date,
                                               '%d/%m/%Y @ %I:%M:%S %p')
             embed.add_field(name='Time of Availability',
                             value=date,
                             inline=False)
         if 'remain' in data and data['remain'] != 'an eternity':
             embed.add_field(name='Time Remaining',
                             value=data['remain'],
                             inline=False)
         await ctx.send(embed=embed)
     if namecount and names and dates:
         yeet = True
     else:
         raise commands.CommandError(
             'I was unable to parse the list of names for that user')
     namelist = []
     reqname = name
     paginator = WrappedPaginator(prefix='', suffix='', max_size=2000)
     for i, v in enumerate(namecount):
         count = namecount[i]
         namemd = names[i]
         name = discord.utils.escape_markdown(names[i])
         name = f"[{name}](https://namemc.com/name/{name} 'Click here to go to the NameMC page for {namemd}')"
         try:
             date = dateutil.parser.parse(dates[i])
             date = datetime.datetime.strftime(date,
                                               '%d/%m/%Y @ %I:%M:%S %p')
         except IndexError:
             date = 'First Name'
         paginator.add_line(f'**{count}** {name}   {date}')
     embed = discord.Embed(title=f'Name history for {reqname}',
                           color=ctx.author.color,
                           timestamp=datetime.datetime.utcnow())
     interface = PaginatorEmbedInterface(ctx.bot,
                                         paginator,
                                         owner=ctx.author,
                                         _embed=embed)
     await interface.send_to(ctx)
Example #19
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)
Example #20
0
 async def cfstatus(self, ctx):
     colors = {
         'none': ctx.author.color,
         'minor': discord.Color.gold(),
         'major': discord.Color.orange(),
         'critical': discord.Color.red(),
         'maintenance': discord.Color.blue()
     }
     emoji = {
         'operational': '<:operational:685538400639385649>',
         'degraded_performance':
         '<:degraded_performance:685538400228343808>',
         'partial_outage': '<:partial_outage:685538400555499675>',
         'major_outage': '<:major_outage:685538400639385706>',
         'under_maintenance': '<:maintenance:685538400337395743>'
     }
     sroute = Route('GET', '/summary.json')
     iroute = Route('GET', '/incidents.json')
     try:
         summary = await self.bot.http.cfstatus.request(sroute)
         incidents = await self.bot.http.cfstatus.request(iroute)
     except Exception:
         return await ctx.error(f'Failed to fetch Cloudflare status')
     # Cloudflare is a special little snowflake with a shit ton of compontents, too many for the embed description
     paginator = WrappedPaginator(prefix='', suffix='', max_size=1980)
     groups = {}
     for c in [c for c in summary['components'] if c['group_id']]:
         if c['status'] == 'operational':
             continue
         if c['group_id'] not in groups:
             groups[c['group_id']] = [c]
         else:
             groups[c['group_id']].append(c)
     for c in [c for c in summary['components'] if not c['group_id']]:
         paginator.add_line(
             f'├{emoji[c["status"]]} **{c["name"]}**: {c["status"].replace("_", " ").title()}'
         )
         for s in groups.get(c['id'], []):
             paginator.add_line(
                 f'├─{emoji[s["status"]]} **{s["name"]}**: {s["status"].replace("_", " ").title()}'
             )
     embed = discord.Embed(color=colors[str(
         summary['status']['indicator'])],
                           title=summary['status']['description'],
                           timestamp=datetime.datetime.utcnow())
     incident = incidents['incidents'][0]
     embed.add_field(
         name='Latest Incident',
         value=
         f'[{incident["name"]}]({incident["shortlink"]})\nStatus: **{incident["status"].capitalize()}**'
     )
     interface = PaginatorEmbedInterface(ctx.bot,
                                         paginator,
                                         owner=ctx.author,
                                         _embed=embed)
     await interface.send_to(ctx)
Example #21
0
 async def paginate(self, *words, destination=None):
     embed = discord.Embed(color=discord.Colour.blurple())
     pg = WrappedPaginator(prefix="", suffix="", max_size=2048)
     for line in words:
         pg.add_line(line)
     inf = PaginatorEmbedInterface(self.bot,
                                   pg,
                                   owner=self.author,
                                   embed=embed)
     await inf.send_to(destination or self)
Example #22
0
	async def reminders(self, ctx):
		mine = sorted(self.reminders.get(ctx.author.id, []), key=lambda r: r['for'])
		if not mine:
			return await ctx.error('You have no reminders.')
		paginator = WrappedPaginator(prefix='', suffix='', max_size=1980)
		for i, r in enumerate(mine):
			forwhen = datetime.datetime.fromtimestamp(r['for'], datetime.timezone.utc).strftime('%b %-d %Y @ %I:%M %p')
			delta = humanfriendly.format_timespan(datetime.datetime.fromtimestamp(r['for'], datetime.timezone.utc) - datetime.datetime.now(datetime.timezone.utc), max_units=2)
			paginator.add_line(f'[{i + 1}] {r["reminder"]} - {forwhen} ({delta})')
		interface = PaginatorEmbedInterface(ctx.bot, paginator, owner=ctx.author)
		return await interface.send_to(ctx)
Example #23
0
    async def jsk_python_result_handling(self, ctx: commands.Context, result):  # pylint: disable=too-many-return-statements
        """
        Determines what is done with a result when it comes out of jsk py.
        This allows you to override how this is done without having to rewrite the command itself.
        What you return is what gets stored in the temporary _ variable.
        """

        if isinstance(result, discord.Message):
            return await ctx.send(f"<Message <{result.jump_url}>>")

        if isinstance(result, discord.File):
            return await ctx.send(file=result)

        if isinstance(result, discord.Embed):
            return await ctx.send(embed=result)

        if isinstance(result, PaginatorInterface):
            return await result.send_to(ctx)

        if not isinstance(result, str):
            # repr all non-strings
            result = repr(result)

        # Eventually the below handling should probably be put somewhere else
        if len(result) <= 2000:
            if result.strip() == '':
                result = "\u200b"

            return await ctx.send(
                result.replace(self.bot.http.token, "[token omitted]"),
                allowed_mentions=discord.AllowedMentions.none())

        if use_file_check(ctx,
                          len(result)):  # File "full content" preview limit
            # 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
            return await ctx.send(file=discord.File(
                filename="output.py", fp=io.BytesIO(result.encode('utf-8'))))

        # 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)
        return await interface.send_to(ctx)
Example #24
0
 async def eval(self, ctx, *, code: str):
     env = {
         "ctx":
         ctx,
         "author":
         ctx.author,
         "message":
         ctx.message,
         "guild":
         ctx.guild,
         "bot":
         self.bot,
         "reference":
         ctx.message.reference,
         "resolved":
         ctx.message.reference.resolved if ctx.message.reference else None,
     }
     env.update(globals())
     imports = "import asyncio\n"
     "import discord\nfrom discord.ext import commands\nimport aiohttp\n"
     body = "async def func():\n" + textwrap.indent(imports + code, "    ")
     try:
         import_expression.exec(body, env, locals())
     except Exception as e:
         etype = type(e)
         trace = e.__traceback__
         lines = traceback.format_exception(etype, e, trace)
         paginator = WrappedPaginator(max_size=500,
                                      prefix="A weird error occured```py",
                                      suffix="```")
         paginator.add_line("".join(lines))
         interface = PaginatorInterface(ctx.bot,
                                        paginator,
                                        owner=ctx.author)
         return await interface.send_to(ctx)
     try:
         maybe_coro = locals()["func"]()
         if inspect.isasyncgen(maybe_coro):
             async for i in maybe_coro:
                 await ctx.send(i)
             return
         thing = await maybe_coro
         if thing:
             if isinstance(thing, discord.Embed):
                 return await ctx.send(embed=thing)
             if isinstance(thing, discord.File):
                 return await ctx.send(file=thing)
             else:
                 await ctx.send(thing)
     except Exception as e:
         await ctx.send(e)
Example #25
0
 async def info(self, ctx, video: str):
     if findvideo(video):
         video = findvideo(video)
     videoinfo = await self.loop.run_in_executor(None,
                                                 func=functools.partial(
                                                     self.video_info,
                                                     video))
     try:
         videoinfo = videoinfo['items'][0]
     except (KeyError, IndexError):
         return await ctx.error(
             f'Couldn\'t find a video. Please provide a valid YouTube video URL'
         )
     title = videoinfo['snippet']['title']
     vid = videoinfo['id']
     author = videoinfo['snippet']['channelTitle']
     authorid = videoinfo['snippet']['channelId']
     published = videoinfo['snippet']['publishedAt'].replace(
         'T', ' ').split('.')[0]
     duration = videoinfo['contentDetails']['duration'].replace(
         'PT', '').replace('H',
                           ' Hrs ').replace('M',
                                            ' Mins ').replace('S', 'Secs')
     description = videoinfo['snippet']['description']
     paginator = WrappedPaginator(
         prefix='```\nDescription (Use controls to change page)\n',
         suffix='```',
         max_size=1895)
     for line in description.split('\n'):
         paginator.add_line(line)
     views = format(
         int(videoinfo.get('statistics', {}).get('viewCount', 0)), ',d')
     likes = format(
         int(videoinfo.get('statistics', {}).get('likeCount', 0)), ',d')
     dislikes = format(
         int(videoinfo.get('statistics', {}).get('dislikeCount', 0)), ',d')
     comments = format(
         int(videoinfo.get('statistics', {}).get('commentCount', 0)), ',d')
     embed = discord.Embed(title=f"Video info for {video}",
                           color=ctx.author.color,
                           timestamp=datetime.datetime.utcnow())
     embed.add_field(
         name=videoinfo["snippet"]["title"],
         value=
         f"» Link: [{title}](https://youtu.be/{vid} 'Click here to watch the video')\n» Author: [{author}](https://youtube.com/channel/{authorid} 'Click here to checkout {author} channel')\n» Published: {published}\n» Views: {views}\n» Likes: {likes}\n» Dislikes: {dislikes}\n» Comments: {comments}",
         inline=False)
     interface = PaginatorEmbedInterface(ctx.bot,
                                         paginator,
                                         owner=ctx.author,
                                         _embed=embed)
     return await interface.send_to(ctx)
Example #26
0
async def auto_paginate(ctx,
                        text,
                        prefix='```',
                        suffix='```',
                        max_size=2000,
                        wrap_at=(' ', '\n')):
    paginator = WrappedPaginator(prefix=prefix,
                                 suffix=suffix,
                                 max_size=max_size,
                                 wrap_on=wrap_at)
    paginator.add_line(text)
    interface = PaginatorInterface(ctx.bot, paginator, owner=ctx.author)
    await interface.send_to(ctx)
    return interface.message
Example #27
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)
Example #28
0
 async def config(self, ctx, option: str = None):
     if not option:
         paginator = WrappedPaginator(prefix='```ini', suffix='```', max_size=800)
         gconf = self.bot.configs[ctx.guild.id]
         for opt, data in gconf.options.items():
             current = gconf.get(opt)
             if isinstance(current, list):
                 current = ', '.join(str(current))
             accepted = data["accepts"]
             if isinstance(accepted, list):
                 accepted = f'List of {accepted[0].__name__}'
             else:
                 accepted = accepted.__name__
             paginator.add_line(f'[{opt}]\n{data["description"].split(" | ")[-1]}\nDefault: {data["default"]}\nCurrent: {gconf.get(opt)}\nAccepts: {accepted}\n')
         interface = PaginatorInterface(ctx.bot, paginator, owner=ctx.author)
         return await interface.send_to(ctx)
Example #29
0
 async def emojis(self, ctx, search=None):
     emojis = []
     if search:
         result = finder(text=search, collection=self.bot.emojis, key=lambda emoji: emoji.name, lazy=False)
         if result == []:
             return await ctx.send("Nothing found for your query.")
         for emoji in result:
             emojis.append(f"{str(emoji)} `{emoji.name}`")
         paginator = WrappedPaginator(prefix='', suffix='', max_size=500)
     else:
         for emoji in self.bot.emojis:
             emojis.append(f"{str(emoji)} `{emoji.name}`")
         paginator = WrappedPaginator(prefix='', suffix='', max_size=1000)
     paginator.add_line('\n'.join(emojis))
     interface = PaginatorInterface(ctx.bot, paginator, owner=ctx.author)
     await interface.send_to(ctx)
Example #30
0
	async def modlogs(self, ctx, user: UserWithFallback = None):
		"""PFXmodlogs <user>"""
		if not user:
			user = ctx.author
		try:
			if type(user) == discord.User or type(user) == discord.Member:
				mlogs = self.modlogs[ctx.guild.id][user.id]
			elif type(user) == int:
				mlogs = self.modlogs[ctx.guild.id][user]
		except KeyError:
			return await ctx.send(f'<a:fireFailed:603214400748257302> No logs found.')
		paginator = WrappedPaginator(prefix='', suffix='')
		for log in mlogs:
			paginator.add_line(f'**Case ID**: {log["caseid"]}\n**Type**: {log["type"].capitalize()}\n**User**: {user}\n**Reason**: {log["reason"]}\n**Date**: {log["date"]}\n**-----------------**')
		embed = discord.Embed(color=discord.Color(15105570), timestamp=datetime.datetime.utcnow())
		interface = PaginatorEmbedInterface(ctx.bot, paginator, owner=ctx.author, _embed=embed)
		await interface.send_to(ctx)