Exemple #1
0
async def listuserbadges(ctx, user: discord.Member = None):
    """Get the badges of a user."""
    if user is None:
        user = ctx.message.author
    badges = await db.user(user).badges()

    # sort
    priority_badges = []
    for badge_name, badge in badges.items():
        priority_num = badge["priority_num"]
        if priority_num != -1:
            priority_badges.append((badge, priority_num))
    sorted_badges = sorted(priority_badges, key=operator.itemgetter(1), reverse=True)

    badge_ranks = []
    for i, (badge, priority_num) in enumerate(sorted_badges[:12], 1):
        badge_ranks.append(f"**{i}. {badge['badge_name']}** ({badge['guild_name']}) [{priority_num}] **—** {badge['description']}")
    badge_ranks = "\n".join(badge_ranks) or "None"

    em = discord.Embed(description="", colour=user.colour)

    total_pages = 0
    for _ in pagify(badge_ranks, ["\n"]):
        total_pages += 1

    for i, page in enumerate(pagify(badge_ranks, ["\n"]), 1):
        em.description = page
        em.set_author(name=f"Badges for {user.name}", icon_url=user.avatar_url)
        em.set_footer(text=f"Page {i} of {total_pages}")
        await ctx.send(embed=em)
Exemple #2
0
    async def cc_list(self, ctx: commands.Context):
        """List all available custom commands.

        The list displays a preview of each command's response, with
        markdown escaped and newlines replaced with spaces.
        """
        cc_dict = await CommandObj.get_commands(self.config.guild(ctx.guild))

        if not cc_dict:
            await ctx.send(
                _(
                    "There are no custom commands in this server."
                    " Use `{command}` to start adding some."
                ).format(command="{}customcom create".format(ctx.prefix))
            )
            return

        results = []
        for command, body in sorted(cc_dict.items(), key=lambda t: t[0]):
            responses = body["response"]
            if isinstance(responses, list):
                result = ", ".join(responses)
            elif isinstance(responses, str):
                result = responses
            else:
                continue
            # Cut preview to 52 characters max
            if len(result) > 52:
                result = result[:49] + "..."
            # Replace newlines with spaces
            result = result.replace("\n", " ")
            # Escape markdown and mass mentions
            result = escape(result, formatting=True, mass_mentions=True)
            results.append((f"{ctx.clean_prefix}{command}", result))

        if await ctx.embed_requested():
            # We need a space before the newline incase the CC preview ends in link (GH-2295)
            content = " \n".join(map("**{0[0]}** {0[1]}".format, results))
            pages = list(pagify(content, page_length=1024))
            embed_pages = []
            for idx, page in enumerate(pages, start=1):
                embed = discord.Embed(
                    title=_("Custom Command List"),
                    description=page,
                    colour=await ctx.embed_colour(),
                )
                embed.set_footer(text=_("Page {num}/{total}").format(num=idx, total=len(pages)))
                embed_pages.append(embed)
            await menus.menu(ctx, embed_pages, menus.DEFAULT_CONTROLS)
        else:
            content = "\n".join(map("{0[0]:<12} : {0[1]}".format, results))
            pages = list(map(box, pagify(content, page_length=2000, shorten_by=10)))
            await menus.menu(ctx, pages, menus.DEFAULT_CONTROLS)
Exemple #3
0
    async def convert(self, ctx, argument):
        _ = self.translator
        destination = await self.search(ctx, argument, self.globally, _)
        if len(destination) > 1:

            def check(message):
                nonlocal destination
                if message.author != ctx.author or message.channel != ctx.channel:
                    return False
                with suppress(Exception):
                    destination = [destination[int(message.content)]]
                    return True
                return False

            message = _("Multiple results found. Choose a destination:")
            message += "\n\n" + "\n".join(
                f"{i}: {d} ({getattr(d, 'guild')})" if hasattr(d, "guild") else f"{i}: {d}"
                for i, d in enumerate(destination)
            )
            for page in pagify(message):
                await ctx.send(page)
            try:
                await ctx.bot.wait_for("message", check=check)
            except asyncio.TimeoutError as e:
                raise commands.BadArgument(_("Never mind, then.")) from e
        result = destination[0]
        destination = ctx.bot.get_channel(result.id) or ctx.bot.get_user(result.id)
        if not destination:
            raise commands.BadArgument(_("I don't have access to {} anymore.").format(result))
        source = ctx.channel if isinstance(ctx.channel, discord.TextChannel) else ctx.author
        rift = Rift(author=ctx.author, source=source, destination=destination)
        if rift in ctx.cog.open_rifts:
            raise commands.BadArgument(_("This rift already exists."))
        return rift
Exemple #4
0
    async def rift_search(self, ctx, searchby: search_converter(_) = None, *, search=None):
        """
        Searches through open rifts.

        searchby: author, source, or destination. If this isn't provided, all
        three are searched through.
        search: Search for the specified author/source/destination. If this
        isn't provided, the author or channel of the command is used.
        """
        searchby = searchby or list(range(3))
        if search is None:
            search = [ctx.author, ctx.channel, ctx.author]
        else:
            try:
                search = await RiftConverter.search(ctx, search, False, _)
            except commands.BadArgument as e:
                embed = await self.create_simple_embed(self.bot.user, str(e), "Bot Exception")
                return await ctx.send(embed=embed)
        results = set()
        for rift in self.open_rifts:
            for i in searchby:
                if rift[i] in search:
                    results.add(rift)
        if not results:
            return await ctx.maybe_send_embed(_("No rifts were found with these parameters."))
        message = _("Results:") + "\n\n"
        message += "\n".join(str(rift) for rift in results)
        for page in pagify(message):
            await ctx.maybe_send_embed(page)
