Beispiel #1
0
    async def add_mute_new_channel(self, channel: discord.abc.GuildChannel):
        """Updated the new channels mute perms once created if the guild has a mute role set."""

        try:
            mute_role_id = self.bot.config[channel.guild.id]["mute_role_id"]
        except KeyError:
            return

        role = channel.guild.get_role(mute_role_id)

        if role is None:
            await self.bot.pool.execute(
                "UPDATE guild_settings SET mute_role_id = NULL WHERE guild_id = $1",
                channel.guild.id)
            self.bot.config[channel.guild.id]["mute_role_id"] = None
            return

        role_overwrites = channel.overwrites_for(role)
        role_overwrites.update(send_messages=False)

        with contextlib.suppress(discord.Forbidden, discord.HTTPException):
            await channel.set_permissions(
                target=role,
                overwrite=role_overwrites,
                reason="Disable mute role permissions to talk in this channel."
            )
Beispiel #2
0
 async def on_guild_channel_create(self, channel: discord.abc.GuildChannel):
     guild: discord.Guild = channel.guild
     roleid = Configuration.get_var(guild.id, "MUTE_ROLE")
     if roleid is not 0:
         role = guild.get_role(roleid)
         if role is not None and channel.permissions_for(
                 guild.me).manage_channels:
             if isinstance(channel, discord.TextChannel):
                 try:
                     await channel.set_permissions(
                         role,
                         reason=Translator.translate(
                             'mute_setup', guild.id),
                         send_messages=False,
                         add_reactions=False)
                 except discord.Forbidden:
                     pass
             else:
                 try:
                     await channel.set_permissions(
                         role,
                         reason=Translator.translate(
                             'mute_setup', guild.id),
                         speak=False,
                         connect=False)
                 except discord.Forbidden:
                     pass
Beispiel #3
0
def role_permissions_in(channel: discord.abc.GuildChannel,
                        role: discord.Role) -> discord.Permissions:
    """Returns a role's permissions in a particular channel

    This function is based off of a previous solution for gathering role channel permissions.
    Original Solution: https://gist.github.com/e-Lisae/f20c579ab70304a73506e5565631b753

    Parameters
    ----------
    channel : discord.abc.GuildChannel
        The channel to get the role's permissions for
    role : discord.Role
        The role to get the permissions for
    
    Returns
    -------
    A `discord.Permissions` object representing the role's permissions
    """

    # gather base permissions
    permissions = discord.Permissions.none()
    permissions.value |= role.permissions.value

    # merge with role permission overwrites
    pair = channel.overwrites_for(role).pair()
    permissions.value = (permissions.value & ~pair[1].value) | pair[0].value

    return permissions
Beispiel #4
0
    async def mute_user(
        self,
        guild: discord.Guild,
        channel: discord.abc.GuildChannel,
        author: discord.Member,
        user: discord.Member,
        reason: str,
    ) -> (bool, str):
        """Mutes the specified user in the specified channel"""
        overwrites = channel.overwrites_for(user)
        permissions = channel.permissions_for(user)

        if permissions.administrator:
            return False, _(mute_unmute_issues["is_admin"])

        new_overs = {}
        if not isinstance(channel, discord.TextChannel):
            new_overs.update(speak=False)
        if not isinstance(channel, discord.VoiceChannel):
            new_overs.update(send_messages=False, add_reactions=False)

        if all(getattr(permissions, p) is False for p in new_overs.keys()):
            return False, _(mute_unmute_issues["already_muted"])

        elif not await is_allowed_by_hierarchy(self.bot, self.settings, guild,
                                               author, user):
            return False, _(mute_unmute_issues["hierarchy_problem"])

        old_overs = {k: getattr(overwrites, k) for k in new_overs}
        overwrites.update(**new_overs)
        try:
            await channel.set_permissions(user,
                                          overwrite=overwrites,
                                          reason=reason)
        except discord.Forbidden:
            return False, _(mute_unmute_issues["permissions_issue"])
        except discord.NotFound as e:
            if e.code == 10003:
                return False, _(mute_unmute_issues["unknown_channel"])
            elif e.code == 10009:
                return False, _(mute_unmute_issues["left_guild"])
        else:
            await self.settings.member(user).set_raw("perms_cache",
                                                     str(channel.id),
                                                     value=old_overs)
            return True, None
Beispiel #5
0
 async def setup_overwrites(self, role: discord.Role, channel: discord.abc.GuildChannel):
     # noinspection PyUnresolvedReferences
     if not channel.permissions_for(channel.guild.me).manage_roles:
         return
     await channel.set_permissions(
         target=role,
         overwrite=self.OVERWRITE_PERMISSIONS,
         reason=translate("setup_audit_reason"),
     )
Beispiel #6
0
 async def on_guild_channel_create(self, channel: discord.abc.GuildChannel):
     # noinspection PyUnresolvedReferences
     guild: discord.Guild = channel.guild
     if not channel.permissions_for(guild.me).manage_roles:
         return
     role = await self.get_punished_role(guild)
     if not role:
         return
     await self.setup_overwrites(role, channel)
Beispiel #7
0
    async def convert(self, ctx: context.Context, channel: discord.abc.GuildChannel) -> str:

        if isinstance(channel, discord.VoiceChannel):
            emoji = 'voice'
            if channel.overwrites_for(channel.guild.default_role).connect is False:
                emoji = 'voice_locked'

        else:
            if channel.is_news():
                emoji = 'news'
                if channel.overwrites_for(channel.guild.default_role).read_messages is False:
                    emoji = 'news_locked'
            else:
                emoji = 'text'
                if channel.is_nsfw():
                    emoji = 'text_nsfw'
                elif channel.overwrites_for(channel.guild.default_role).read_messages is False:
                    emoji = 'text_locked'

        return ctx.bot.utils.channel_emojis[emoji]
