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." )
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
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
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
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"), )
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)
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]
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)
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
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)
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
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