Exemple #5
0
    async def discover_guild(
        self,
        author: discord.User,
        *,
        mod: bool = False,
        permissions: Union[discord.Permissions, dict] = None,
        prompt: str = "",
    ):
        """
        discovers which of shared guilds between the bot
        and provided user based on conditions (mod or permissions is an or)

        prompt is for providing a user prompt for selection
        """
        shared_guilds = []
        if permissions is None:
            perms = discord.Permissions()
        elif isinstance(permissions, discord.Permissions):
            perms = permissions
        else:
            perms = discord.Permissions(**permissions)

        for guild in self.bot.guilds:
            x = guild.get_member(author.id)
            if x is not None:
                if await self.internal_filter(x, mod, perms):
                    shared_guilds.append(guild)
        if len(shared_guilds) == 0:
            raise ValueError("No Qualifying Shared Guilds")
        if len(shared_guilds) == 1:
            return shared_guilds[0]
        output = ""
        guilds = sorted(shared_guilds, key=lambda g: g.name)
        for i, guild in enumerate(guilds, 1):
            output += "{}: {}\n".format(i, guild.name)
        output += "\n{}".format(prompt)

        for page in pagify(output, delims=["\n"]):
            await author.send(box(page))

        try:
            message = await self.bot.wait_for(
                "message",
                check=MessagePredicate.same_context(channel=author.dm_channel, user=author),
                timeout=45,
            )
        except asyncio.TimeoutError:
            await author.send(_("You took too long to select. Try again later."))
            return None

        try:
            message = int(message.content.strip())
            guild = guilds[message - 1]
        except (ValueError, IndexError):
            await author.send(_("That wasn't a valid choice."))
            return None
        else:
            return guild
Exemple #6
0
    async def _repo_list(self, ctx):
        """List all installed repos."""
        repos = self._repo_manager.get_all_repo_names()
        repos = sorted(repos, key=str.lower)
        joined = _("Installed Repos:\n\n")
        for repo_name in repos:
            repo = self._repo_manager.get_repo(repo_name)
            joined += "+ {}: {}\n".format(repo.name, repo.short or "")

        for page in pagify(joined, ["\n"], shorten_by=16):
            await ctx.send(box(page.lstrip(" "), lang="diff"))
Exemple #7
0
    async def __msg_list(self, ctx: commands.Context, event: str):
        """Handler for listing message formats."""

        guild = ctx.guild

        msg = "{} message formats:\n".format(event.capitalize())
        async with self.config.guild(guild).get_attr(event).messages() as messages:
            for n, m in enumerate(messages, start=1):
                msg += "  {}. {}\n".format(n, m)

        for page in pagify(msg, ["\n", " "], shorten_by=20):
            await ctx.send(box(page))
Exemple #8
0
 async def rift_list_destinations(self, ctx, source: discord.TextChannel = None):
     """List destinations for opened rifts"""
     if source is None:
         source = ctx.channel
     rifts = await self.get_rifts(source, True)
     if rifts:
         message = ("Rifts:") + "\n\n"
         message += "\n".join(rift.mention() for rift in rifts)
         for page in pagify(message):
             await ctx.maybe_send_embed(page)
     else:
         embed = await self.create_simple_embed(self.bot.user, "No Rift Found.")
         await ctx.send(embed=embed)
Exemple #9
0
    async def cc_show(self, ctx, command_name: str):
        """Shows a custom command's reponses and its settings."""

        try:
            cmd = await self.commandobj.get_full(ctx.message, command_name)
        except NotFound:
            ctx.send(_("I could not not find that custom command."))
            return

        responses = cmd["response"]

        if isinstance(responses, str):
            responses = [responses]

        author = ctx.guild.get_member(cmd["author"]["id"])
        # If the author is still in the server, show their current name
        if author:
            author = "{} ({})".format(author, cmd["author"]["id"])
        else:
            author = "{} ({})".format(cmd["author"]["name"], cmd["author"]["id"])

        _type = _("Random") if len(responses) > 1 else _("Normal")

        text = _(
            "Command: {}\n"
            "Author: {}\n"
            "Created: {}\n"
            "Type: {}\n".format(command_name, author, cmd["created_at"], _type)
        )

        cooldowns = cmd["cooldowns"]

        if cooldowns:
            cooldown_text = _("Cooldowns:\n")
            for rate, per in cooldowns.items():
                cooldown_text += _("{} seconds per {}\n".format(per, rate))
            text += cooldown_text

        text += _("Responses:\n")
        responses = ["- " + r for r in responses]
        text += "\n".join(responses)

        for p in pagify(text):
            await ctx.send(box(p, lang="yaml"))
Exemple #10
0
    async def streamalert_list(self, ctx: commands.Context):
        """List all active stream alerts in this server."""
        streams_list = defaultdict(list)
        guild_channels_ids = [c.id for c in ctx.guild.channels]
        msg = _("Active alerts:\n\n")

        for stream in self.streams:
            for channel_id in stream.channels:
                if channel_id in guild_channels_ids:
                    streams_list[channel_id].append(stream.name.lower())

        if not streams_list:
            await ctx.send(_("There are no active alerts in this server."))
            return

        for channel_id, streams in streams_list.items():
            channel = ctx.guild.get_channel(channel_id)
            msg += "** - #{}**\n{}\n".format(channel, ", ".join(streams))

        for page in pagify(msg):
            await ctx.send(page)
