25
25
26
26
from __future__ import annotations
27
27
28
- from typing import TYPE_CHECKING
28
+ from typing import TYPE_CHECKING , Any , Coroutine
29
29
30
- from typing_extensions import reveal_type
30
+ from typing_extensions import override , reveal_type
31
31
32
32
from .asset import Asset
33
33
from .emoji import PartialEmoji
34
34
from .mixins import Hashable
35
35
from .types .channel import (
36
36
VoiceChannelEffectSendEvent as VoiceChannelEffectSendEventPayload ,
37
37
)
38
- from .types .soundboard import PartialSoundboardSound as PartialSoundboardSoundPayload
39
38
from .types .soundboard import SoundboardSound as SoundboardSoundPayload
40
39
from .utils import cached_slot_property
41
40
42
41
if TYPE_CHECKING :
43
42
from .guild import Guild
44
43
from .http import HTTPClient
45
- from .member import Member
46
44
from .state import ConnectionState
47
45
48
46
49
47
__all__ = (
50
48
"PartialSoundboardSound" ,
51
49
"SoundboardSound" ,
52
- "DefaultSoundboardSound" ,
53
50
)
54
51
55
52
@@ -66,45 +63,54 @@ class PartialSoundboardSound(Hashable):
66
63
The sound's emoji.
67
64
"""
68
65
69
- __slots__ = ("id" , "volume" , "emoji" , "_http" , "emoji" )
66
+ __slots__ = ("id" , "volume" , "emoji" , "_http" )
70
67
71
68
def __init__ (
72
69
self ,
73
- data : PartialSoundboardSoundPayload | VoiceChannelEffectSendEventPayload ,
70
+ data : SoundboardSoundPayload | VoiceChannelEffectSendEventPayload ,
74
71
http : HTTPClient ,
75
72
):
76
73
self ._http = http
77
74
self ._from_data (data )
78
75
79
- def __eq__ (self , other : PartialSoundboardSound ) -> bool :
76
+ def _from_data (
77
+ self , data : SoundboardSoundPayload | VoiceChannelEffectSendEventPayload
78
+ ) -> None :
79
+ self .id = int (data .get ("sound_id" , 0 ))
80
+ self .volume = (
81
+ float (data .get ("volume" , 0 ) or data .get ("sound_volume" , 0 )) or None
82
+ )
83
+ if raw_emoji := data .get (
84
+ "emoji"
85
+ ): # From gateway event (VoiceChannelEffectSendEventPayload)
86
+ self .emoji = PartialEmoji .from_dict (raw_emoji )
87
+ else : # From HTTP response (SoundboardSoundPayload)
88
+ self .emoji = PartialEmoji (
89
+ name = data .get ("emoji_name" ),
90
+ id = int (data .get ("emoji_id" , 0 ) or 0 ) or None ,
91
+ )
92
+
93
+ @override
94
+ def __eq__ (
95
+ self , other : PartialSoundboardSound
96
+ ) -> bool : # pyright: ignore[reportIncompatibleMethodOverride]
80
97
if isinstance (other , self , __class__ ):
81
98
return self .id == other .id
82
99
return NotImplemented
83
100
84
- def __ne__ (self , other : PartialSoundboardSound ) -> bool :
101
+ @override
102
+ def __ne__ (
103
+ self , other : PartialSoundboardSound
104
+ ) -> bool : # pyright: ignore[reportIncompatibleMethodOverride]
85
105
return not self .__eq__ (other )
86
106
87
107
@property
88
108
def file (self ) -> Asset :
89
109
""":class:`Asset`: Returns the sound's file."""
90
110
return Asset ._from_soundboard_sound (self , sound_id = self .id )
91
111
92
- def _from_data (
93
- self , data : PartialSoundboardSoundPayload | VoiceChannelEffectSendEventPayload
94
- ) -> None :
95
- self .id = int (data ["sound_id" ])
96
- self .volume = float (data .get ("volume" , 0 )) or data .get ("sound_volume" )
97
- if raw_emoji := data .get (
98
- "emoji"
99
- ): # From gateway event (VoiceChannelEffectSendEventPayload)
100
- self .emoji = PartialEmoji .from_dict (raw_emoji )
101
- elif emoji_id := data .get (
102
- "emoji_id" , 0
103
- ): # From HTTP response (PartialSoundboardSoundPayload)
104
- self .emoji = PartialEmoji (
105
- name = data .get ("emoji_name" ),
106
- id = int (emoji_id ) or None ,
107
- )
112
+ def __repr__ (self ) -> str :
113
+ return f"<PartialSoundboardSound id={ self .id } volume={ self .volume } emoji={ self .emoji !r} >"
108
114
109
115
110
116
class SoundboardSound (PartialSoundboardSound ):
@@ -129,17 +135,12 @@ class SoundboardSound(PartialSoundboardSound):
129
135
"""
130
136
131
137
__slots__ = (
132
- "id" ,
133
- "volume" ,
134
138
"name" ,
135
139
"available" ,
136
- "emoji" ,
137
140
"guild_id" ,
138
- "_cs_guild" ,
139
141
"user" ,
140
- "_http " ,
142
+ "_cs_guild " ,
141
143
"_state" ,
142
- "emoji" ,
143
144
)
144
145
145
146
def __init__ (
@@ -152,59 +153,42 @@ def __init__(
152
153
self ._state = state
153
154
super ().__init__ (data , http )
154
155
155
- def _from_data (self , data : SoundboardSoundPayload ) -> None :
156
+ @override
157
+ def _from_data (
158
+ self , data : SoundboardSoundPayload
159
+ ) -> None : # pyright: ignore[reportIncompatibleMethodOverride]
156
160
super ()._from_data (data )
157
161
self .name = data ["name" ]
158
162
self .available : bool = data ["available" ]
159
- self .guild_id = int (data [ "guild_id" ])
163
+ self .guild_id = int (data . get ( "guild_id" , 0 ) or 0 ) or None
160
164
user = data .get ("user" )
161
-
162
165
self .user = self ._state .store_user (user ) if user else None
163
166
164
167
@cached_slot_property ("_cs_guild" )
165
- def guild (self ) -> Guild :
168
+ def guild (self ) -> Guild | None :
166
169
""":class:`Guild`: The guild the sound belongs to.
167
170
168
171
The :class:`Guild` object representing the guild the sound belongs to.
169
172
.. versionadded:: 2.7
170
173
"""
171
- return self ._state ._get_guild (self .guild_id )
174
+ return self ._state ._get_guild (self .guild_id ) if self . guild_id else None
172
175
173
- def __eq__ (self , other : SoundboardSound ) -> bool :
176
+ @override
177
+ def __eq__ (
178
+ self , other : SoundboardSound
179
+ ) -> bool : # pyright: ignore[reportIncompatibleMethodOverride]
174
180
return isinstance (other , SoundboardSound ) and self .__dict__ == other .__dict__
175
181
176
- def delete (self ):
177
- return self ._http .delete_sound (self )
178
-
179
- def _update (self , data : PartialSoundboardSound ) -> None :
180
- super ()._update (data )
181
- self .name = data ["name" ]
182
- self .available = bool (data .get ("available" , True ))
183
-
184
-
185
- class DefaultSoundboardSound (PartialSoundboardSound ):
186
- """Represents a default soundboard sound.
187
-
188
- Attributes
189
- ----------
190
- id: :class:`int`
191
- The sound's ID.
192
- volume: :class:`float`
193
- The sound's volume.
194
- name: :class:`str`
195
- The sound's name.
196
- emoji: :class:`PartialEmoji`
197
- The sound's emoji.
198
- """
199
-
200
- __slots__ = ("id" , "volume" , "name" , "emoji" , "_http" )
201
-
202
- def __init__ (self , * , http : HTTPClient , data : SoundboardSoundPayload ) -> None :
203
- super ().__init__ (data , http )
204
- self .name = data ["name" ]
205
-
206
- def __eq__ (self , other : DefaultSoundboardSound ) -> bool :
207
- return (
208
- isinstance (other , DefaultSoundboardSound )
209
- and self .__dict__ == other .__dict__
210
- )
182
+ @property
183
+ def is_default_sound (self ) -> bool :
184
+ """:class:`bool`: Whether the sound is a default sound."""
185
+ return self .guild_id is None
186
+
187
+ def delete (self , * , reason : str | None = None ) -> Coroutine [Any , Any , None ]:
188
+ if self .is_default_sound :
189
+ raise ValueError ("Cannot delete a default sound." )
190
+ return self ._http .delete_sound (self , reason = reason )
191
+
192
+ @override
193
+ def __repr__ (self ) -> str :
194
+ return f"<SoundboardSound id={ self .id } name={ self .name !r} volume={ self .volume } emoji={ self .emoji !r} guild={ self .guild !r} user={ self .user !r} available={ self .available } default={ self .is_default_sound } >"
0 commit comments