Esempio n. 1
0
    async def chatchart(self, ctx, channel: discord.TextChannel = None, messages=5000):
        """
        Generates a pie chart, representing the last 5000 messages in the specified channel.
        """
        e = discord.Embed(description="Loading...", colour=0x00CCFF)
        e.set_thumbnail(url="https://i.imgur.com/vSp4xRk.gif")
        em = await ctx.send(embed=e)

        if channel is None:
            channel = ctx.message.channel
        history = []
        if not channel.permissions_for(ctx.message.author).read_messages == True:
            await em.delete()
            return await ctx.send("You're not allowed to access that channel.")
        try:
            async for msg in channel.history(limit=messages):
                history.append(msg)
        except discord.errors.Forbidden:
            await em.delete()
            return await ctx.send("No permissions to read that channel.")
        msg_data = {"total count": 0, "users": {}}

        for msg in history:
            if len(msg.author.name) >= 20:
                short_name = "{}...".format(msg.author.name[:20])
            else:
                short_name = msg.author.name
            whole_name = "{}#{}".format(short_name, msg.author.discriminator)
            if msg.author.bot:
                pass
            elif whole_name in msg_data["users"]:
                msg_data["users"][whole_name]["msgcount"] += 1
                msg_data["total count"] += 1
            else:
                msg_data["users"][whole_name] = {}
                msg_data["users"][whole_name]["msgcount"] = 1
                msg_data["total count"] += 1

        for usr in msg_data["users"]:
            pd = float(msg_data["users"][usr]["msgcount"]) / float(msg_data["total count"])
            msg_data["users"][usr]["percent"] = round(pd * 100, 1)

        top_ten = heapq.nlargest(
            20,
            [
                (x, msg_data["users"][x][y])
                for x in msg_data["users"]
                for y in msg_data["users"][x]
                if y == "percent"
            ],
            key=lambda x: x[1],
        )
        others = 100 - sum(x[1] for x in top_ten)
        img = self.create_chart(top_ten, others, channel)
        await em.delete()
        await ctx.message.channel.send(file=discord.File(img, "chart.png"))
Esempio n. 2
0
    async def modlog(self, ctx: commands.Context, channel: discord.TextChannel = None):
        """Set a channel as the modlog.

        Omit `<channel>` to disable the modlog.
        """
        guild = ctx.guild
        if channel:
            if channel.permissions_for(guild.me).send_messages:
                await modlog.set_modlog_channel(guild, channel)
                await ctx.send(
                    _("Mod events will be sent to {channel}").format(channel=channel.mention)
                )
            else:
                await ctx.send(
                    _("I do not have permissions to send messages in {channel}!").format(
                        channel=channel.mention
                    )
                )
        else:
            try:
                await modlog.get_modlog_channel(guild)
            except RuntimeError:
                await ctx.send_help()
            else:
                await modlog.set_modlog_channel(guild, None)
                await ctx.send(_("Mod log deactivated."))
Esempio n. 3
0
    async def _roles_add(
        self,
        ctx: Context,
        message_id: int,
        channel: discord.TextChannel,
        emoji,
        *,
        role: discord.Role
    ):
        """Add a role on a message

        `message_id` must be found in `channel`
            To get a message's id: Settings > Appearance > Developer mode then
            Right click a message > Copy ID
        `emoji` can either be a Unicode emoji or a server emote
        `role` must be found in the channel's server"""
        guild = channel.guild
        message = await self.safe_get_message(channel, message_id)
        if message is None:
            response = self.MESSAGE_NOT_FOUND
        elif guild is None:
            response = self.NOT_IN_SERVER
        elif role.guild != channel.guild:
            response = self.ROLE_NOT_FOUND
        elif channel.guild.me.guild_permissions.manage_roles is False:
            response = self.CANT_MANAGE_ROLES
        elif channel.permissions_for(channel.guild.me).add_reactions is False:
            response = self.CANT_ADD_REACTIONS
        else:
            msg_conf = self.get_message_config(channel.id, message.id)
            emoji_match = self.EMOTE_REGEX.fullmatch(emoji)
            emoji_id = emoji if emoji_match is None else emoji_match.group(1)
            if emoji_id in await msg_conf({}):
                response = self.ALREADY_BOUND
            else:
                emoji = None
                if emoji_id.isdigit():
                    for emoji_server in self.bot.guilds:
                        if emoji is None:
                            emoji = discord.utils.get(emoji_server.emojis, id=int(emoji_id))
                try:
                    await message.add_reaction(emoji or emoji_id)
                except discord.HTTPException:  # Failed to find the emoji
                    response = self.EMOJI_NOT_FOUND
                else:
                    try:
                        await ctx.message.author.add_roles(role)
                        await ctx.message.author.remove_roles(role)
                    except (discord.Forbidden, discord.HTTPException):
                        response = self.CANT_GIVE_ROLE
                        await message.remove_reaction(emoji or emoji_id, self.bot.user)
                    else:
                        self.add_to_message_cache(channel.id, message_id, message)
                        self.add_to_cache(guild.id, channel.id, message_id, emoji_id, role)
                        await msg_conf.get_attr(emoji_id).set(role.id)
                        response = self.ROLE_SUCCESSFULLY_BOUND.format(
                            emoji or emoji_id, channel.mention
                        )
        await ctx.send(response)