Exemple #11
0
    async def addmoneyrole(self,
                           ctx,
                           amount: int,
                           role: discord.Role,
                           destination: Optional[str] = "wallet"):
        """Add money to the balance of all users within a role.

        Valid arguements are 'banks' or 'wallet'.
        """
        if destination.lower() not in ["bank", "wallet"]:
            return await ctx.send(
                "You've supplied an invalid destination, you can choose to add it to a bank or their wallet.\nIf no destination is supplied it will default to their wallet."
            )

        failedmsg = ""
        if destination.lower() == "bank":
            for user in role.members:
                try:
                    await bank.deposit_credits(user, amount)
                except (ValueError, TypeError) as e:
                    if isinstance(e, ValueError):
                        log.debug(
                            f"Failed to add money to {user} - invalid amount.")
                    else:
                        log.debug(
                            f"Failed to add money to {user} - deposit amount is not an int."
                        )
                except BalanceTooHigh as e:
                    await bank.set_balance(ctx.author, e.max_balance)
                    failedmsg += f"Failed to add {amount} to {user} due to the max wallet balance limit. Their cash has been set to the max balance.\n"
        else:
            for user in role.members:
                try:
                    await self.walletdeposit(ctx, user, amount)
                except ValueError:
                    failedmsg += f"Failed to add {amount} to {user} due to the max wallet balance limit. Their cash has been set to the max balance.\n"
        if failedmsg:
            for page in pagify(failedmsg):
                await ctx.send(page)
        await ctx.tick()
Exemple #12
0
    async def webhook_permissions(self, ctx: commands.Context):
        """Show all members in the server that have `manage_webhook` permissions."""
        async with ctx.typing():
            roles = []
            lines = []
            total_members = set()

            for role in ctx.guild.roles:
                perms = role.permissions
                if perms.administrator or perms.manage_webhooks:
                    roles.append(role)
                    lines.append(f"**{role}** | {role.mention}")
                    members = []
                    for member in filter(lambda m: m not in total_members, role.members):
                        total_members.add(member)
                        member_string = f"{member} ({member.id})"
                        if member.bot:
                            member_string = f"[{member_string}](https://www.youtube.com/watch?v=dQw4w9WgXcQ&ab_channel=RickAstleyVEVO 'This user is a bot')"
                        members.append(member_string)
                    if members:
                        lines.append(humanize_list(members))

            if not lines:
                await ctx.send(
                    "No one here has `manage_webhook` permissions other than the owner."
                )

            base_embed = discord.Embed(
                color=await ctx.embed_color(), title="Users with `manage_webhook` Permissions"
            )
            base_embed.set_footer(text=f"{len(roles)} roles | {len(total_members)} members")
            embeds = []

            for page in pagify("\n".join(lines)):
                embed = base_embed.copy()
                embed.description = page
                embeds.append(embed)

        controls = {"\N{CROSS MARK}": close_menu} if len(embeds) == 1 else DEFAULT_CONTROLS
        await menu(ctx, embeds, controls)
Exemple #13
0
    async def bumpleaderboard(self, ctx, amount: int = 10):
        """View the top Bumpers in the server."""
        if amount < 1:
            raise commands.BadArgument

        members_data = await self.config.all_members(ctx.guild)
        members_list = [(member, data["count"])
                        for member, data in members_data.items()]
        ordered_list = sorted(members_list, key=lambda m: m[1],
                              reverse=True)[:(amount)]

        mapped_strings = [
            f"{index}. <@{member[0]}>: {member[1]}"
            for index, member in enumerate(ordered_list, start=1)
        ]

        if not mapped_strings:
            await ctx.send("There are no tracked bumpers in this server.")
            return

        color = await ctx.embed_color()
        leaderboard_string = "\n".join(mapped_strings)
        if len(leaderboard_string) > 2048:
            embeds = []
            leaderboard_pages = list(pagify(leaderboard_string))
            for index, page in enumerate(leaderboard_pages, start=1):
                embed = discord.Embed(color=color,
                                      title="Bump Leaderboard",
                                      description=page)
                embed.set_footer(text=f"{index}/{len(leaderboard_pages)}")
                embed.set_author(name=ctx.guild.name,
                                 icon_url=ctx.guild.icon_url)
                embeds.append(embed)
            await menu(ctx, embeds, DEFAULT_CONTROLS)
        else:
            embed = discord.Embed(color=color,
                                  title="Bump Leaderboard",
                                  description=leaderboard_string)
            embed.set_author(name=ctx.guild.name, icon_url=ctx.guild.icon_url)
            await ctx.send(embed=embed)
Exemple #14
0
    async def rssnotifier_listroles(
        self,
        ctx: GuildContext,
        feed_name: str,
        channel: Optional[discord.TextChannel] = None,
    ) -> None:
        """
        List role mentions list for the given feed name.

        Use `[p]rss list` for the list of available feeds.
        """
        if channel is None:
            channel = ctx.channel

        role_ids = await self.config.custom(FEED, channel.id,
                                            feed_name).role_mentions()
        role_list = "\n".join(map("- <@&{}>".format, role_ids))
        # this should realistically never reach second page
        for page in pagify(
                f"List of roles that will be pinged for {inline(feed_name)} feed"
                f" in {channel.mention}:\n{role_list}"):
            await ctx.send(page)
    async def dp_guild_role(self, ctx, *, rolename):
        """Generates the permissions of a role.

        Role name can be the name of the role (or at least close to it) or the ID of it.
        
        Permissions Values:
            True: means that the role has that permission
            False: means that the role does not have that permission"""
        try:
            int(rolename)
            isint = True
        except ValueError:
            isint = False
        if not isint:
            roles = [role.name for role in ctx.guild.roles]
            results = process.extract(rolename, roles, limit=1)
            if results[0][1] <= 70:
                return await ctx.send(
                    "Match was too low to be sure the role was found.")
            role = [
                role for role in ctx.guild.roles if role.name == results[0][0]
            ][0]
        else:
            try:
                role = [
                    role for role in ctx.guild.roles
                    if role.id == int(rolename)
                ][0]
            except IndexError:
                return await ctx.send("Could not find a role with that ID.")
            results = [[role.name]]
        t = PrettyTable(["Permission", "Value"])
        for perm, value in role.permissions:
            if value:
                continue
            t.add_row([perm, value])
        sending = f"```ini\n[Permissions for role: {results[0][0]}]```\n```py\n{t}```"
        for page in pagify(sending):
            await ctx.send(sending)
