Пример #1
0
    async def _source(self, ctx: commands.Context, command: str, start: typing.Optional[int], end: typing.Optional[int]):
        """
        display the source of a command

        examples:
            `>source owner` :: show the full source of `owner`
            `>source owner 2` :: show line `2` of `owner`
            `>source owner 3 5` :: show lines 3-5 of `owner`
        """

        command = ctx.bot.get_command(command)
        if (not command):
            await ctx.bot.send_help(ctx)
            return

        if (not await command.can_run(ctx)):
            await ctx.bot.send_help(ctx)
            return

        if (start):
            if ((end) and ((start < 1) or (start > end))):
                raise commands.BadArgument()
        else:
            # show all
            start, end = 1, -1

        source = inspect.getsource(command.callback)
        source = format.get_lines(source, start, end)
        
        message = format.dedent(source)
        message = message.replace("```", "``")
        
        for (page) in format.pagify(message, shorten_by=10):
            if (page):
                await ctx.send("```py\n{0}```".format(page))
Пример #2
0
    async def _unicode(self, ctx: commands.Context, *, characters: str):
        """
        show unicode information on a character

        example:
            `>unicode :zero:` :: \\U00000030\\U000020e3
        """

        message = ""

        max_ = max([len(character) for (character) in characters])

        for (character) in characters:
            digit = "{0:x}".format(ord(character))
            name = unicodedata.name(character, "unknown name")

            # fix weird bug with the enclosing keycap
            if (name in ["COMBINING ENCLOSING KEYCAP", "ZERO WIDTH SPACE"]):
                i = " "
            else:
                i = ""

            message += "\u200b {0:>{width}} {1} \\U{2:>08}  \\N{{{3}}}\n".format(
                character, i, digit, name,
                width=max_
            )

        for (page) in format.pagify(message, shorten_by=8):
            if (page):
                await ctx.send("```\n{0}```".format(page))
Пример #3
0
    async def _roll(self,
                    ctx: commands.Context,
                    count: int = 1,
                    sides: int = 6):
        """
        roll count die with sides

        english is hard

        examples:
            `>roll`      :: roll `one`, `six` sided die
            `>roll 2`    :: roll `two`, `six` sided dice
            `>roll 3 10` :: roll `three`, `ten` sided dice
        """

        if ((count < 1) or (sides < 1)):
            await ctx.bot.send_help(ctx)
            return

        rolls = list()

        for (_) in range(count):
            roll = random.randint(1, sides)
            rolls.append(str(roll))

        message = ", ".join(rolls)

        for (page) in format.pagify(message, delims=[" "]):
            if (page):
                await ctx.send(page)
Пример #4
0
    async def _github_issue_list(self, ctx: commands.Context):
        """
        list open issues
        """

        # https://developer.github.com/v3/issues/#list-issues-for-a-repository
        url = "repos/ShineyDev/sbt/issues"

        async with ctx.typing():
            try:
                issues = await self.request("GET", url)
            except (GitHubError) as e:
                await ctx.send("`{0}: {1}`".format(type(e).__name__, str(e)))
                return

        message = ""

        for (issue) in issues:
            if (issue.get("pull_request")):
                # not an issue, i will never understand why prs show as
                # issues ¯\_(ツ)_/¯
                continue
            elif (issue.get("state") == "closed"):
                continue

            url = format.wrap_url(issue.get("html_url"))
            message += "{0}\n".format(url)

        if (not message):
            await ctx.send("there are no open issues")
            return

        for (page) in format.pagify(message):
            if (page):
                await ctx.send(page)
Пример #5
0
    async def _dis(self, ctx: commands.Context, *, command: str):
        """
        display the disassembled source of a command

        example:
            `>dis owner` :: show the disassembled source of `owner`
        """

        command = ctx.bot.get_command(command)
        if (not command):
            await ctx.bot.send_help(ctx)
            return

        if (not await command.can_run(ctx)):
            await ctx.bot.send_help(ctx)
            return

        message = dis.Bytecode(command.callback).dis()
        if (not message):
            await ctx.bot.send_help(ctx)
            return

        message = message.replace("```", "``")
        
        for (page) in format.pagify(message, shorten_by=8):
            if (page):
                await ctx.send("```\n{0}```".format(page))
Пример #6
0
    async def list(self, ctx):
        """displays a list of all users on your server"""
        msg = ""
        for member in self.bot.guild.members:
            msg += f"{member.display_name} - created at {member.created_at} - joined at {member.joined_at}\n"

        for page in fmt.pagify(msg, delims=["\n#"], page_length=1990):
            await self.bot.sendc(ctx, fmt.box(page, "md"))
