Example #1
0
    async def command_remove(self, ctx: commands.Context, name):
        """Remove a custom command"""
        owner_id = await self.bot.db.execute(
            "SELECT added_by FROM custom_command WHERE command_trigger = %s AND guild_id = %s",
            name,
            ctx.guild.id,
            one_value=True,
        )
        if not owner_id:
            raise exceptions.CommandWarning(
                f"Custom command `{ctx.prefix}{name}` does not exist")

        owner = ctx.guild.get_member(owner_id)
        if (owner is not None and owner != ctx.author
                and not ctx.author.guild_permissions.manage_guild):
            raise exceptions.CommandWarning(
                f"`{ctx.prefix}{name}` can only be removed by **{owner}** unless you have `manage_server` permission."
            )

        await self.bot.db.execute(
            "DELETE FROM custom_command WHERE guild_id = %s AND command_trigger = %s",
            ctx.guild.id,
            name,
        )
        await util.send_success(
            ctx, f"Custom command `{ctx.prefix}{name}` has been deleted")
Example #2
0
    async def add(self, ctx: commands.Context, name, *, response):
        """Add a new custom command"""
        if not await self.can_add_commands(ctx):
            raise commands.MissingPermissions(["manage_server"])

        if name in self.bot_command_list():
            raise exceptions.CommandWarning(
                f"`{ctx.prefix}{name}` is already a built in command!")
        if await self.bot.db.execute(
                "SELECT content FROM custom_command WHERE guild_id = %s AND command_trigger = %s",
                ctx.guild.id,
                name,
                one_value=True,
        ):
            raise exceptions.CommandWarning(
                f"Custom command `{ctx.prefix}{name}` already exists on this server!"
            )

        await self.bot.db.execute(
            "INSERT INTO custom_command VALUES(%s, %s, %s, %s, %s)",
            ctx.guild.id,
            name,
            response,
            arrow.utcnow().datetime,
            ctx.author.id,
        )
        await util.send_success(
            ctx,
            f"Custom command `{ctx.prefix}{name}` added with the response \n```{response}```",
        )
Example #3
0
    async def big_emoji(self, ctx: commands.Context, emoji):
        """
        Get source image and stats of an emoji

        Will display additional info if Miso is in the server where the emoji is located in.
        Displaying who added the emoji requires Miso to have manage emojis permission!

        Usage:
            >emoji :emoji:
        """
        if emoji[0] == "<":
            emoji = await util.get_emoji(ctx, emoji)
            if emoji is None:
                raise exceptions.CommandWarning("I don't know this emoji!")

            emoji_url = emoji.url
            emoji_name = emoji.name
        else:
            # unicode emoji
            emoji_name = emoji_literals.UNICODE_TO_NAME.get(emoji)
            if emoji_name is None:
                raise exceptions.CommandWarning("I don't know this emoji!")

            codepoint = "-".join(
                f"{ord(e):x}" for e in emoji_literals.NAME_TO_UNICODE.get(emoji_name)
            )
            emoji_name = emoji_name.strip(":")
            emoji_url = f"https://twemoji.maxcdn.com/v/13.0.1/72x72/{codepoint}.png"

        content = discord.Embed(title=f"`:{emoji_name}:`")
        content.set_image(url=emoji_url)
        stats = await util.image_info_from_url(self.bot.session, emoji_url)
        content.set_footer(text=f"Type: {stats['filetype']}")

        if isinstance(emoji, discord.Emoji):
            emoji = await emoji.guild.fetch_emoji(emoji.id)
            desc = [f"Uploaded {arrow.get(emoji.created_at).format('D/M/YYYY')}"]
            if emoji.user:
                desc.append(f"by **{emoji.user}**")
            if ctx.guild != emoji.guild:
                desc.append(f"in **{emoji.guild}**")

            content.description = "\n".join(desc)

        content.set_footer(
            text=f"{stats['filetype']} | {stats['filesize']} | {stats['dimensions']}"
        )
        await ctx.send(embed=content)