Exemple #16
0
    async def docsites(self, ctx: commands.Context):
        """List all installed and available documentation websites."""
        sites = await self.conf.sites()
        if ctx.guild is not None:
            sites.update(await self.conf.guild(ctx.guild).sites())

        lines: List[str] = []
        for name, url in sites.items():
            try:
                metadata = await self.get_inv_metadata(url)
            except InvNotAvailable:
                continue

            lines.append(f"`{name}` - [{metadata}]({url})")

        if not lines:
            await ctx.send("No sites are available.")

        description = "\n".join(lines)

        for page in chatutils.pagify(description, page_length=2048):
            await ctx.send(embed=discord.Embed(description=page))
Exemple #17
0
 async def strikes(self, ctx: commands.Context, *, member: discord.Member):
     """Show all previous strikes for a user."""
     with self._db_connect() as conn:
         cursor = conn.execute(
             """
             SELECT id, moderator, reason FROM strikes
             WHERE user == ? AND guild == ?
             ORDER BY id DESC
             """,
             (member.id, member.guild.id),
         )
         table = self._create_table(cursor, member.guild)
     if table:
         pages = pagify(table, shorten_by=25)
         await ctx.send(
             _("Strikes for {user.display_name}:\n").format(user=member))
         for page in pages:
             await ctx.send(box(page))
     else:
         await ctx.send(
             _("{user.display_name} has never received any strikes.").
             format(user=member))
 async def invites(self, ctx: commands.Context, *, server: int = None):
     """Get invites from server by id"""
     if server is None:
         server = ctx.guild
     else:
         server = self.bot.get_guild(server)
     if server is None:
         await ctx.send(_("Failed to get server with provided ID"))
         return
     if not server.me.guild_permissions.manage_guild:
         await ctx.send(
             _(
                 'I need permission "Manage Server" to access list of invites on server'
             )
         )
         return
     invites = await server.invites()
     if invites:
         inviteslist = "\n".join([f"{x} ({x.channel.name})" for x in invites])
         await menu(ctx, list(chat.pagify(inviteslist)), DEFAULT_CONTROLS)
     else:
         await ctx.send(_("There is no invites for this server"))
Exemple #19
0
 async def find_dungeon_from_name(self,
                                  ctx,
                                  name,
                                  database: "DungeonContext",
                                  difficulty: str = None):
     """
     Gets the sub_dungeon model given the name of a dungeon and its difficulty.
     """
     dungeons = database.get_dungeons_from_nickname(name.lower())
     if not dungeons:
         dungeons = database.get_dungeons_from_name(name)
         if len(dungeons) == 0:
             await ctx.send("No dungeons found!")
             return
         if len(dungeons) > 1:
             header = "Multiple Dungeons Found, please be more specific:\n"
             for page in pagify(header + '\n'.join(d.name_en
                                                   for d in dungeons)):
                 await ctx.send(page)
             return
         dungeon = dungeons.pop()
         sub_id = database.get_sub_dungeon_id_from_name(
             dungeon.dungeon_id, difficulty)
         sub_dungeon_model = None
         if sub_id is None:
             sub_id = 0
             for sd in dungeon.sub_dungeons:
                 if sd.sub_dungeon_id > sub_id:
                     sub_id = sd.sub_dungeon_id
                     sub_dungeon_model = sd
         else:
             for sd in dungeon.sub_dungeons:
                 if sd.sub_dungeon_id == sub_id:
                     sub_dungeon_model = sd
                     break
         dungeon.sub_dungeons = [sub_dungeon_model]
     else:
         dungeon = dungeons.pop()
     return dungeon
Exemple #20
0
 async def warnings(self, ctx: commands.Context, userid: int = None):
     """Show warnings for the specified user.
     If userid is None, show warnings for the person running the command
     Note that showing warnings for users other than yourself requires
     appropriate permissions
     """
     if userid is None:
         user = ctx.author
     else:
         if not await is_admin_or_superior(self.bot, ctx.author):
             await ctx.send(
                 warning(
                     _("You are not allowed to check warnings for other users!"
                       )))
             return
         else:
             user = ctx.guild.get_member(userid)
             if user is None:  # user not in guild
                 user = namedtuple("Member", "id guild")(userid, ctx.guild)
     msg = ""
     member_settings = self.config.member(user)
     async with member_settings.warnings() as user_warnings:
         if not user_warnings.keys():  # no warnings for the user
             await ctx.send(_("That user has no warnings!"))
         else:
             for key in user_warnings.keys():
                 mod = ctx.guild.get_member(user_warnings[key]["mod"])
                 if mod is None:
                     mod = discord.utils.get(self.bot.get_all_members(),
                                             id=user_warnings[key]["mod"])
                     if mod is None:
                         mod = await self.bot.get_user_info(
                             user_warnings[key]["mod"])
                 msg += "{} point warning {} issued by {} for {}\n".format(
                     user_warnings[key]["points"], key, mod,
                     user_warnings[key]["description"])
             await ctx.send_interactive(
                 pagify(msg, shorten_by=58),
                 box_lang="Warnings for {}".format(user))