Пример #7
0
 async def list(self, ctx):
     """
     list all current timed messages
     """
     to_send = ""
     with self.bot.session_scope() as session:
         msgs = TimedMessage.get_all_from_guild(ctx.guild.id, session)
         for msg in msgs:
             to_send += f"{str(msg)}\n\n"
     for page in pagify(to_send, delims=["\n#"], page_length=1990):
         await self.bot.sendc(ctx, box(page, "md"))
Пример #8
0
    async def _loaded_extensions(self, ctx: commands.Context):
        """
        show loaded extensions
        """

        message = ""

        for (extension_name, extension) in ctx.bot.cogs.items():
            message += "{0}\n".format(extension_name)

        for (page) in format.pagify(message, shorten_by=8):
            if (page):
                await ctx.send("```\n{0}```".format(page))
Пример #9
0
    async def _loaded_imports(self, ctx: commands.Context):
        """
        show loaded imports
        """

        message = ""

        for (module_) in sys.modules:
            message += "{0}\n".format(module_)

        for (page) in format.pagify(message, shorten_by=8):
            if (page):
                await ctx.send("```\n{0}```".format(page))
Пример #10
0
    async def _spellout(self, ctx: commands.Context, *, text: str):
        """
        s p e l l o u t text

        yeah i think you understand what this one does
        """

        message = ""
        for (character) in text:
            message += "{0} ".format(character)

        for (page) in format.pagify(message, delims=[" "]):
            if (page):
                await ctx.send(page)
Пример #11
0
    async def _list_sound_queue(self, ctx):
        """list current items in queue"""
        queue = self.bot.audio.list_queue(ctx.guild.id)
        msg = ""
        _index = 0

        if queue is not None:
            for t in queue:
                msg += f"\n# Position {_index} #\n- "
                msg += f"{t.title}"
                _index = _index + 1

        for page in fmt.pagify(msg, delims=["\n#"], page_length=1990):
            if page:
                await self.bot.sendc(ctx, fmt.box(page, "md"))
            else:
                await self.bot.sendc(ctx, fmt.box("Queue is empty."))
Пример #12
0
    async def _github_issue_events(self, ctx: commands.Context, id: int):
        """
        show events for an issue
        """

        # https://developer.github.com/v3/issues/events/#list-events-for-an-issue
        url = "repos/ShineyDev/sbt/issues/{0}/events".format(id)

        async with ctx.typing():
            try:
                events = await self.request("GET", url)
            except (GitHubError) as e:
                await ctx.send("`{0}: {1}`".format(type(e).__name__, str(e)))
                return

        # https://developer.github.com/v3/issues/#get-a-single-issue
        url = "repos/ShineyDev/sbt/issues/{0}".format(id)

        async with ctx.typing():
            try:
                issue = await self.request("GET", url)
            except (GitHubError) as e:
                await ctx.send("`{0}: {1}`".format(type(e).__name__, str(e)))
                return

        message = "+ {0} opened this issue\n".format(issue["user"]["login"])

        for (event) in events:
            if (event["event"] == "moved_columns_in_project"):
                # this will be here until github either remove the
                # `project_card` key from starfox-preview or remove the
                # `lock_reason` key from sailor-v-preview since we are
                # currently using sailor-v-preview to get access to the
                # `lock_reason` key
                continue

            if (event["event"] not in EVENT_MESSAGES.keys()):
                continue

            message += EVENT_MESSAGES[event["event"]].format(event)
            message += "\n"

        for (page) in format.pagify(message, shorten_by=12):
            if (page):
                await ctx.send("```diff\n{0}```".format(page))
Пример #13
0
    async def list(self, ctx):
        """a list of all available tags"""
        self.bot.log.info("list")
        with self.bot.session_scope() as session:
            tags = Tag.get_all_from_guild(ctx.guild.id, session)

            msg = ""
            last_header = "^"
            for t in tags:
                if t.Name[0] is not last_header:
                    last_header = t.Name[0]
                    msg += f"\n# {last_header} #\n- "
                msg += f"[{t.Name}]"
                typ = TagType(t.Type).name.upper()[0]
                msg += f"({typ}|{t.entries.count()}) - "

            for page in fmt.pagify(msg, delims=["\n#"], page_length=1990):
                await self.bot.sendc(ctx, fmt.box(page, "md"))