Example #4
0
    async def notification_remove(self, ctx: commands.Context, *, keyword):
        """Remove a notification keyword"""
        if ctx.guild is None:
            raise exceptions.CommandWarning(
                "Please use this in the guild you want to remove notifications from."
            )

        try:
            await ctx.message.delete()
        except (discord.Forbidden, discord.NotFound):
            pass
        guild_id = ctx.guild.id
        keyword = keyword.lower().strip()

        check = await self.bot.db.execute(
            """
            SELECT * FROM notification WHERE guild_id = %s AND user_id = %s AND keyword = %s
            """,
            guild_id,
            ctx.author.id,
            keyword,
        )
        if not check:
            raise exceptions.CommandWarning(
                "You don't have such notification!")

        try:
            await util.send_success(
                ctx.author,
                f"The keyword notification for `{keyword}` that you set in **{ctx.guild.name}** has been removed.",
            )
        except discord.errors.Forbidden:
            raise exceptions.CommandWarning(
                "I was unable to send you a DM! Please change your settings.")

        await self.bot.db.execute(
            """
            DELETE FROM notification WHERE guild_id = %s AND user_id = %s AND keyword = %s
            """,
            guild_id,
            ctx.author.id,
            keyword,
        )

        # remake notification cache
        await self.create_cache()
        await util.send_success(
            ctx, f"Removed a notification! Check your DM {emojis.VIVISMIRK}")
Example #5
0
    async def rolepicker_remove(self, ctx: commands.Context, *, name):
        """Remove a role from the rolepicker"""
        role_id = await self.bot.db.execute(
            """
            SELECT role_id FROM rolepicker_role WHERE guild_id = %s AND role_name = %s
            """,
            ctx.guild.id,
            name.lower(),
            one_value=True,
        )
        if not role_id:
            raise exceptions.CommandWarning(
                f"Could not find role with the name `{name}` in the picker.")

        await self.bot.db.execute(
            """
            DELETE FROM rolepicker_role WHERE guild_id = %s AND role_name = %s
            """,
            ctx.guild.id,
            name.lower(),
        )
        await util.send_success(
            ctx,
            f"<@&{role_id}> can no longer be acquired from the rolepicker channel.",
        )
Example #6
0
    async def purge(self, ctx: commands.Context, amount: int):
        """
        Delete given amount of messages in the current channel

        Optionally if users are mentioned, only messages by those users are deleted.

        Usage:
            >purge <amount> [mentions...]
        """
        if amount > 100:
            raise exceptions.CommandWarning(
                "You cannot delete more than 100 messages at a time.")

        await ctx.message.delete()

        if ctx.message.mentions:
            deleted = []
            async for message in ctx.channel.history(limit=100,
                                                     oldest_first=False):
                if message.author in ctx.message.mentions:
                    deleted.append(message)
                    if len(deleted) >= amount:
                        break
            try:
                await ctx.channel.delete_messages(deleted)
            except discord.errors.HTTPException:
                raise exceptions.CommandError(
                    "You can only delete messages that are under 14 days old.")
        else:
            deleted = await ctx.channel.purge(limit=amount)

        await ctx.send(
            f":put_litter_in_its_place: Deleted `{len(deleted)}` messages.",
            delete_after=5,
        )
Example #7
0
    async def tz_list(self, ctx: commands.Context):
        """List current time of all server members who have it saved"""
        content = discord.Embed(
            title=f":clock2: Current time in {ctx.guild}",
            color=int("3b88c3", 16),
        )
        rows = []
        user_ids = [user.id for user in ctx.guild.members]
        data = await self.bot.db.execute(
            "SELECT user_id, timezone FROM user_settings WHERE user_id IN %s AND timezone IS NOT NULL",
            user_ids,
        )
        if not data:
            raise exceptions.CommandWarning(
                "No one on this server has set their timezone yet!")

        dt_data = []
        for user_id, tz_str in data:
            dt_data.append((arrow.now(tz_str), ctx.guild.get_member(user_id)))

        for dt, member in sorted(dt_data, key=lambda x: int(x[0].format("Z"))):
            if member is None:
                continue
            rows.append(
                f"{dt.format('MMM Do HH:mm')} - **{util.displayname(member)}**"
            )

        await util.send_as_pages(ctx, content, rows)