Esempio n. 4
0
 async def post_game_start(self, channel: discord.TextChannel, msg: str) -> None:
     if not channel.permissions_for(channel.guild.me).send_messages:
         log.debug(f"No permission to send messages in {channel} ({channel.id})")
         return
     try:
         await channel.send(msg)
     except Exception:
         log.exception(f"Could not post goal in {channel} ({channel.id})")
Esempio n. 5
0
    async def channel(self, ctx, channel: discord.TextChannel = None):
        """Set the channel to send AltDentifier join checks to.

        This also works as a toggle, so if no channel is provided, it will disable join checks for this server."""
        if not channel:
            await self.config.guild(ctx.guild).channel.clear()
            await ctx.send("Disabled AltDentifier join checks in this server.")
        else:
            if not (channel.permissions_for(ctx.me).send_messages
                    and channel.permissions_for(ctx.me).send_messages):
                await ctx.send(
                    "I do not have permission to talk/send embeds in that channel."
                )
            else:
                await self.config.guild(ctx.guild).channel.set(channel.id)
        await self.build_cache()
        await ctx.tick()
Esempio n. 6
0
 async def dumpchannel(self, ctx, channel: TextChannel, limit=100):
     """Dump 100 messages from a channel to a file."""
     await ctx.send(f"Dumping {limit} messages from {channel.mention}")
     os.makedirs(f"#{channel.name}-{channel.id}", exist_ok=True)
     async for message in channel.history(limit=limit):
         with open(f"#{channel.name}-{channel.id}/{message.id}.txt", "w") as f:
             f.write(message.content)
     await ctx.send("Done!")
Esempio n. 7
0
 async def lvlchannel(self, ctx, channel: discord.TextChannel):
     if not channel.permissions_for(ctx.guild.me).send_messages:
         return await ctx.send(
             f"**I must have Send Messages on channel: {str(channel)} in order to use this command"
         )
     await self.settings.set_setting(ctx.guild, "lvlchannel", channel.id)
     return await ctx.send(
         f"**Successfully set the level channel for {ctx.guild}.**")
Esempio n. 8
0
async def get_pinned_messages_time_period(channel: discord.TextChannel, days):
    pinned = []
    search_duration = datetime.datetime.now() - datetime.timedelta(days=days)
    async for message in channel.history(limit=None, after=search_duration):
        link_split = message.content.split("\n")[0].split("/")
        og_message_id = link_split[len(link_split) - 1]
        pinned.append(og_message_id)
    return pinned
Esempio n. 9
0
    async def purge_message_list(self, channel: discord.TextChannel,
                                 message_list: typing.List[discord.Message]):
        """Delete a list of messages from the channel"""

        await channel.purge(
            check=lambda m: m.id in [i.id for i in message_list],
            bulk=channel.permissions_for(channel.guild.me).manage_messages)
        message_list.clear()
Esempio n. 10
0
 async def messagecount(self, ctx, channel: discord.TextChannel = None):
     channel = channel or ctx.channel
     async with ctx.channel.typing():
         count = 0
         async for _ in channel.history(limit=None):
             count += 1
         await ctx.reply(f"There are {count} messages in {channel.mention}."
                         )