Пример #14
0
    async def _walk(self, ctx: commands.Context, module: str):
        """
        walk a module

        example:
            `>walk information`
        """

        message = "modules.{0}\n\n".format(module)

        module = ctx.bot.get_cog(module)
        if (not module):
            await ctx.bot.send_help(ctx)
            return

        command_ = None
        callbacks = list()

        for (command) in module.walk_commands():
            if (command.callback.__name__ in callbacks):
                continue

            callbacks.append(command.callback.__name__)
            command_ = command

            width = len(command.qualified_name.split(" ")) - 1
            indent = "  " * width
            name = command.name
            aliases = "| {0}".format(" | ".join(
                command.aliases)) if command.aliases else ""
            enabled = "*" if command.enabled else " "
            hidden = "*" if command.hidden else " "

            message += "{0}{1:<{width}} {2:<32} | {3} | {4} |\n".format(
                indent,
                name,
                aliases,
                enabled,
                hidden,
                width=(20 - (width * 2)))

        for (page) in format.pagify(message, shorten_by=8):
            if (page):
                await ctx.send("```\n{0}```".format(page))
Пример #15
0
    async def _whitelist(self, ctx: commands.Context):
        """
        show the current whitelist
        """

        if (not ctx.bot._settings.whitelist):
            await ctx.bot.send_help(ctx)
            return

        message = ""

        for (id) in ctx.bot._settings.whitelist:
            user = await ctx.bot.get_user(id)
            if (user):
                message += "{0}  |  {1}\n".format(id, user.name)
            else:
                message += "{0}\n".format(id)

        for (page) in format.pagify(message, shorten_by=8):
            if (page):
                await ctx.send("```\n{0}```".format(page))
Пример #16
0
    async def _eval(self, ctx: commands.Context, *, shit: str):
        """
        eval shit

        there is no better explanation of what this command does
        """

        shit = shit.strip("`")
        shit = format.dedent(shit)

        if (shit.startswith("py\n")):
            shit = shit[3:]

        globals_ = globals().copy()
        globals_["self"] = self
        globals_["ctx"] = ctx

        for (i, result) in enumerate(self._results):
            globals_[f"_{i}"] = result

        if (hasattr(self, "_exception")):
            globals_["_x"] = self._exception

        function = "async def _evaluate(self):\n{0}".format(
            format.indent(shit, amount=4))

        try:
            exec(function, globals_, locals())
            result = await locals()["_evaluate"](self)
        except (Exception) as e:
            if (ctx.invoked_with == "repl"):
                return

            message = await ctx.send("`{0}: {1}`".format(
                type(e).__name__, str(e)))
            await ctx.message.add_reaction("\U0000274e")
            self._exception = e

            if (not checks.is_debugging_check(ctx)):
                await asyncio.sleep(5)
                await message.delete()
                await ctx.message.delete()

            return
        else:
            await ctx.message.add_reaction("\U00002705")

        if (result != None):
            result = str(result)
            result = (result.replace(
                ctx.bot._settings.github_api_key, "[REDACTED]").replace(
                    ctx.bot._settings.google_api_key, "[REDACTED]").replace(
                        ctx.bot._settings.google_engine_id,
                        "[REDACTED]").replace(ctx.bot._settings.secret,
                                              "[REDACTED]").replace(
                                                  ctx.bot._settings.token,
                                                  "[REDACTED]"))

            for (page) in format.pagify(result,
                                        delims=["\n", ",", " "],
                                        shorten_by=8):
                if (page):
                    page = await ctx.send("```\n{0}```".format(page))