Exemple #21
0
 async def search(self, ctx, *, artistsong: str):
     """
     Returns Lyrics for Song Lookup.
     User arguments - artist/song
     """
     async with ctx.typing():
         title, artist, lyrics, source = await getlyrics(artistsong)
         title = "" if title == "" else "{} by {}".format(title, artist)
         paged_embeds = []
         paged_content = [p for p in pagify(lyrics, page_length=900)]
         for index, page in enumerate(paged_content):
             e = discord.Embed(
                 title="{}".format(title),
                 description=page,
                 colour=await self.bot.get_embed_color(ctx.channel),
             )
             e.set_footer(
                 text="Requested by {} | Source: {} | Page: {}/{}".format(
                     ctx.message.author, source, int(index + 1),
                     len(paged_content)))
             paged_embeds.append(e)
     await menu(ctx, paged_embeds, controls=DEFAULT_CONTROLS, timeout=180.0)
Exemple #22
0
    async def customemoji(self, ctx):
        """
        Set custom emojis for the bot to use

        Requires you to upload a .yaml file with
        emojis that the bot can see
        an example may be found
        [here](https://github.com/TrustyJAID/Trusty-cogs/blob/master/hockey/emoji.yaml)
        if no emoji is provided for a team the Other
        slot will be filled instead
        It's recommended to have an emoji for every team
        to utilize all features of the cog such as pickems
        """
        attachments = ctx.message.attachments
        if attachments == []:
            await ctx.send(
                _("Upload the .yaml file to use. Type `exit` to cancel."))
            msg = await self.wait_for_file(ctx)
            if msg is None:
                return
            try:
                await self.change_custom_emojis(msg.attachments)
            except InvalidFileError:
                await ctx.send(
                    _("That file doesn't seem to be formatted correctly."))
                return
        else:
            try:
                await self.change_custom_emojis(attachments)
            except InvalidFileError:
                await ctx.send(
                    _("That file doesn't seem to be formatted correctly."))
                return
        new_msg = "".join(("<:" + TEAMS[e]["emoji"] + ">") for e in TEAMS)
        msg = _("New emojis set to: ") + new_msg
        for page in pagify(msg):
            await ctx.send(page)
        await ctx.send(
            "You should reload the cog for everything to work correctly.")
Exemple #23
0
 async def make_event_embed(self, ctx: commands.Context,
                            event: Event) -> discord.Embed:
     em = discord.Embed(title=event.event)
     em.set_author(name=f"{event.hoster} is hosting",
                   icon_url=event.hoster.avatar_url)
     try:
         prefixes = await self.bot.get_valid_prefixes(ctx.guild)
         prefix = prefixes[0]
     except AttributeError:
         prefixes = await self.bot.get_prefix(ctx.message)
         prefix = prefixes[0]
     max_slots_msg = ""
     if event.max_slots:
         slots = event.max_slots - len(event.members)
         if slots < 0:
             slots = 0
         max_slots_msg = f"**{slots} slots available.**"
     em.description = (
         f"To join this event type `{prefix}join {event.hoster}`"
         f"\n\n{max_slots_msg}")
     player_list = ""
     for i, member in enumerate(event.members):
         player_class = ""
         if member[1]:
             player_class = f" - {member[1]}"
         player_list += f"**Slot {i+1}**\n{member[0].mention}{player_class}\n"
     for page in pagify(player_list, shorten_by=1024):
         em.add_field(name="Attendees", value=page)
     if event.maybe and len(em.fields) < 25:
         em.add_field(name="Maybe",
                      value=humanize_list([m.mention for m in event.maybe]))
     if event.approver:
         em.set_footer(text=f"Approved by {event.approver}",
                       icon_url=event.approver.avatar_url)
     thumbnails = await self.config.guild(ctx.guild).custom_links()
     for name, link in thumbnails.items():
         if name.lower() in event.event.lower():
             em.set_thumbnail(url=link)
     return em
Exemple #24
0
    async def fifo_list(self, ctx: commands.Context, all_guilds: bool = False):
        """
        Lists all current tasks and their triggers.

        Do `[p]fifo list True` to see tasks from all guilds
        """
        if all_guilds:
            pass  # TODO: All guilds
        else:
            out = ""
            all_tasks = await self.config.guild(ctx.guild).tasks()
            for task_name, task_data in all_tasks.items():
                out += f"{task_name}: {task_data}\n\n"

            if out:
                if len(out) > 2000:
                    for page in pagify(out):
                        await ctx.maybe_send_embed(page)
                else:
                    await ctx.maybe_send_embed(out)
            else:
                await ctx.maybe_send_embed("No tasks to list")
Exemple #25
0
    async def which(self, ctx, *, term: str = None):
        """Shows PAD Which Monster entries"""

        if term is None:
            await ctx.author.send(
                '__**PAD Which Monster**__ *(also check out {0}pad / {0}padfaq / {0}boards / {0}glossary)*'
                .format(ctx.prefix))
            msg = self.which_to_text()
            for page in pagify(msg):
                await ctx.author.send(box(page))
            return

        name, definition, timestamp, success = await self._resolve_which(
            ctx, term)
        if name is None or definition is None:
            return
        if not success:
            await ctx.send('`Which {}`\n{}'.format(name, definition))
            return
        await ctx.send(
            inline('Which {} - Last Updated {}'.format(name, timestamp)))
        await ctx.send(definition)
 async def mr_list(self, ctx):
     """Assigned roles list"""
     members_data = await self.config.all_members(ctx.guild)
     assigned_roles = []
     for member, data in members_data.items():
         if not data["role"]:
             continue
         dic = {
             _("User"): ctx.guild.get_member(member) or f"[X] {member}",
             _("Role"): shorten(
                 str(ctx.guild.get_role(data["role"]) or "[X] {}".format(data["role"])),
                 32,
                 placeholder="…",
             ),
         }
         assigned_roles.append(dic)
     pages = list(chat.pagify(tabulate(assigned_roles, headers="keys", tablefmt="orgtbl")))
     pages = [chat.box(page) for page in pages]
     if pages:
         await menu(ctx, pages, DEFAULT_CONTROLS)
     else:
         await ctx.send(chat.info(_("There is no assigned personal roles on this server")))