Esempio n. 11
0
	async def send_message(self, channel: discord.TextChannel, message: str, delay=0.01):
		"""Sends a message to a channel with discord.typing()"""
		try:
			async with channel.typing():
				await asyncio.sleep(len(message) * delay)
				await self.bot.send_filtered(channel, content=message)
		except discord.Forbidden:
			pass  # Not allowed to send messages in this channel
Esempio n. 12
0
 async def total_messages(self, ctx, channel: discord.TextChannel = None):
     channel = channel or ctx.channel
     count = 0
     async for _ in channel.history(limit=None):
         count += 1
     embed = discord.Embed(
         title="Total Messages", description=f"Total messages sent in {channel.mention}: {count}", color=discord.Colour.purple())
     await ctx.channel.send(embed=embed)
Esempio n. 13
0
async def construct_fake_context(bot, channel: discord.TextChannel, author):
    for msg in channel.history(limit=2):
        ctx = await bot.get_context(msg)
        ctx.command = bot.get_command("bump")
        ctx.author = author
        break

    return ctx  # says undefined, f**k off pycharm it IS defined.
Esempio n. 14
0
    def send_error_embed(self,
                         channel: discord.TextChannel,
                         description: str = None,
                         title: str = "Ошибка"):
        embed = self.get_special_embed(0xFF4C4C, title=title)
        embed.description = description

        return channel.send(embed=embed)
Esempio n. 15
0
async def fetch_status_message(channel: TextChannel) -> Optional[Message]:
    out = None
    async for message in channel.history(limit=None):
        if out is None and message.author == bot.user:
            out = message
        else:
            await message.delete()
    return out
Esempio n. 16
0
    def send_ok_embed(self,
                      channel: discord.TextChannel,
                      description: str = None,
                      title: str = "ОК"):
        embed = self.get_special_embed(0x6AAF6A, title=title)
        embed.description = description

        return channel.send(embed=embed)
Esempio n. 17
0
    async def setup_starboard(
        self,
        ctx: commands.Context,
        name: str,
        channel: discord.TextChannel = None,
        emoji: Union[discord.Emoji, str] = "⭐",
    ) -> None:
        """
            Create a starboard on this server

            `<name>` is the name for the starboard and will be lowercase only
            `[channel]` is the channel where posts will be made defaults to current channel
            `[emoji=⭐]` is the emoji that will be used to add to the starboard defaults to ⭐
        """
        guild = ctx.message.guild
        name = name.lower()
        if channel is None:
            channel = ctx.message.channel
        if type(emoji) == discord.Emoji:
            if emoji not in guild.emojis:
                await ctx.send(_("That emoji is not on this guild!"))
                return
        if not channel.permissions_for(guild.me).send_messages:
            send_perms = _("I don't have permission to post in ")

            await ctx.send(send_perms + channel.mention)
            return

        if not channel.permissions_for(guild.me).embed_links:
            embed_perms = _("I don't have permission to embed links in ")
            await ctx.send(embed_perms + channel.mention)
            return
        if guild.id not in self.starboards:
            self.starboards[guild.id] = {}
        starboards = self.starboards[guild.id]
        if name in starboards:
            await ctx.send(
                _("{name} starboard name is already being used").format(
                    name=name))
            return
        starboard = StarboardEntry(name, channel.id, str(emoji))
        starboards[name] = starboard
        await self._save_starboards(guild)
        msg = _("Starboard set to {channel} with emoji {emoji}").format(
            channel=channel.mention, emoji=emoji)
        await ctx.send(msg)
Esempio n. 18
0
def can_bot_respond(channel: TextChannel) -> bool:
    """Checks, can a bot send messages to this channel"""
    # TODO: until we have proper threads support, we allow bot to respond in threads
    if not channel:
        return True
    bot = channel.guild.me
    permissions = channel.permissions_for(bot)
    return permissions.send_messages