Example #8
0
    async def unmute(self, ctx: commands.Context, member: discord.Member):
        """Unmute user"""
        mute_role_id = await self.bot.db.execute(
            """
            SELECT mute_role_id FROM guild_settings WHERE guild_id = %s
            """,
            ctx.guild.id,
            one_value=True,
        )
        mute_role = ctx.guild.get_role(mute_role_id)
        if not mute_role:
            raise exceptions.CommandWarning(
                "Mute role for this server has been deleted or is not set, "
                f"please use `{ctx.prefix}muterole <role>` to set it.")
        try:
            await member.remove_roles(mute_role)
        except discord.errors.Forbidden:
            raise exceptions.CommandError(
                f"It seems I don't have permission to unmute {member.mention}")

        await util.send_success(ctx, f"Unmuted {member.mention}")
        await self.bot.db.execute(
            """
            DELETE FROM muted_user WHERE guild_id = %s AND user_id = %s
            """,
            ctx.guild.id,
            member.id,
        )
        self.cache_needs_refreshing = True
Example #9
0
    async def tz_set(self, ctx: commands.Context, your_timezone):
        """
        Set your timezone
        Give timezone as a tz database name (case sensitive):
        https://en.wikipedia.org/wiki/List_of_tz_database_time_zones

        Example:
            >timezone set Europe/Helsinki
        """
        try:
            ts = arrow.now(your_timezone)
        except arrow.ParserError as e:
            raise exceptions.CommandWarning(str(e), help_footer=True)
        await ctx.bot.db.execute(
            """
            INSERT INTO user_settings (user_id, timezone)
                VALUES (%s, %s)
            ON DUPLICATE KEY UPDATE
                timezone = VALUES(timezone)
            """,
            ctx.author.id,
            your_timezone,
        )
        await util.send_success(
            ctx,
            f"Saved your timezone as **{your_timezone}**\n:clock2: Current time: **{ts.ctime()}**",
        )
Example #10
0
    async def editprofile_color(self, ctx: commands.Context, color):
        """
        Set a background color to be used instead of your role color.
        Set as default to use role color again.
        """
        if color.lower() == "default":
            color_value = None
        else:
            color = "#" + color.strip("#")
            color_hex = await util.get_color(ctx, color)
            if color_hex is None:
                raise exceptions.CommandWarning(f"Invalid color {color}")

            color_value = str(color_hex).strip("#")

        await self.bot.db.execute(
            """
            INSERT INTO user_profile (user_id, background_color)
                VALUES (%s, %s)
            ON DUPLICATE KEY UPDATE
                background_color = VALUES(background_color)
            """,
            ctx.author.id,
            color_value,
        )
        await util.send_success(
            ctx,
            f"Profile background color set to `{color_value or 'default'}`!")
Example #11
0
    async def serverbanner(self, ctx: commands.Context):
        """Get server's banner"""
        guild = ctx.guild
        content = discord.Embed()

        if not guild.banner:
            raise exceptions.CommandWarning("This server has no banner")

        content.set_author(
            name=f"{guild} Banner",
            url=guild.banner.url,
            icon_url=guild.icon.url if guild.icon else None,
        )

        content.set_image(url=guild.banner.url)
        stats = await util.image_info_from_url(self.bot.session,
                                               guild.banner.url)
        color = await util.color_from_image_url(
            self.bot.session,
            guild.banner.replace(size=64, format="png").url)
        content.colour = int(color, 16)
        if stats is not None:
            content.set_footer(
                text=
                f"{stats['filetype']} | {stats['filesize']} | {stats['dimensions']}"
            )

        await ctx.send(embed=content)