Exemple #27
0
 async def sourcecode(self, ctx, *, command: str):
     """
     Get the source code of a command
     """
     command = self.bot.get_command(command)
     if command is None:
         await ctx.send("Command not found.")
         return
     source_code = inspect.getsource(command.callback)
     temp_pages = []
     pages = []
     for page in pagify(source_code,
                        escape_mass_mentions=True,
                        page_length=1980):
         temp_pages.append("```py\n" + str(page).replace("```", "``") +
                           "```")
     max_i = len(temp_pages)
     i = 1
     for page in temp_pages:
         pages.append(f"Page {i}/{max_i}\n" + page)
         i += 1
     await menu(ctx, pages, controls=DEFAULT_CONTROLS)
Exemple #28
0
    async def message_track_cache(self, ctx, guild: Optional[discord.Guild]):
        """
        [BOT OWNER] Check cached messages counter for this server.
        """
        if not self.counted_message:
            return await ctx.send("No messages tracked.")

        list_words = []

        guild = guild or ctx.guild

        try:
            sorting_list = sorted(
                self.counted_message[guild.id].items(),
                key=lambda x: x[1]["message"],
                reverse=True,
            )
        except KeyError:
            return await ctx.send(
                "Sorry, there's currently no messages being tracked for this server."
            )
        except AttributeError:
            return await ctx.send(
                "Sorry, there's currently no messages for that.")

        for userid, counter in sorting_list:
            list_words.append("{} {} messages".format(userid,
                                                      counter["message"]))

        if not list_words:
            return False

        message_to_user = "******"

        for msg in list_words:
            message_to_user += "\n\t- {}".format(msg)

        for page in pagify(message_to_user):
            await ctx.send(box(page))
Exemple #29
0
 async def fontg_list(self, ctx):
     'List fonts in the directory.'
     A = self
     C = f"{A.imgpath}/fonts/"
     B = f"{A.datapath}/fonts/"
     F = os.listdir(C)
     try:
         D = os.listdir(B)
     except FileNotFoundError:
         os.mkdir(f"{A.datapath}/fonts/")
         D = os.listdir(B)
     G = sorted(F + D)
     if len(C) and len(B) == 0:
         return await A.bot.send_message(
             channel,
             'No fonts found. Place fonts in your <data directory>/ImgWelcome/fonts/.'
         )
     E = '[Current fonts]\n'
     for H in G:
         E += f"{H}\n"
     for I in pagify(E, delims=['\n']):
         await ctx.send(box(I, lang='ini'))
Exemple #30
0
    async def global_list(self, ctx):
        """List global embeds."""
        embeds_stored = await self.config.embeds()
        if not embeds_stored:
            return await ctx.send("There are no embeds stored globally.")
        msg = ""
        for embed in embeds_stored:
            user = ctx.guild.get_member(embeds_stored[embed]["author"])
            msg += f"{embed} - Created by: {user if user is not None else '<unknown user>'}\n"
        embeds = [
            discord.Embed(
                title="Global Embeds",
                description=page,
                color=await ctx.embed_colour(),
            )
            for page in pagify(msg)
        ]

        if len(embeds) == 1:
            await ctx.send(embed=embeds[0])
            return
        await menu(ctx, embeds, DEFAULT_CONTROLS)
 async def on_adventure_miniboss(self, ctx: commands.Context) -> None:
     roles = [
         f"<@&{rid}>"
         for rid in await self.config.guild(ctx.guild).miniboss_roles()
     ]
     users = [
         f"<@!{uid}>"
         for uid in await self.config.guild(ctx.guild).miniboss_users()
     ]
     guild_members = [m.id for m in ctx.guild.members]
     all_users = await self.config.all_users()
     for u_id, data in all_users.items():
         user_mention = f"<@!{u_id}>"
         if u_id in guild_members and data[
                 "miniboss"] and user_mention not in users:
             users.append(user_mention)
     if roles or users:
         msg = (f"{humanize_list(roles) if roles else ''} " +
                f"{humanize_list(users) if users else ''} " +
                _("A miniboss has appeared, come join!"))
         for page in pagify(msg):
             await ctx.send(page, **self.sanitize)
Exemple #32
0
    async def rg_view_role(self, ctx: commands.GuildContext, *,
                           role: discord.Role):
        """
        Views the current settings for a role.
        """

        rsets = await self.config.role(role).all()

        output = (
            f"This role:\n{'is' if rsets['self_role'] else 'is not'} self assignable"
            f"\n{'is' if rsets['self_removable'] else 'is not'} self removable"
            f"\n{'is' if rsets['sticky'] else 'is not'} sticky.")
        if rsets["requires_any"]:
            rstring = ", ".join(r.name for r in ctx.guild.roles
                                if r.id in rsets["requires_any"])
            output += f"\nThis role requires any of the following roles: {rstring}"
        if rsets["requires_all"]:
            rstring = ", ".join(r.name for r in ctx.guild.roles
                                if r.id in rsets["requires_all"])
            output += f"\nThis role requires all of the following roles: {rstring}"
        if rsets["exclusive_to"]:
            rstring = ", ".join(r.name for r in ctx.guild.roles
                                if r.id in rsets["exclusive_to"])
            output += (
                f"\nThis role is mutually exclusive to the following roles: {rstring}"
            )
        if rsets["cost"]:
            curr = await bank.get_currency_name(ctx.guild)
            cost = rsets["cost"]
            output += f"\nThis role costs {cost} {curr}"
        else:
            output += "\nThis role does not have an associated cost."

        page_gen = pagify(output)
        try:
            for page in page_gen:
                await ctx.send(page)
        finally:
            page_gen.close()  # type: ignore