Пример #17
0
    async def _embed(self, ctx: commands.Context):
        """
        create and edit an embed, then get either the json or the
        code given back to you :)
        """

        previous = collections.deque(maxlen=3)
        current = format.embed()
        next = collections.deque(maxlen=3)

        message = await ctx.send(embed=current)

        keys = [
            "title",
            "description",
            "color",
            "colour",
            "thumbnail",
            "author",
            "author_url",
            "author_icon_url",
            "field",
            "image",
            "footer",
            "footer_icon_url",
        ]

        reactions = [
            "\U0001f4dd",
            "\U0001f4dc",
            "\U00002b05",
            "\U000027a1",
            "\U00002705",
            "\U0000267b",
            "\U0001f5d1",
        ]

        for (reaction) in reactions:
            await message.add_reaction(reaction)

        while (True):

            def check(reaction: discord.Reaction, member: discord.Member):
                if (member == ctx.author):
                    if (reaction.message.id == message.id):
                        if (str(reaction.emoji) in reactions):
                            return True

                return False

            tasks = {
                asyncio.create_task(
                    ctx.bot.wait_for("reaction_add", check=check,
                                     timeout=120)),
                asyncio.create_task(
                    ctx.bot.wait_for("reaction_remove",
                                     check=check,
                                     timeout=120)),
            }

            done, pending = await asyncio.wait(
                tasks, return_when=asyncio.FIRST_COMPLETED)

            try:
                reaction, _ = done.pop().result()
            except (asyncio.TimeoutError) as e:
                await message.clear_reactions()
                ctx.command.reset_cooldown(ctx)
                return

            for (task) in pending:
                task.cancel()

            if (str(reaction.emoji) == reactions[0]):

                def check(message: discord.Message):
                    if (message.author == ctx.author):
                        if (message.channel == ctx.channel):
                            if ("=" in message.content):
                                if (message.content.split("=", 1)[0] in keys):
                                    if (message.content.startswith("field")):
                                        if (message.content.count("|") == 1):
                                            return True
                                        elif (message.content.count("|") == 2):
                                            _, _, inline = message.content.split(
                                                "|")
                                            if (inline.isdigit()):
                                                if (int(inline) in [0, 1]):
                                                    return True
                                    else:
                                        return True
                            elif (message.content == "field-"):
                                return True

                try:
                    message_ = await ctx.bot.wait_for("message",
                                                      check=check,
                                                      timeout=60)
                except (asyncio.TimeoutError) as e:
                    await message.remove_reaction(str(reaction.emoji),
                                                  ctx.author)
                    continue
                else:
                    if (message_.content == "field-"):
                        if (len(current.fields) != 0):
                            current.remove_field(len(current.fields) - 1)
                            await message.edit(embed=current)
                    else:
                        key, value = message_.content.split("=", 1)

                        if ((len(value) + len(current)) > 6000):
                            await message_.delete()
                            await message.remove_reaction(
                                str(reaction.emoji), ctx.author)
                            continue

                        current_ = current.copy()

                        try:
                            if (key == "title"):
                                if (len(value) <= 256):
                                    previous.append(current.copy())
                                    current_.title = value
                                    next.clear()
                            elif (key == "description"):
                                previous.append(current.copy())
                                current_.description = value
                                next.clear()
                            elif ((key == "color") or (key == "colour")):
                                if (len(value) == 3):
                                    value = "".join(i * 2 for i in value)

                                if (len(value) == 6):
                                    try:
                                        color = int(value, 16)
                                    except (ValueError) as e:
                                        pass
                                    else:
                                        previous.append(current.copy())
                                        current_.color = color
                                        next.clear()
                            elif (key == "thumbnail"):
                                previous.append(current.copy())
                                current_.set_thumbnail(url=value)
                                next.clear()
                            elif (key == "author"):
                                if (len(value) <= 256):
                                    previous.append(current.copy())
                                    current_.set_author(
                                        name=value,
                                        url=current.author.url,
                                        icon_url=current.author.icon_url)
                                    next.clear()
                            elif (key == "author_url"):
                                if (current.author.name !=
                                        discord.Embed.Empty):
                                    previous.append(current.copy())
                                    current_.set_author(
                                        name=current.author.name,
                                        url=value,
                                        icon_url=current.author.icon_url)
                                    next.clear()
                            elif (key == "author_icon_url"):
                                if (current.author.name !=
                                        discord.Embed.Empty):
                                    previous.append(current.copy())
                                    current_.set_author(
                                        name=current.author.name,
                                        url=current.author.url,
                                        icon_url=value)
                                    next.clear()
                            elif (key == "field"):
                                if (len(current.fields) < 25):
                                    if (value.count("|") == 1):
                                        name, value = value.split("|")

                                        if (len(name) <= 256):
                                            previous.append(current.copy())
                                            current_.add_field(name=name,
                                                               value=value)
                                            next.clear()
                                    else:
                                        name, value, inline = value.split("|")

                                        if (len(name) <= 256):
                                            previous.append(current.copy())
                                            current_.add_field(
                                                name=name,
                                                value=value,
                                                inline=bool(int(inline)))
                                            next.clear()
                            elif (key == "image"):
                                previous.append(current.copy())
                                current_.set_image(url=value)
                                next.clear()
                            elif (key == "footer"):
                                previous.append(current.copy())
                                current_.set_footer(
                                    text=value,
                                    icon_url=current.footer.icon_url)
                                next.clear()
                            elif (key == "footer_icon_url"):
                                if (current.footer.text !=
                                        discord.Embed.Empty):
                                    previous.append(current.copy())
                                    current_.set_footer(
                                        text=current.footer.text,
                                        icon_url=value)
                                    next.clear()

                            await message.edit(embed=current_)
                        except (discord.HTTPException) as e:
                            pass
                        else:
                            current = current_.copy()

                await message_.delete()
            elif (str(reaction.emoji) == reactions[1]):

                def check(message: discord.Message):
                    if (message.author == ctx.author):
                        if (message.channel == ctx.channel):
                            try:
                                json.loads(message.content, encoding="utf-8")
                                return True
                            except (json.JSONDecodeError) as e:
                                pass

                try:
                    message_ = await ctx.bot.wait_for("message",
                                                      check=check,
                                                      timeout=60)
                except (asyncio.TimeoutError) as e:
                    await message.remove_reaction(str(reaction.emoji),
                                                  ctx.author)
                    continue
                else:
                    json_ = json.loads(message_.content, encoding="utf-8")
                    dict_ = current.to_dict()
                    dict_.update(json_)

                    previous.append(current.copy())
                    current = discord.Embed.from_dict(dict_)
                    next.clear()

                    await message.edit(embed=current)

                await message_.delete()
            elif (str(reaction.emoji) == reactions[2]):
                if (previous):
                    next.appendleft(current.copy())
                    current = previous.pop()

                    await message.edit(embed=current)
            elif (str(reaction.emoji) == reactions[3]):
                if (next):
                    previous.append(current.copy())
                    current = next.popleft()

                    await message.edit(embed=current)
            elif (str(reaction.emoji) == reactions[4]):
                await message.clear_reactions()

                json_ = current.to_dict()
                if (json_):
                    json_ = json.dumps(json_, indent=2)

                    for (page) in format.pagify(json_, shorten_by=8):
                        await ctx.send("```\n{0}```".format(page))

                    ctx.command.reset_cooldown(ctx)
                    return
            elif (str(reaction.emoji) == reactions[5]):
                previous.append(current.copy())
                current = format.embed()
                next.clear()

                await message.edit(embed=current)
            elif (str(reaction.emoji) == reactions[6]):
                await message.delete()
                ctx.command.reset_cooldown(ctx)
                return

            await message.remove_reaction(str(reaction.emoji), ctx.author)