Example #12
0
    async def starboard_emoji(self, ctx: commands.Context, emoji):
        """Change the emoji to use for starboard"""
        if emoji[0] == "<":
            # is custom emoji
            emoji_obj = await util.get_emoji(ctx, emoji)
            if emoji_obj is None:
                raise exceptions.CommandWarning("I don't know this emoji!")

            await self.bot.db.execute(
                """
                INSERT INTO starboard_settings (guild_id, emoji_name, emoji_id, emoji_type)
                    VALUES (%s, %s, %s, %s)
                ON DUPLICATE KEY UPDATE
                    emoji_name = VALUES(emoji_name),
                    emoji_id = VALUES(emoji_id),
                    emoji_type = VALUES(emoji_type)
                """,
                ctx.guild.id,
                None,
                emoji_obj.id,
                "custom",
            )
            await util.send_success(
                ctx,
                f"Starboard emoji is now {emoji} (emoji id `{emoji_obj.id}`)")
        else:
            # unicode emoji
            emoji_name = emoji_literals.UNICODE_TO_NAME.get(emoji)
            if emoji_name is None:
                raise exceptions.CommandWarning("I don't know this emoji!")

            await self.bot.db.execute(
                """
                INSERT INTO starboard_settings (guild_id, emoji_name, emoji_id, emoji_type)
                    VALUES (%s, %s, %s, %s)
                ON DUPLICATE KEY UPDATE
                    emoji_name = VALUES(emoji_name),
                    emoji_id = VALUES(emoji_id),
                    emoji_type = VALUES(emoji_type)
                """,
                ctx.guild.id,
                emoji_name,
                None,
                "unicode",
            )
            await util.send_success(ctx, f"Starboard emoji is now {emoji}")
        await self.bot.cache.cache_starboard_settings()
Example #13
0
    async def starboard_current(self, ctx: commands.Context):
        """See the current starboard configuration"""
        starboard_settings = self.bot.cache.starboard_settings.get(
            str(ctx.guild.id))
        if not starboard_settings:
            raise exceptions.CommandWarning(
                "Nothing has been configured on this server yet!")

        (
            is_enabled,
            board_channel_id,
            required_reaction_count,
            emoji_name,
            emoji_id,
            emoji_type,
            log_channel_id,
        ) = starboard_settings

        if emoji_type == "custom":
            emoji = self.bot.get_emoji(emoji_id)
        else:
            emoji = emoji_name

        blacklisted_channels = await self.bot.db.execute(
            """
            SELECT channel_id FROM starboard_blacklist WHERE guild_id = %s
            """,
            ctx.guild.id,
            as_list=True,
        )

        content = discord.Embed(title=":star: Current starboard settings",
                                color=int("ffac33", 16))
        content.add_field(
            name="State",
            value=":white_check_mark: Enabled"
            if is_enabled else ":x: Disabled",
        )
        content.add_field(name="Emoji", value=emoji)
        content.add_field(name="Reactions required",
                          value=required_reaction_count)
        content.add_field(
            name="Board channel",
            value=f"<#{board_channel_id}>"
            if board_channel_id is not None else None,
        )
        content.add_field(
            name="Log channel",
            value=f"<#{log_channel_id}>"
            if log_channel_id is not None else None,
        )
        content.add_field(
            name="Blacklisted channels",
            value=" ".join(f"<#{cid}>" for cid in blacklisted_channels)
            if blacklisted_channels else None,
        )

        await ctx.send(embed=content)