Exemple #33
0
    async def alts(self, ctx, ckey: str, check_ips: bool = True):
        """
        Search for a list of possible alt accounts

        This command can take a long time if there are a lot of alt accounts or if your connections table is very large!
        """
        try:
            if check_ips == False:
                await ctx.send(f"{warning('IP check bypassed')}")
            message = await ctx.send("Checking for alts...")
            async with ctx.typing():
                alts = await self.get_alts(ctx, ckey, check_ips)
                if len(alts) > 0:
                    alts = humanize_list(alts)
                    if len(alts) < 1800:
                        await ctx.send(f"Possible alts for {ckey}:\n> {alts}")
                    else:
                        await ctx.send(f"Possible alts for {ckey}:")
                        for page in pagify(alts, delims=[' ']):
                            await ctx.send(f"> {page}")
                else:
                    await ctx.send("No alts detected!")
                await message.delete(
                )  #Deleting over editing since this command can take a while

        except aiomysql.Error as err:
            embed = discord.Embed(title=f"Error looking up alts",
                                  description=f"{format(err)}",
                                  color=0xff0000)
            await ctx.send(embed=embed)
            return await message.delete()  #^

        except RuntimeError:
            embed = discord.Embed(
                title=f"Error looking up alts",
                description="Please check your entry and try again!",
                color=0xff0000)
            await ctx.send(embed=embed)
            return await message.delete()  #^
Exemple #34
0
    async def defenderfreshmeat(self,
                                ctx,
                                hours: int = 24,
                                *,
                                keywords: str = ""):
        """Returns a list of the new users of the day

        Can be filtered. Supports wildcards (* and ?)"""
        keywords = keywords.lower()
        msg = ""
        new_members = []
        x_hours_ago = ctx.message.created_at - datetime.timedelta(hours=hours)
        for m in ctx.guild.members:
            if m.joined_at > x_hours_ago:
                new_members.append(m)

        new_members.sort(key=lambda m: m.joined_at, reverse=True)

        if keywords:
            if "*" not in keywords and "?" not in keywords:
                keywords = f"*{keywords}*"
            keywords = keywords.lower()

        for m in new_members:
            if keywords:
                if not fnmatch.fnmatch(m.name.lower(), keywords):
                    continue
            join = m.joined_at.strftime("%Y/%m/%d %H:%M:%S")
            created = m.created_at.strftime("%Y/%m/%d %H:%M:%S")
            msg += f"J/C: {join}  {created} | {m.id} | {m}\n"

        pages = []
        for p in pagify(msg, delims=["\n"], page_length=1500):
            pages.append(box(p, lang="go"))

        if pages:
            await menu(ctx, pages, DEFAULT_CONTROLS)
        else:
            await ctx.send("Nothing to show.")
Exemple #35
0
    async def _cmdlog_channel_task(self) -> None:
        log.debug("CmdLog channel logger task started.")
        while True:
            try:
                await self._wait_to_next_safe_send_time()
                to_send = [await self._queue.get()]
                while self._queue.empty() is False:
                    to_send.append(self._queue.get_nowait())

                self.last_send = self._utc_now()

                msg = "\n".join(str(i) for i in to_send)
                for page in pagify(msg):
                    await self.channel.send(box(page))

            except Exception as e:
                log.warning(
                    "Something went wrong preparing and sending the messages for the CmdLog "
                    "channel. Some will have been lost, however they will still be available "
                    "under the `[p]cmdlog` command in Discord. Please report this to Vexed.",
                    exc_info=e,
                )
Exemple #36
0
    async def wardengrouplistrules(self, ctx: commands.Context):
        """Lists existing rules"""
        guild = ctx.guild
        text = ""
        rules = {}
        for event in WardenEvent:
            rules[event.value] = self.get_warden_rules_by_event(guild, event)
        for k, v in rules.items():
            rules[k] = [inline(r.name) for r in v]
        rules["invalid"] = []
        for k, v in self.invalid_warden_rules[ctx.guild.id].items():
            rules["invalid"].append(inline(v.name))

        text = "Active Warden rules per event:\n\n"
        events_without_rules = []

        for k, v in rules.items():
            if not v and k != "invalid":
                events_without_rules.append(k.replace("-", " "))
                continue
            if k == "invalid":
                continue
            event_name = k.replace("-", " ").capitalize()
            rule_names = ", ".join(v)
            text += f"**{event_name}**:\n{rule_names}\n"

        if events_without_rules:
            text += "\nThese events have no rules: "
            text += ", ".join(events_without_rules)

        if rules["invalid"]:
            text += f"\n**Invalid rules**:\n{', '.join(rules['invalid'])}\n"
            text += (
                "These rules failed the validation process at the last start. Check if "
                "their format is still considered valid in the most recent version of "
                "Defender.")

        for p in pagify(text, delims=[" ", "\n"]):
            await ctx.send(p)