Пример #18
0
    async def _debug(self, ctx: commands.Context, index: typing.Optional[int],
                     *, shit: str):
        """
        debug shit

        there is no better explanation of what this command does
        """

        shit = shit.strip("`").strip()

        globals_ = globals().copy()
        globals_["self"] = self
        globals_["ctx"] = ctx

        for (i, result) in enumerate(self._results):
            globals_[f"_{i}"] = result

        if (hasattr(self, "_exception")):
            globals_["_x"] = self._exception

        try:
            result = eval(shit, globals_, locals())
        except (Exception) as e:
            message = await ctx.send("`{0}: {1}`".format(
                type(e).__name__, str(e)))
            await ctx.message.add_reaction("\U0000274e")
            self._exception = e

            if (not checks.is_debugging_check(ctx)):
                await asyncio.sleep(5)
                await message.delete()
                await ctx.message.delete()

            return

        try:
            if (asyncio.iscoroutine(result)):
                result = await result
        except (Exception) as e:
            message = await ctx.send("`{0}: {1}`".format(
                type(e).__name__, str(e)))
            await ctx.message.add_reaction("\U0000274e")
            self._exception = e

            if (not checks.is_debugging_check(ctx)):
                await asyncio.sleep(5)
                await message.delete()
                await ctx.message.delete()

            return
        else:
            await ctx.message.add_reaction("\U00002705")

        if (index in range(len(self._results))):
            self._results[index] = result
        else:
            self._results.appendleft(result)

        if (result != None):
            result = str(result)
            result = (result.replace(
                ctx.bot._settings.github_api_key, "[REDACTED]").replace(
                    ctx.bot._settings.google_api_key, "[REDACTED]").replace(
                        ctx.bot._settings.google_engine_id,
                        "[REDACTED]").replace(ctx.bot._settings.secret,
                                              "[REDACTED]").replace(
                                                  ctx.bot._settings.token,
                                                  "[REDACTED]"))

            for (page) in format.pagify(result,
                                        delims=["\n", ",", " "],
                                        shorten_by=8):
                if (page):
                    page = await ctx.send("```\n{0}```".format(page))