Example #14
0
    async def unban(self, ctx: commands.Context, *discord_users):
        """Unban user(s)"""
        if not discord_users:
            return await util.send_command_help(ctx)

        if len(discord_users) == 1:
            user = await util.get_user(ctx, discord_users[0])
            if user is None:
                try:
                    user = await self.bot.fetch_user(int(user))
                except (ValueError, discord.NotFound):
                    raise exceptions.CommandError(
                        f"Invalid user or id `{user}`")
            try:
                await ctx.guild.unban(user)
            except discord.errors.Forbidden:
                raise exceptions.CommandError(
                    f"It seems I don't have the permission to unban **{user}** {user.mention}"
                )
            except discord.errors.NotFound:
                raise exceptions.CommandWarning(
                    f"Unable to unban. **{user}** is not banned")
            else:
                return await util.send_success(
                    ctx, f"Unbanned **{user}** {user.mention}")

        success = []
        failure = []
        for discord_user in discord_users:
            user = await util.get_user(ctx, discord_user)
            if user is None:
                try:
                    user = await self.bot.fetch_user(int(discord_user))
                except (ValueError, discord.NotFound):
                    failure.append(f"`{discord_user}` Invalid user or id")
                    continue

            try:
                await ctx.guild.unban(user)
            except discord.errors.Forbidden:
                failure.append(f"`{user}` No permission to unban")
            except discord.errors.NotFound:
                failure.append(f"`{user}` is not banned")
            else:
                success.append(f"`{user}` Unbanned")

        await util.send_tasks_result_list(
            ctx, success, failure,
            f":memo: Attempting to unban {len(discord_users)} users...")
Example #15
0
    async def blacklist_guild(self, ctx: commands.Context, guild_id: int, *,
                              reason):
        """Blacklist a guild from adding or using Miso Bot"""
        guild = self.bot.get_guild(guild_id)
        if guild is None:
            raise exceptions.CommandWarning(
                f"Cannot find guild with id `{guild_id}`")

        await self.bot.db.execute(
            "INSERT IGNORE blacklisted_guild VALUES (%s, %s)", guild.id,
            reason)
        self.bot.cache.blacklist["global"]["guild"].add(guild_id)
        await guild.leave()
        await util.send_success(ctx,
                                f"**{guild}** can no longer use Miso Bot!")
Example #16
0
    async def emojify(self, ctx: commands.Context, *, text):
        """Emojify your message"""
        request_data = {"density": 100, "input": text, "shouldFilterEmojis": False}
        async with self.bot.session.post(
            "https://api.emojify.net/convert",
            json=request_data,
            headers={"Content-Type": "application/json"},
        ) as response:
            data = await response.json(loads=orjson.loads)
            result = data.get("result")

            try:
                await ctx.send(result)
            except discord.errors.HTTPException:
                raise exceptions.CommandWarning("Your text when emojified is too long to send!")
Example #17
0
    async def prefix(self, ctx: commands.Context, prefix):
        """
        Set a custom command prefix for this server

        Usage:
            >prefix <text>
            >prefix \"<text with spaces>\"
        """
        if prefix.strip() == "":
            raise exceptions.CommandWarning("Prefix cannot be empty.")

        if prefix.startswith(" "):
            raise exceptions.CommandWarning(
                "Prefix cannot start with a space.")

        if len(prefix) > 32:
            raise exceptions.CommandWarning(
                "Prefix cannot be over 32 characters.")

        prefix = prefix.lstrip()
        await self.bot.db.execute(
            """
            INSERT INTO guild_prefix (guild_id, prefix)
                VALUES (%s, %s)
            ON DUPLICATE KEY UPDATE
                prefix = VALUES(prefix)
            """,
            ctx.guild.id,
            prefix,
        )
        self.bot.cache.prefixes[str(ctx.guild.id)] = prefix
        await util.send_success(
            ctx,
            f"Command prefix for this server is now `{prefix}`. "
            f"Example command usage: {prefix}ping",
        )
Example #18
0
    async def unblacklist_command(self, ctx: commands.Context, *, command):
        """Unblacklist a command"""
        cmd = self.bot.get_command(command)
        if cmd is None:
            raise exceptions.CommandWarning(
                f"Command `{ctx.prefix}{command}` not found.")

        await self.bot.db.execute(
            "DELETE FROM blacklisted_command WHERE guild_id = %s AND command_name = %s",
            ctx.guild.id,
            cmd.qualified_name,
        )
        self.bot.cache.blacklist[str(ctx.guild.id)]["command"].discard(
            cmd.qualified_name.lower())
        await util.send_success(
            ctx, f"`{ctx.prefix}{cmd}` is no longer blacklisted.")