Beispiel #8
0
    async def archive_channel(self, channel: discord.abc.GuildChannel):
        print(f"Processing channel: {channel}")
        self.discard.start_channel(channel)

        # XXX is it a good idea for userbots to do this?
        #await self.fetch_channel(channel.id)

        num_messages = 0
        oldest_message = None
        newest_message = None
        message = None

        pbar = None

        # before and after datetimes must be timezone-naive in UTC (why not timezone-aware UTC?)
        async for message in channel.history(after=self.discard.after,
                                             before=self.discard.before,
                                             limit=None,
                                             oldest_first=True):
            if oldest_message is None:
                oldest_message = message
                expected_timedelta = (
                    self.discard.before
                    or datetime.datetime.now()) - oldest_message.created_at

            for reaction in message.reactions:
                # Fetch the users who reacted
                async for user in reaction.users():
                    pass

            if num_messages % PBAR_UPDATE_INTERVAL == 0 and num_messages > PBAR_MINIMUM_MESSAGES:
                timedelta = message.created_at - oldest_message.created_at
                if pbar is None:
                    pbar = tqdm(total=expected_timedelta.days,
                                initial=timedelta.days,
                                unit="day",
                                miniters=1)
                else:
                    diff = timedelta.days - pbar.n
                    if diff:
                        pbar.update(diff)

            num_messages += 1

        if pbar:
            pbar.update(expected_timedelta.days - pbar.n)
            pbar.close()

        newest_message = message

        self.discard.end_channel(channel, num_messages, oldest_message,
                                 newest_message)
Beispiel #9
0
    async def unmute_user(
        self,
        guild: discord.Guild,
        channel: discord.abc.GuildChannel,
        author: discord.Member,
        user: discord.Member,
        reason: str,
    ) -> (bool, str):
        overwrites = channel.overwrites_for(user)
        perms_cache = await self.settings.member(user).perms_cache()

        if channel.id in perms_cache:
            old_values = perms_cache[channel.id]
        else:
            old_values = {
                "send_messages": None,
                "add_reactions": None,
                "speak": None
            }

        if all(getattr(overwrites, k) == v for k, v in old_values.items()):
            return False, _(mute_unmute_issues["already_unmuted"])

        elif not await is_allowed_by_hierarchy(self.bot, self.settings, guild,
                                               author, user):
            return False, _(mute_unmute_issues["hierarchy_problem"])

        overwrites.update(**old_values)
        try:
            if overwrites.is_empty():
                await channel.set_permissions(user,
                                              overwrite=cast(
                                                  discord.PermissionOverwrite,
                                                  None),
                                              reason=reason)
            else:
                await channel.set_permissions(user,
                                              overwrite=overwrites,
                                              reason=reason)
        except discord.Forbidden:
            return False, _(mute_unmute_issues["permissions_issue"])
        except discord.NotFound as e:
            if e.code == 10003:
                return False, _(mute_unmute_issues["unknown_channel"])
            elif e.code == 10009:
                return False, _(mute_unmute_issues["left_guild"])
        else:
            await self.settings.member(user).clear_raw("perms_cache",
                                                       str(channel.id))
            return True, None
Beispiel #10
0
 async def on_guild_channel_create(self, channel: discord.abc.GuildChannel):
     guild: discord.Guild = channel.guild
     roleid = Configuration.getConfigVar(guild.id, "MUTE_ROLE")
     if roleid is not 0:
         role = discord.utils.get(guild.roles, id=roleid)
         if role is not None and channel.permissions_for(
                 guild.me).manage_channels:
             if isinstance(channel, discord.TextChannel):
                 await channel.set_permissions(
                     role,
                     reason="Automatic mute role setup",
                     send_messages=False,
                     add_reactions=False)
             else:
                 await channel.set_permissions(
                     role,
                     reason="Automatic mute role setup",
                     speak=False,
                     connect=False)
Beispiel #11
0
def verify_channel_visibility(channel: discord.abc.GuildChannel, user: discord.Member) -> bool:
    """Checks whether a user can see a channel.

    The Discord API provides a full list of channels including ones normally invisible to the
    client. This helps hide channels that a bot or user shouldn't see.

    Args:
        channel: discord.py channel.
        user: discord.py server member.

    Returns:
        ``True`` if the user can view and use the given channel.

    """
    permissions = channel.permissions_for(user)
    if channel.type is discord.ChannelType.voice:
        # read_messages is actually view_channel in the official API
        # discord.py mislabeled this, maybe not realizing voice channels use it too
        return (permissions.connect and permissions.read_messages)
    return permissions.read_messages
async def validate_notification_channel(ctx,
                                        channel: discord.abc.GuildChannel):
    """Returns True if channel is valid"""

    if not channel:
        return channel

    # If there isn't a guild aka it's a PrivateGuild
    if not ctx.guild:
        raise errors.InvalidChannelError("This command doesn't work here.")

    # Only people with manage_channels or with the Notification Manager role can subscribe channels
    perms = channel.permissions_for(ctx.author)
    role = discord.utils.find(lambda r: r.name == 'Notification Manager',
                              ctx.author.roles)
    if not role and not perms.manage_channels:
        raise errors.InvalidChannelError(
            "You don't have the Manage Channels permission to subscribe the channel."
        )

    return channel
Beispiel #13
0
 async def _channel_is_sendable_to_you(
         self, channel: discord.abc.GuildChannel) -> bool:
     our_permissions = channel.permissions_for(
         await channel.guild.fetch_member(self.app.discord_client.user.id))
     return our_permissions.send_messages