Esempio n. 19
0
 async def welcomeChannel(self, ctx:commands.Context, channel: discord.TextChannel):
     
     permissions = channel.permissions_for(ctx.guild.get_member(self.bot.user.id))
     if permissions.read_messages and permissions.send_messages and permissions.embed_links:
         Configuration.setConfigVar(ctx.guild.id, "WELCOME_CHANNEL", channel.id)
         await ctx.send(f"<#{channel.id}> will now be used for welcome messages.")
     else:
         await ctx.send(f"I cannot use {channel.mention} for logging, I do not have the required permissions in there (read_messages, send_messages and embed_links).")
Esempio n. 20
0
 async def channelunmute(self, ctx, channel: discord.TextChannel = None):
     if channel is None:
         channel = ctx.message.channel
     prevPerms = channel.overwrites_for(ctx.guild.default_role)
     prevPerms.send_messages = self.everyoneStatus[str(channel.id)]
     await channel.set_permissions(ctx.guild.default_role,
                                   overwrite=prevPerms)
     for role in ctx.guild.roles:
         perms = channel.overwrites_for(role)
         if role.id in self.editList[str(channel.id)]:
             perms.send_messages = True
             await channel.set_permissions(role, overwrite=perms)
     await ctx.send(embed=discord.Embed(
         description=
         f"<a:check:771786758442188871> {channel.mention} has been unlocked.",
         color=discord.Color.green()))
     self.editList.pop(str(channel.id))
Esempio n. 21
0
  async def lock(self, ctx, channel : discord.TextChannel=None):

    """Locks a channel."""

    overwrite = channel.overwrites_for(ctx.guild.default_role)
    overwrite.send_messages = False
    await channel.set_permissions(ctx.guild.default_role, overwrite=overwrite)
    await ctx.send('Channel locked.')
Esempio n. 22
0
def check_owner(member: discord.Member, channel: discord.TextChannel) -> bool:
    """
    選択したメンバーが個人チャンネルの所有者か確認できます。
    """
    if channel.permissions_for(member).manage_channels == True:
        return True
    else:
        return False
 async def sidewind(self, ctx, target: discord.User,
                    channel: discord.TextChannel):
     async for message in channel.history():
         if message.author == target:
             await ctx.send(
                 str(target) + " sent: " + message.content + " in " +
                 str(channel) + " on " +
                 message.created_at.strftime("%m/%d/%Y, %H:%M:%S"))
Esempio n. 24
0
 async def copyrole(self, ctx, role: discord.Role,
                    src_channel: discord.TextChannel,
                    des_channels: commands.Greedy[discord.TextChannel]):
     """Copy role permission from a channel to channels"""
     perms = src_channel.overwrites_for(role)
     for c in des_channels:
         await c.set_permissions(role, overwrite=perms)
     await ctx.send("Changed permissions successfully")
Esempio n. 25
0
    def everyone_can_read(self, channel: discord.TextChannel):
        everyone = channel.guild.default_role
        overwritten = channel.overwrites_for(everyone).read_messages

        if overwritten is None:
            return everyone.permissions.read_messages
        else:
            return overwritten
Esempio n. 26
0
    async def _rescan_channel(self,
                              ctx: discord.ext.commands.Context,
                              channel: discord.TextChannel,
                              lookback_num=250,
                              lookback_time=datetime.timedelta(days=7),
                              force_sentinel=None):
        """
        Rescan the given channel to populate the message cache with all previously
        sent messages with emoji or reacts.

        To avoid excessive re-scanning of already-cached messages, we persist
        a "sentinel" datetime to the database indicating where to begin the next scan.

        Messages sent before the sentinel are considered final and will never be rescanned;
        messages sent after are considered tentative, and might have their cache entries
        invalidated (i.e. overwritten by newer data).

        The sentinel is chosen to be the earlier of:
        1) the datetime of the `lookback_num`'th most recent message in the channel, OR
        2) the datetime occurring `lookback_time` before the most recent message in the channel.

        WARNING: The sentinel is an imperfect heuristic; in particular it
                 assumes that messages will never be reacted to again once
                 they become old enough. (i.e. no "necro" reactions).

        TODO: The rescan currently only detects reactions to messages.
              It will not detect messages that contain emoji in the body,
              although it would be nice to track these occurrences as well.

        Args:
            ctx: The context from which the rescan was requested.
            channel: The channel to be rescanned.
            lookback_num: How many messages to look back for the next sentinel.
            lookback_time: How much time before the most recent message to look
                           back for the next sentinel.
            force_sentinel: datetime.datetime, If provided, force a rescan up
                            to this point in the past.

        Returns:
            None
        """
        start_time = time.time()

        if not channel.permissions_for(ctx.guild.me).read_message_history:
            logger.warning(
                f'Bot not permitted to read_message_history in {channel.name}')
            return

        # Find the last sentinel, if it exists
        Channel = tinydb.Query()
        sentinel_datetime = None
        if channels := self._channels.search(Channel.id == channel.id):
            if len(channels) != 1:
                logger.warning(
                    f"Search for channel id {channel.id} expected 1 channel; yielded {channels}"
                )
                return
            sentinel_datetime = stodt(channels[0]['sentinel_datetime'])