Example #19
0
    async def get(self, ctx, *links):
        """Manually get tweets."""
        if len(links) > 10:
            raise exceptions.CommandWarning("Only 10 links at a time please!")

        for tweet_url in links:
            if "status" in tweet_url:
                tweet_id = re.search(r"status/(\d+)", tweet_url).group(1)
            else:
                tweet_id = tweet_url

            await self.twitter_renderer.send_tweet(int(tweet_id), channels=[ctx.channel])

        try:
            await ctx.message.edit(suppress=True)
        except (discord.Forbidden, discord.NotFound):
            pass
Example #20
0
    async def creategif(self, ctx: commands.Context, media_url):
        """Create a gfycat gif from video url"""
        starttimer = time()
        auth_headers = await gfycat_oauth(self.bot.session)
        url = "https://api.gfycat.com/v1/gfycats"
        params = {"fetchUrl": media_url.strip("`")}
        async with self.bot.session.post(url,
                                         json=params,
                                         headers=auth_headers) as response:
            data = await response.json(loads=orjson.loads)

        try:
            gfyname = data["gfyname"]
        except KeyError:
            raise exceptions.CommandWarning(
                "Unable to create gif from this link!")

        message = await ctx.send(f"Encoding {emojis.LOADING}")

        i = 1
        url = f"https://api.gfycat.com/v1/gfycats/fetch/status/{gfyname}"
        await asyncio.sleep(5)
        while True:
            async with self.bot.session.get(url,
                                            headers=auth_headers) as response:
                data = await response.json(loads=orjson.loads)
                task = data["task"]

            if task == "encoding":
                pass

            elif task == "complete":
                await message.edit(
                    content=
                    f"Gif created in **{util.stringfromtime(time() - starttimer, 2)}**"
                    f"\nhttps://gfycat.com/{data['gfyname']}")
                break

            else:
                await message.edit(
                    content="There was an error while creating your gif :(")
                break

            await asyncio.sleep(i)
            i += 1
Example #21
0
    async def tz_now(self,
                     ctx: commands.Context,
                     member: discord.Member = None):
        """Get current time for a member"""
        if member is None:
            member = ctx.author

        tz_str = await self.bot.db.execute(
            "SELECT timezone FROM user_settings WHERE user_id = %s",
            member.id,
            one_value=True,
        )
        if tz_str:
            dt = arrow.now(tz_str)
            await ctx.send(f":clock2: **{dt.format('MMM Do HH:mm')}**")
        else:
            raise exceptions.CommandWarning(
                f"{member} has not set their timezone yet!")
Example #22
0
    async def banner(self,
                     ctx: commands.Context,
                     *,
                     user: discord.User = None):
        """Get user's banner"""
        if user is None:
            user = ctx.author

        # banners are not cached so an api call is required
        user = await self.bot.fetch_user(user.id)

        content = discord.Embed()

        if not user.banner:
            if not user.accent_color:
                raise exceptions.CommandWarning(
                    f"**{user}** has not set banner or accent color.")

            content.color = user.accent_color
            content.description = f":art: Solid color `{user.accent_color}`"
            content.set_author(name=f"{user} Banner",
                               icon_url=user.display_avatar.url)
            return await ctx.send(embed=content)

        content.set_author(name=f"{user} Banner",
                           url=user.banner.url,
                           icon_url=user.display_avatar.url)

        content.set_image(url=user.banner.url)
        stats = await util.image_info_from_url(self.bot.session,
                                               user.banner.url)
        color = await util.color_from_image_url(
            self.bot.session,
            user.banner.replace(size=64, format="png").url)
        content.colour = int(color, 16)
        if stats is not None:
            content.set_footer(
                text=
                f"{stats['filetype']} | {stats['filesize']} | {stats['dimensions']}"
            )

        await ctx.send(embed=content)
