aboutsummaryrefslogtreecommitdiff
path: root/discord/channel.py
diff options
context:
space:
mode:
Diffstat (limited to 'discord/channel.py')
-rw-r--r--discord/channel.py123
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`