Esempio n. 27
0
async def update_channel_open(prefix: str, channel: discord.TextChannel):
    if channel.name.startswith(YES) or channel.name.startswith(NO):
        new_name = prefix + channel.name[1:]
    else:
        new_name = prefix + channel.name
    try:
        await asyncio.wait_for(channel.edit(name=new_name), timeout=2)
    except asyncio.TimeoutError:
        return
Esempio n. 28
0
async def get_gems(ctx, channel: discord.TextChannel):
    hist = channel.history()
    async for msg in hist:
        buffer = BytesIO()
        await msg.attachments[0].save(buffer)
        buffer.seek(0)
        img = Image.open(buffer)
        print(pytesseract.image_to_string(img))
        break
Esempio n. 29
0
async def hide(ctx, channel: discord.TextChannel = None, *, Reason=None):
    channel = channel or ctx.channel
    overwrite = channel.overwrites_for(ctx.guild.default_role)
    overwrite.view_channel = False
    await channel.set_permissions(ctx.guild.default_role, overwrite=overwrite)
    embedAAAAB = discord.Embed(title="Channel Hidden.➖",
                               description=f"Reason: ```md\n{Reason}```",
                               color=0x3A56D4)
    await ctx.send(embed=embedAAAAB)
Esempio n. 30
0
    async def checkchannel(self,
                           ctx: NabCtx,
                           *,
                           channel: discord.TextChannel = None):
        """Checks the channel's permissions.

        Makes sure that the bot has all the required permissions to work properly.
        If no channel is specified, the current one is checked."""
        if channel is None:
            channel = ctx.channel
        permissions = channel.permissions_for(ctx.me)
        content = f"**Checking {channel.mention}:**"
        if permissions.administrator:
            content += f"\n{ctx.tick(True)} I have `Administrator` permission."
            await ctx.send(content)
            return
        perm_dict = dict(permissions)
        check_permissions = {
            "read_messages":
            ["error", "I won't be able to see commands in here."],
            "send_messages": ["error", "I won't be able to respond in here."],
            "add_reactions": [
                "error",
                "Pagination or commands that require emoji confirmation won't work."
            ],
            "external_emojis":
            ["warn", "I won't be able to show my emojis in some commands."],
            "read_message_history":
            ["error", "I won't be able to see your reactions in commands."],
            "manage_messages": [
                "warn",
                "Command pagination won't work well and I won't be able to delete messages "
                "in the ask channel."
            ],
            "embed_links":
            ["error", "I won't be able to show many of my commands."],
            "attach_files":
            ["warn", "I won't be able to show images in some of my commands."],
            "manage_roles": [
                "warn",
                "I only need this to manage auto roles and joinable roles."
            ],
            "manage_channels":
            ["warn", "I only need this to create watchlists."]
        }
        ok = True
        for k, v in check_permissions.items():
            level, explain = v
            if not perm_dict[k]:
                ok = False
                perm_name = k.replace("_", " ").title()
                icon = ctx.tick(
                    False) if level == "error" else config.warn_emoji
                content += f"\nMissing `{perm_name}` permission\n\t{icon} {explain}"
        if ok:
            content += f"\n{ctx.tick(True)} All permissions are correct!"
        await ctx.send(content)