Example #23
0
    async def notification_test(self,
                                ctx: commands.Context,
                                message: discord.Message = None):
        """
        Test if Miso can send you a notification
        If supplied with a message id, will check if you would have been notified by it.
        """
        if message is None:
            try:
                await self.send_notification(ctx.author,
                                             message or ctx.message, ["test"],
                                             test=True)
                await ctx.send(":ok_hand: Check your DM")
            except discord.errors.Forbidden:
                raise exceptions.CommandWarning(
                    "I was unable to send you a DM! Please check your privacy settings."
                )
        else:
            if ctx.author not in message.channel.members:
                raise exceptions.CommandError("You cannot see this message.")

            keywords = await self.bot.db.execute(
                "SELECT keyword FROM notification WHERE user_id = %s",
                ctx.author.id,
                as_list=True,
            )

            pattern = regex.compile(self.keyword_regex,
                                    words=keywords,
                                    flags=regex.IGNORECASE)

            finds = pattern.findall(message.content)
            if not finds:
                await ctx.send(":x: This message would not notify you")
            else:
                keywords = list(set(finds))
                await self.send_notification(ctx.author,
                                             message,
                                             keywords,
                                             test=True)
                await ctx.send(":ok_hand: Check your DM")
Example #24
0
    async def notification_list(self, ctx: commands.Context):
        """List your current notifications"""
        words = await self.bot.db.execute(
            """
            SELECT guild_id, keyword, times_triggered FROM notification WHERE user_id = %s ORDER BY keyword
            """,
            ctx.author.id,
        )

        if not words:
            raise exceptions.CommandInfo(
                "You have not set any notifications yet!")

        content = discord.Embed(
            title=f":love_letter: You have {len(words)} notifications",
            color=int("dd2e44", 16),
        )

        rows = []
        for guild_id, keyword, times_triggered in sorted(words):
            guild = self.bot.get_guild(guild_id)
            if guild is None:
                guild = f"[Unknown server `{guild_id}`]"

            rows.append(
                f"**{guild}** : `{keyword}` - Triggered **{times_triggered}** times"
            )

        try:
            await util.send_as_pages(ctx.author,
                                     content,
                                     rows,
                                     maxpages=1,
                                     maxrows=50)
        except discord.errors.Forbidden:
            raise exceptions.CommandWarning(
                "I was unable to send you a DM! Please change your settings.")

        if ctx.guild is not None:
            await util.send_success(
                ctx, f"Notification list sent to your DM {emojis.VIVISMIRK}")
Example #25
0
    async def editprofile_description(self, ctx: commands.Context, *, text):
        """Change the description on your profile"""
        if text.strip() == "":
            return await util.send_command_help(ctx)

        if len(text) > 500:
            raise exceptions.CommandWarning(
                f"Description cannot be more than 500 characters ({len(text)})"
            )

        await self.bot.db.execute(
            """
            INSERT INTO user_profile (user_id, description)
                VALUES (%s, %s)
            ON DUPLICATE KEY UPDATE
                description = VALUES(description)
            """,
            ctx.author.id,
            text,
        )
        await util.send_success(ctx, "Profile description updated!")
Example #26
0
    async def command_clear(self, ctx: commands.Context):
        """Delete all custom commands on this server"""
        count = (await self.bot.db.execute(
            "SELECT COUNT(*) FROM custom_command WHERE guild_id = %s",
            ctx.guild.id,
            one_value=True,
        ) or 0)
        if count < 1:
            raise exceptions.CommandWarning(
                "This server has no custom commands yet!")

        content = discord.Embed(title=":warning: Are you sure?",
                                color=int("ffcc4d", 16))
        content.description = f"This action will delete all **{count}** custom commands on this server and is **irreversible**."
        msg = await ctx.send(embed=content)

        async def confirm():
            await self.bot.db.execute(
                "DELETE FROM custom_command WHERE guild_id = %s",
                ctx.guild.id,
            )
            content.title = f":white_check_mark: Cleared commands in {ctx.guild}"
            content.description = ""
            content.color = int("77b255", 16)
            await msg.edit(embed=content)

        async def cancel():
            content.title = ":x: Action cancelled"
            content.description = ""
            content.color = int("dd2e44", 16)
            await msg.edit(embed=content)

        functions = {"✅": confirm, "�": cancel}
        asyncio.ensure_future(
            util.reaction_buttons(ctx,
                                  msg,
                                  functions,
                                  only_author=True,
                                  single_use=True))