Exemple #37
0
    async def db_integrity_check(self, ctx):
        """Check Database integrity.

        Everything should be True. Otherwise there is malfunction somewhere in XP handling."""
        c = Counter()
        invalid_users = []
        async with ctx.typing():
            async for user in self.db.users.find({}):
                total_xp = 0
                for server in user["servers"]:
                    xp = await self._level_exp(user["servers"][server]["level"]
                                               )
                    total_xp += xp
                    total_xp += user["servers"][server]["current_exp"]
                valid = total_xp == user["total_exp"]
                c[valid] += 1
                if not valid:
                    invalid_users.append((
                        user["username"],
                        user["user_id"],
                        total_xp,
                        user["total_exp"],
                        user["total_exp"] - total_xp,
                    ))
        await ctx.send(chat.box(tabulate(c.most_common())))
        if invalid_users:
            await ctx.send_interactive(
                chat.pagify(
                    tabulate(
                        invalid_users,
                        headers=[
                            "Username", "ID", "Calculated total XP",
                            "Total XP", "Diff"
                        ],
                    ),
                    page_length=1992,
                ),
                box_lang="",
            )
Exemple #38
0
    async def tag_global_list(self, ctx: commands.Context):
        """View stored tags."""
        tags = self.get_unique_tags()
        if not tags:
            return await ctx.send("There are no global tags.")

        data = self.generate_tag_list(tags)
        aliases = data["aliases"]
        description = data["description"]

        e = discord.Embed(color=await ctx.embed_color())
        e.set_author(name="Global Tags", icon_url=ctx.me.avatar_url)

        embeds = []
        pages = list(pagify("\n".join(description)))
        footer = f"{len(tags)} tags | {len(aliases)} aliases"
        for index, page in enumerate(pages, 1):
            embed = e.copy()
            embed.description = page
            embed.set_footer(text=f"{index}/{len(pages)} | {footer}")
            embeds.append(embed)
        await menu(ctx, embeds, DEFAULT_CONTROLS)
Exemple #39
0
    async def ccrole_list(self, ctx):
        """Shows custom commands list"""
        guild = ctx.guild
        cmd_list = await self.config.guild(guild).cmdlist()
        cmd_list = {k: v for k, v in cmd_list.items() if v}
        if not cmd_list:
            await ctx.send(
                "There are no custom commands in this server. Use `{}ccrole add` to start adding some."
                .format(ctx.prefix))
            return

        cmd_list = ", ".join([ctx.prefix + c for c in sorted(cmd_list.keys())])
        cmd_list = "Custom commands:\n\n" + cmd_list

        if (
                len(cmd_list) < 1500
        ):  # I'm allowed to have arbitrary numbers for when it's too much to dm dammit
            await ctx.send(box(cmd_list))
        else:
            for page in pagify(cmd_list, delims=[" ", "\n"]):
                await ctx.author.send(box(page))
            await ctx.send("Command list DM'd")
Exemple #40
0
    async def bash(self, ctx, *, arg):
        """Bash shell"""
        env = os.environ.copy()
        if hasattr(sys, "real_prefix") or sys.base_prefix != sys.prefix:
            # os.path.sep - this is folder separator, i.e. `\` on win or `/` on unix
            # os.pathsep - this is paths separator in PATH, i.e. `;` on win or `:` on unix
            if sys.platform == "win32":
                binfolder = f"{sys.prefix}{os.path.sep}Scripts"
                env["PATH"] = f"{binfolder}{os.pathsep}{env['PATH']}"
            else:
                binfolder = f"{sys.prefix}{os.path.sep}bin"
                env["PATH"] = f"{binfolder}{os.pathsep}{env['PATH']}"

        proc = await asyncio.create_subprocess_shell(arg,
                                                     stdin=None,
                                                     stderr=STDOUT,
                                                     stdout=PIPE,
                                                     env=env)
        out = await proc.stdout.read()
        msg = pagify(out.decode('utf-8'))
        await ctx.send(f"```ini\n\n[SkyBASH Input]: {arg}\n```")
        await ctx.send_interactive(msg, box_lang="py")
Exemple #41
0
 async def _cog_list(self, ctx, repo: Repo):
     """List all available cogs from a single repo."""
     installed = await self.installed_cogs()
     installed_str = ""
     if installed:
         installed_str = _("Installed Cogs:\n") + "\n".join(
             [
                 "- {}{}".format(i.name, ": {}".format(i.short) if i.short else "")
                 for i in installed
                 if i.repo_name == repo.name
             ]
         )
     cogs = repo.available_cogs
     cogs = _("Available Cogs:\n") + "\n".join(
         [
             "+ {}: {}".format(c.name, c.short or "")
             for c in cogs
             if not (c.hidden or c in installed)
         ]
     )
     cogs = cogs + "\n\n" + installed_str
     for page in pagify(cogs, ["\n"], shorten_by=16):
         await ctx.send(box(page.lstrip(" "), lang="diff"))
Exemple #42
0
    async def ccrole_list(self, ctx):
        """Shows custom commands list"""
        guild = ctx.guild
        cmd_list = await self.config.guild(guild).cmdlist()
        cmd_list = {k: v for k, v in cmd_list.items() if v}
        if not cmd_list:
            await ctx.send(
                "There are no custom commands in this server. Use `{}ccrole add` to start adding some.".format(
                    ctx.prefix
                )
            )
            return

        cmd_list = ", ".join([ctx.prefix + c for c in sorted(cmd_list.keys())])
        cmd_list = "Custom commands:\n\n" + cmd_list

        if (
            len(cmd_list) < 1500
        ):  # I'm allowed to have arbitrary numbers for when it's too much to dm dammit
            await ctx.send(box(cmd_list))
        else:
            for page in pagify(cmd_list, delims=[" ", "\n"]):
                await ctx.author.send(box(page))
            await ctx.send("Command list DM'd")