diff options
Diffstat (limited to 'discord/channel.py')
| -rw-r--r-- | discord/channel.py | 123 |
1 files changed, 112 insertions, 11 deletions
diff --git a/discord/channel.py b/discord/channel.py index c9eb9c34..ded4da41 100644 --- a/discord/channel.py +++ b/discord/channel.py @@ -30,11 +30,12 @@ from typing import Callable, Dict, List, Optional, TYPE_CHECKING, Union, overloa import discord.abc from .permissions import PermissionOverwrite, Permissions -from .enums import ChannelType, try_enum, VoiceRegion, VideoQualityMode +from .enums import ChannelType, StagePrivacyLevel, try_enum, VoiceRegion, VideoQualityMode from .mixins import Hashable from . import utils from .asset import Asset from .errors import ClientException, NoMoreItems, InvalidArgument +from .stage_instance import StageInstance __all__ = ( 'TextChannel', @@ -49,7 +50,7 @@ __all__ = ( if TYPE_CHECKING: from .role import Role - from .member import Member + from .member import Member, VoiceState from .abc import Snowflake from .message import Message from .webhook import Webhook @@ -611,7 +612,7 @@ class VocalGuildChannel(discord.abc.Connectable, discord.abc.GuildChannel, Hasha return ChannelType.voice.value @property - def members(self): + def members(self) -> List[Member]: """List[:class:`Member`]: Returns all members that are currently inside this voice channel.""" ret = [] for user_id, state in self.guild._voice_states.items(): @@ -622,7 +623,7 @@ class VocalGuildChannel(discord.abc.Connectable, discord.abc.GuildChannel, Hasha return ret @property - def voice_states(self): + def voice_states(self) -> Dict[int, VoiceState]: """Returns a mapping of member IDs who have voice states in this channel. .. versionadded:: 1.3 @@ -640,7 +641,7 @@ class VocalGuildChannel(discord.abc.Connectable, discord.abc.GuildChannel, Hasha return {key: value for key, value in self.guild._voice_states.items() if value.channel.id == self.id} @utils.copy_doc(discord.abc.GuildChannel.permissions_for) - def permissions_for(self, member): + def permissions_for(self, member: Union[Role, Member], /) -> Permissions: base = super().permissions_for(member) # voice channels cannot be edited by people who can't connect to them @@ -875,20 +876,119 @@ class StageChannel(VocalGuildChannel): self.topic = data.get('topic') @property - def requesting_to_speak(self): + def requesting_to_speak(self) -> List[Member]: """List[:class:`Member`]: A list of members who are requesting to speak in the stage channel.""" return [member for member in self.members if member.voice.requested_to_speak_at is not None] @property + def speakers(self) -> List[Member]: + """List[:class:`Member`]: A list of members who have been permitted to speak in the stage channel. + + .. versionadded:: 2.0 + """ + return [member for member in self.members if not member.voice.suppress and member.voice.requested_to_speak_at is None] + + @property + def listeners(self) -> List[Member]: + """List[:class:`Member`]: A list of members who are listening in the stage channel. + + .. versionadded:: 2.0 + """ + return [member for member in self.members if member.voice.suppress] + + @property + def moderators(self) -> List[Member]: + """List[:class:`Member`]: A list of members who are moderating the stage channel. + + .. versionadded:: 2.0 + """ + required_permissions = Permissions.stage_moderator() + return [member for member in self.members if self.permissions_for(member) >= required_permissions] + + @property def type(self): """:class:`ChannelType`: The channel's Discord type.""" return ChannelType.stage_voice @utils.copy_doc(discord.abc.GuildChannel.clone) async def clone(self, *, name: str = None, reason: Optional[str] = None) -> StageChannel: - return await self._clone_impl({ - 'topic': self.topic, - }, name=name, reason=reason) + return await self._clone_impl({}, name=name, reason=reason) + + @property + def instance(self) -> Optional[StageInstance]: + """Optional[:class:`StageInstance`]: The running stage instance of the stage channel. + + .. versionadded:: 2.0 + """ + return utils.get(self.guild.stage_instances, channel_id=self.id) + + async def create_instance(self, *, topic: str, privacy_level: StagePrivacyLevel = utils.MISSING) -> StageInstance: + """|coro| + + Create a stage instance. + + You must have the :attr:`~Permissions.manage_channels` permission to + use this. + + .. versionadded:: 2.0 + + Parameters + ----------- + topic: :class:`str` + The stage instance's topic. + privacy_level: :class:`StagePrivacyLevel` + The stage instance's privacy level. Defaults to :attr:`PrivacyLevel.guild_only`. + + Raises + ------ + InvalidArgument + If the ``privacy_level`` parameter is not the proper type. + Forbidden + You do not have permissions to create a stage instance. + HTTPException + Creating a stage instance failed. + + Returns + -------- + :class:`StageInstance` + The newly created stage instance. + """ + + payload = { + 'channel_id': self.id, + 'topic': topic + } + + if privacy_level is not utils.MISSING: + if not isinstance(privacy_level, StagePrivacyLevel): + raise InvalidArgument('privacy_level field must be of type PrivacyLevel') + + payload['privacy_level'] = privacy_level.value + + data = await self._state.http.create_stage_instance(**payload) + return StageInstance(guild=self.guild, state=self._state, data=data) + + async def fetch_instance(self) -> StageInstance: + """|coro| + + Gets the running :class:`StageInstance`. + + .. versionadded:: 2.0 + + Raises + ------- + :exc:`.NotFound` + The stage instance or channel could not be found. + :exc:`.HTTPException` + Getting the stage instance failed. + + Returns + -------- + :class:`StageInstance` + The stage instance. + """ + data = await self._state.http.get_stage_instance(self.id) + return StageInstance(guild=self.guild, state=self._state, data=data) @overload async def edit( @@ -918,12 +1018,13 @@ class StageChannel(VocalGuildChannel): You must have the :attr:`~Permissions.manage_channels` permission to use this. + .. versionchanged:: 2.0 + The ``topic`` parameter must now be set via :attr:`create_instance`. + Parameters ---------- name: :class:`str` The new channel's name. - topic: Optional[:class:`str`] - The new channel's topic. position: :class:`int` The new channel's position. sync_permissions: :class:`bool` |