Esempio n. 31
0
 async def forcemention(self, channel: discord.TextChannel,
                        role: discord.Role, message: str, **kwargs):
     mentionPerms = discord.AllowedMentions(roles=True)
     me = channel.guild.me
     if (not role.mentionable
             and not channel.permissions_for(me).mention_everyone
             and channel.permissions_for(me).manage_roles
             and me.top_role > role):
         await role.edit(mentionable=True)
         await channel.send(message,
                            allowed_mentions=mentionPerms,
                            **kwargs)
         await asyncio.sleep(1.5)
         await role.edit(mentionable=False)
     else:
         await channel.send(message,
                            allowed_mentions=mentionPerms,
                            **kwargs)
Esempio n. 32
0
 async def make_info_channel_multiple_messages(channel: TextChannel, contents: List[AnyStr]) -> List[Message]:
     with channel.typing():
         messages: List[Message]
         ChannelManager.purge_channel(channel)
         for content in contents:
             message: Message = await channel.send("WIP")
             await message.edit(content=content)
             messages.append(message)
     return messages
Esempio n. 33
0
 async def user_messages(self,
                         ctx,
                         user: discord.Member,
                         channel: discord.TextChannel,
                         date_begin,
                         date_stop=None):
     """This command checks all messages given by a user in a channel within a certain date"""
     worked, work = False, True
     if (work == False):
         await ctx.send('No Member Found')
     else:
         try:
             monthb, dayb, yearb = map(int, date_begin.split('/'))
             try:
                 months, days, years = map(int, date_stop.split('/'))
                 bef = datetime.datetime(years, months, days)
             except:
                 bef = None
                 date_stop = 'current'
             worked = True
         except:
             await ctx.send('You have entered a wrong date start or stop')
         if (worked == True):
             embed = discord.Embed(title='All Messages Sent By {}'.format(
                 user.display_name),
                                   description='Dates from {} to {}'.format(
                                       date_begin, date_stop),
                                   color=discord.Color.teal())
             embed.set_author(name=user.display_name,
                              icon_url=user.avatar_url)
             async for message in channel.history(after=datetime.datetime(
                     yearb, monthb, dayb),
                                                  before=bef,
                                                  oldest_first=True):
                 if (message.author == user):
                     month, day, year = map(
                         str,
                         str(message.created_at).split(' ')[0].split('-'))
                     hour, minute, second = map(
                         str,
                         str(message.created_at).split(' ')[1].split(':'))
                     second = second.split('.')[0]
                     hour = str(int(hour) + 5)
                     if (hour > '12'):
                         hour = str(int(hour) - 12)
                         ti = 'P'
                         if (hour > '12'):
                             hour = str(int(hour) - 12)
                             ti = 'A'
                     else:
                         ti = 'A'
                     embed.add_field(name=message.content,
                                     value='{}/{}/{} {}:{}:{} {}M'.format(
                                         month, day, year, abs(hour),
                                         minute, second, ti),
                                     inline=False)
             await ctx.author.send('', embed=embed)
Esempio n. 34
0
    async def get_messages_for_deletion(
        *,
        channel: discord.TextChannel,
        number: int = None,
        check: Callable[[discord.Message], bool] = lambda x: True,
        before: Union[discord.Message, datetime] = None,
        after: Union[discord.Message, datetime] = None,
        delete_pinned: bool = False,
    ) -> List[discord.Message]:
        """
        Gets a list of messages meeting the requirements to be deleted.
        Generally, the requirements are:
        - We don't have the number of messages to be deleted already
        - The message passes a provided check (if no check is provided,
          this is automatically true)
        - The message is less than 14 days old
        - The message is not pinned

        Warning: Due to the way the API hands messages back in chunks,
        passing after and a number together is not advisable.
        If you need to accomplish this, you should filter messages on
        the entire applicable range, rather than use this utility.
        """

        # This isn't actually two weeks ago to allow some wiggle room on API limits
        two_weeks_ago = datetime.utcnow() - timedelta(days=14, minutes=-5)

        def message_filter(message):
            return (
                check(message)
                and message.created_at > two_weeks_ago
                and (delete_pinned or not message.pinned)
            )

        if after:
            if isinstance(after, discord.Message):
                after = after.created_at
            after = max(after, two_weeks_ago)

        collected = []
        async for message in channel.history(
            limit=None, before=before, after=after, reverse=False
        ):
            if message.created_at < two_weeks_ago:
                break
            if message_filter(message):
                collected.append(message)
                if number and number <= len(collected):
                    break

        return collected