Example #27
0
    async def inspect(self, ctx: commands.Context, *ids: int):
        """Resolve user ids into usernames"""
        if len(ids) > 25:
            raise exceptions.CommandWarning("Only 25 at a time please!")
        rows = []
        for user_id in ids:
            user = self.bot.get_user(user_id)
            if user is None:
                try:
                    user = await self.bot.fetch_user(user_id)
                except discord.errors.NotFound:
                    user = None

            if user is None:
                rows.append(f"`{user_id}` -> ?")
            else:
                rows.append(f"`{user_id}` -> {user} {user.mention}")

        content = discord.Embed(
            title=f":face_with_monocle: Inspecting {len(ids)} users...",
            color=int("bdddf4", 16),
        )
        await util.send_as_pages(ctx, content, rows, maxrows=25)
Example #28
0
    async def votechannel_add(self,
                              ctx: commands.Context,
                              channel: discord.TextChannel,
                              reaction_type=None):
        """
        Set a channel to be a voting channel.

        Available types: [ vote | rate ]
        Defaults to vote.
        """
        if reaction_type is None:
            channel_type = "voting"
        elif reaction_type.lower() in ["rate", "rating"]:
            channel_type = "rating"
        elif reaction_type.lower() in ["vote", "voting"]:
            channel_type = "voting"
        else:
            raise exceptions.CommandWarning(
                f"Unknown reaction type `{reaction_type}`", help_footer=True)

        await self.bot.db.execute(
            """
            INSERT INTO voting_channel (guild_id, channel_id, voting_type)
                VALUES (%s, %s, %s)
            ON DUPLICATE KEY UPDATE
                voting_type = VALUES(voting_type)
            """,
            ctx.guild.id,
            channel.id,
            channel_type,
        )
        self.bot.cache.votechannels.add(channel.id)
        await util.send_success(
            ctx,
            f"{channel.mention} is now a voting channel of type `{channel_type}`"
        )
Example #29
0
    async def servericon(self, ctx: commands.Context, guild: int = None):
        """Get the icon of the server"""
        if guild is not None:
            guild = self.bot.get_guild(guild)
        if guild is None:
            guild = ctx.guild

        if guild.icon is None:
            raise exceptions.CommandWarning("This server has no icon.")

        content = discord.Embed()
        content.set_author(name=str(guild), url=guild.icon.url)
        content.set_image(url=guild.icon.url)
        stats = await util.image_info_from_url(self.bot.session, guild.icon.url)
        color = await util.color_from_image_url(
            self.bot.session, str(guild.icon.replace(size=64, format="png"))
        )
        content.colour = int(color, 16)
        if stats is not None:
            content.set_footer(
                text=f"{stats['filetype']} | {stats['filesize']} | {stats['dimensions']}"
            )

        await ctx.send(embed=content)
Example #30
0
    async def blacklist_command(self, ctx: commands.Context, *, command):
        """Blacklist a command"""
        cmd = self.bot.get_command(command)
        if cmd is None:
            raise exceptions.CommandWarning(
                f"Command `{ctx.prefix}{command}` not found.")

        await self.bot.db.execute(
            "INSERT IGNORE blacklisted_command VALUES (%s, %s)",
            cmd.qualified_name,
            ctx.guild.id,
        )
        try:
            self.bot.cache.blacklist[str(ctx.guild.id)]["command"].add(
                cmd.qualified_name.lower())
        except KeyError:
            self.bot.cache.blacklist[str(ctx.guild.id)] = {
                "member": set(),
                "command": {cmd.qualified_name.lower()},
            }
        await util.send_success(
            ctx,
            f"`{ctx.prefix}{cmd}` is now a blacklisted command on this server."
        )