Esempio n. 35
0
    async def channelinfo(self, ctx: NabCtx, channel: discord.TextChannel = None):
        """Shows information about a channel.

        If no channel is specified, the information for the current channel is shown."""
        if channel is None:
            channel = ctx.channel
        if not channel.permissions_for(ctx.author).read_messages:
            return await ctx.error("You are not supposed to see that channel, so I can't show you anything.")
        embed = discord.Embed(title=f"#{channel}", description=f"**ID** {channel.id}", colour=discord.Colour.blurple(),
                              timestamp=channel.created_at)
        if channel.topic:
            embed.description += f"\n{channel.topic}"
        embed.add_field(name="Visible by", value=f"{len(channel.members):,} members")
        embed.add_field(name="Mention", value=f"`{channel.mention}`")
        embed.add_field(name="NSFW", value=ctx.tick(channel.nsfw))
        embed.set_footer(text="Created on")
        await ctx.send(embed=embed)
Esempio n. 36
0
    async def checkchannel(self, ctx: NabCtx, *, channel: discord.TextChannel = None):
        """Checks the channel's permissions.

        Makes sure that the bot has all the required permissions to work properly.
        If no channel is specified, the current one is checked."""
        if channel is None:
            channel = ctx.channel
        permissions = channel.permissions_for(ctx.me)
        content = f"**Checking {channel.mention}:**"
        if permissions.administrator:
            content += f"\n{ctx.tick(True)} I have `Administrator` permission."
            await ctx.send(content)
            return
        perm_dict = dict(permissions)
        check_permissions = {
            "read_messages": ["error", "I won't be able to see commands in here."],
            "send_messages": ["error", "I won't be able to respond in here."],
            "add_reactions": ["error", "Pagination or commands that require emoji confirmation won't work."],
            "external_emojis": ["warn", "I won't be able to show my emojis in some commands."],
            "read_message_history": ["error", "I won't be able to see your reactions in commands."],
            "manage_messages": ["warn", "Command pagination won't work well and I won't be able to delete messages "
                                        "in the ask channel."],
            "embed_links": ["error", "I won't be able to show many of my commands."],
            "attach_files": ["warn", "I won't be able to show images in some of my commands."],
            "manage_roles": ["warn", "I only need this to manage auto roles and joinable roles."],
            "manage_channels": ["warn", "I only need this to create watchlists."]
        }
        ok = True
        for k, v in check_permissions.items():
            level, explain = v
            if not perm_dict[k]:
                ok = False
                perm_name = k.replace("_", " ").title()
                icon = ctx.tick(False) if level == "error" else config.warn_emoji
                content += f"\nMissing `{perm_name}` permission\n\t{icon} {explain}"
        if ok:
            content += f"\n{ctx.tick(True)} All permissions are correct!"
        await ctx.send(content)
Esempio n. 37
0
    async def permissions(self, ctx: NabCtx, member: discord.Member = None, channel: discord.TextChannel = None):
        """Shows a member's permissions in the current channel.

        If no member is provided, it will show your permissions.
        Optionally, a channel can be provided as the second parameter, to check permissions in said channel."""
        member = member or ctx.author
        channel = channel or ctx.channel
        guild_permissions = channel.permissions_for(member)
        embed = discord.Embed(title=f"Permissions in #{channel.name}", colour=member.colour)
        embed.set_author(name=member.display_name, icon_url=get_user_avatar(member))
        allowed = []
        denied = []
        for name, value in guild_permissions:
            name = name.replace('_', ' ').replace('guild', 'server').title()
            if value:
                allowed.append(name)
            else:
                denied.append(name)
        if allowed:
            embed.add_field(name=f"{ctx.tick()}Allowed", value="\n".join(allowed))
        if denied:
            embed.add_field(name=f"{ctx.tick(False)}Denied", value="\n".join(denied))
        await ctx.send(embed=embed)
Esempio n. 38
0
    def __can_speak_in(channel: discord.TextChannel) -> bool:
        """Indicates whether the bot has permission to speak in channel."""

        return channel.permissions_for(channel.guild.me).send_messages