disagreement 0.0.1__py3-none-any.whl → 0.1.0rc1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- disagreement/__init__.py +8 -3
- disagreement/audio.py +116 -0
- disagreement/client.py +176 -6
- disagreement/color.py +50 -0
- disagreement/components.py +2 -2
- disagreement/errors.py +13 -8
- disagreement/event_dispatcher.py +102 -45
- disagreement/ext/__init__.py +0 -0
- disagreement/ext/app_commands/__init__.py +46 -0
- disagreement/ext/app_commands/commands.py +513 -0
- disagreement/ext/app_commands/context.py +556 -0
- disagreement/ext/app_commands/converters.py +478 -0
- disagreement/ext/app_commands/decorators.py +569 -0
- disagreement/ext/app_commands/handler.py +627 -0
- disagreement/ext/commands/__init__.py +57 -0
- disagreement/ext/commands/cog.py +155 -0
- disagreement/ext/commands/converters.py +175 -0
- disagreement/ext/commands/core.py +497 -0
- disagreement/ext/commands/decorators.py +192 -0
- disagreement/ext/commands/errors.py +76 -0
- disagreement/ext/commands/help.py +37 -0
- disagreement/ext/commands/view.py +103 -0
- disagreement/ext/loader.py +54 -0
- disagreement/ext/tasks.py +182 -0
- disagreement/gateway.py +67 -21
- disagreement/http.py +104 -3
- disagreement/models.py +308 -1
- disagreement/shard_manager.py +2 -0
- disagreement/utils.py +10 -0
- disagreement/voice_client.py +42 -0
- {disagreement-0.0.1.dist-info → disagreement-0.1.0rc1.dist-info}/METADATA +47 -33
- disagreement-0.1.0rc1.dist-info/RECORD +52 -0
- disagreement-0.0.1.dist-info/RECORD +0 -32
- {disagreement-0.0.1.dist-info → disagreement-0.1.0rc1.dist-info}/WHEEL +0 -0
- {disagreement-0.0.1.dist-info → disagreement-0.1.0rc1.dist-info}/licenses/LICENSE +0 -0
- {disagreement-0.0.1.dist-info → disagreement-0.1.0rc1.dist-info}/top_level.txt +0 -0
disagreement/event_dispatcher.py
CHANGED
@@ -47,10 +47,20 @@ class EventDispatcher:
|
|
47
47
|
# Pre-defined parsers for specific event types to convert raw data to models
|
48
48
|
self._event_parsers: Dict[str, Callable[[Dict[str, Any]], Any]] = {
|
49
49
|
"MESSAGE_CREATE": self._parse_message_create,
|
50
|
+
"MESSAGE_UPDATE": self._parse_message_update,
|
51
|
+
"MESSAGE_DELETE": self._parse_message_delete,
|
52
|
+
"MESSAGE_REACTION_ADD": self._parse_message_reaction,
|
53
|
+
"MESSAGE_REACTION_REMOVE": self._parse_message_reaction,
|
50
54
|
"INTERACTION_CREATE": self._parse_interaction_create,
|
51
55
|
"GUILD_CREATE": self._parse_guild_create,
|
52
56
|
"CHANNEL_CREATE": self._parse_channel_create,
|
57
|
+
"CHANNEL_UPDATE": self._parse_channel_update,
|
53
58
|
"PRESENCE_UPDATE": self._parse_presence_update,
|
59
|
+
"GUILD_MEMBER_ADD": self._parse_guild_member_add,
|
60
|
+
"GUILD_MEMBER_REMOVE": self._parse_guild_member_remove,
|
61
|
+
"GUILD_BAN_ADD": self._parse_guild_ban_add,
|
62
|
+
"GUILD_BAN_REMOVE": self._parse_guild_ban_remove,
|
63
|
+
"GUILD_ROLE_UPDATE": self._parse_guild_role_update,
|
54
64
|
"TYPING_START": self._parse_typing_start,
|
55
65
|
}
|
56
66
|
|
@@ -58,6 +68,21 @@ class EventDispatcher:
|
|
58
68
|
"""Parses raw MESSAGE_CREATE data into a Message object."""
|
59
69
|
return self._client.parse_message(data)
|
60
70
|
|
71
|
+
def _parse_message_update(self, data: Dict[str, Any]) -> Message:
|
72
|
+
"""Parses raw MESSAGE_UPDATE data into a Message object."""
|
73
|
+
return self._client.parse_message(data)
|
74
|
+
|
75
|
+
def _parse_message_delete(self, data: Dict[str, Any]) -> Dict[str, Any]:
|
76
|
+
"""Parses MESSAGE_DELETE and updates message cache."""
|
77
|
+
message_id = data.get("id")
|
78
|
+
if message_id:
|
79
|
+
self._client._messages.pop(message_id, None)
|
80
|
+
return data
|
81
|
+
|
82
|
+
def _parse_message_reaction_raw(self, data: Dict[str, Any]) -> Dict[str, Any]:
|
83
|
+
"""Returns the raw reaction payload."""
|
84
|
+
return data
|
85
|
+
|
61
86
|
def _parse_interaction_create(self, data: Dict[str, Any]) -> "Interaction":
|
62
87
|
"""Parses raw INTERACTION_CREATE data into an Interaction object."""
|
63
88
|
from .interactions import Interaction
|
@@ -88,6 +113,52 @@ class EventDispatcher:
|
|
88
113
|
|
89
114
|
return TypingStart(data, client_instance=self._client)
|
90
115
|
|
116
|
+
def _parse_message_reaction(self, data: Dict[str, Any]):
|
117
|
+
"""Parses raw reaction data into a Reaction object."""
|
118
|
+
|
119
|
+
from .models import Reaction
|
120
|
+
|
121
|
+
return Reaction(data, client_instance=self._client)
|
122
|
+
|
123
|
+
def _parse_guild_member_add(self, data: Dict[str, Any]):
|
124
|
+
"""Parses GUILD_MEMBER_ADD into a Member object."""
|
125
|
+
|
126
|
+
guild_id = str(data.get("guild_id"))
|
127
|
+
return self._client.parse_member(data, guild_id)
|
128
|
+
|
129
|
+
def _parse_guild_member_remove(self, data: Dict[str, Any]):
|
130
|
+
"""Parses GUILD_MEMBER_REMOVE into a GuildMemberRemove model."""
|
131
|
+
|
132
|
+
from .models import GuildMemberRemove
|
133
|
+
|
134
|
+
return GuildMemberRemove(data, client_instance=self._client)
|
135
|
+
|
136
|
+
def _parse_guild_ban_add(self, data: Dict[str, Any]):
|
137
|
+
"""Parses GUILD_BAN_ADD into a GuildBanAdd model."""
|
138
|
+
|
139
|
+
from .models import GuildBanAdd
|
140
|
+
|
141
|
+
return GuildBanAdd(data, client_instance=self._client)
|
142
|
+
|
143
|
+
def _parse_guild_ban_remove(self, data: Dict[str, Any]):
|
144
|
+
"""Parses GUILD_BAN_REMOVE into a GuildBanRemove model."""
|
145
|
+
|
146
|
+
from .models import GuildBanRemove
|
147
|
+
|
148
|
+
return GuildBanRemove(data, client_instance=self._client)
|
149
|
+
|
150
|
+
def _parse_channel_update(self, data: Dict[str, Any]):
|
151
|
+
"""Parses CHANNEL_UPDATE into a Channel object."""
|
152
|
+
|
153
|
+
return self._client.parse_channel(data)
|
154
|
+
|
155
|
+
def _parse_guild_role_update(self, data: Dict[str, Any]):
|
156
|
+
"""Parses GUILD_ROLE_UPDATE into a GuildRoleUpdate model."""
|
157
|
+
|
158
|
+
from .models import GuildRoleUpdate
|
159
|
+
|
160
|
+
return GuildRoleUpdate(data, client_instance=self._client)
|
161
|
+
|
91
162
|
# Potentially add _parse_user for events that directly provide a full user object
|
92
163
|
# def _parse_user_update(self, data: Dict[str, Any]) -> User:
|
93
164
|
# return User(data=data)
|
@@ -169,75 +240,61 @@ class EventDispatcher:
|
|
169
240
|
if not waiters:
|
170
241
|
self._waiters.pop(event_name, None)
|
171
242
|
|
172
|
-
async def
|
173
|
-
|
174
|
-
Dispatches an event to all registered listeners.
|
175
|
-
|
176
|
-
Args:
|
177
|
-
event_name (str): The name of the event (e.g., 'MESSAGE_CREATE').
|
178
|
-
raw_data (Dict[str, Any]): The raw data payload from the Discord Gateway for this event.
|
179
|
-
"""
|
180
|
-
event_name_upper = event_name.upper()
|
181
|
-
listeners = self._listeners.get(event_name_upper)
|
182
|
-
|
243
|
+
async def _dispatch_to_listeners(self, event_name: str, data: Any) -> None:
|
244
|
+
listeners = self._listeners.get(event_name)
|
183
245
|
if not listeners:
|
184
|
-
# print(f"No listeners for event {event_name_upper}")
|
185
246
|
return
|
186
247
|
|
187
|
-
|
188
|
-
if event_name_upper in self._event_parsers:
|
189
|
-
try:
|
190
|
-
parser = self._event_parsers[event_name_upper]
|
191
|
-
parsed_data = parser(raw_data)
|
192
|
-
except Exception as e:
|
193
|
-
print(f"Error parsing event data for {event_name_upper}: {e}")
|
194
|
-
# Optionally, dispatch with raw_data or raise, or log more formally
|
195
|
-
# For now, we'll proceed to dispatch with raw_data if parsing fails,
|
196
|
-
# or just log and return if parsed_data is critical.
|
197
|
-
# Let's assume if a parser exists, its output is critical.
|
198
|
-
return
|
248
|
+
self._resolve_waiters(event_name, data)
|
199
249
|
|
200
|
-
self._resolve_waiters(event_name_upper, parsed_data)
|
201
|
-
# print(f"Dispatching event {event_name_upper} with data: {parsed_data} to {len(listeners)} listeners.")
|
202
250
|
for listener in listeners:
|
203
251
|
try:
|
204
|
-
# Inspect the listener to see how many arguments it expects
|
205
252
|
sig = inspect.signature(listener)
|
206
253
|
num_params = len(sig.parameters)
|
207
254
|
|
208
|
-
if num_params == 0:
|
255
|
+
if num_params == 0:
|
209
256
|
await listener()
|
210
|
-
elif
|
211
|
-
|
212
|
-
): # Listener takes one argument (the parsed data or model)
|
213
|
-
await listener(parsed_data)
|
214
|
-
# elif num_params == 2 and event_name_upper == "MESSAGE_CREATE": # Special case for (client, message)
|
215
|
-
# await listener(self._client, parsed_data) # This might be too specific here
|
257
|
+
elif num_params == 1:
|
258
|
+
await listener(data)
|
216
259
|
else:
|
217
|
-
# Fallback or error if signature doesn't match expected patterns
|
218
|
-
# For now, assume one arg is the most common for parsed data.
|
219
|
-
# Or, if you want to be strict:
|
220
260
|
print(
|
221
|
-
f"Warning: Listener {listener.__name__} for {
|
261
|
+
f"Warning: Listener {listener.__name__} for {event_name} has an unhandled number of parameters ({num_params}). Skipping or attempting with one arg."
|
222
262
|
)
|
223
|
-
if num_params > 0:
|
224
|
-
await listener(
|
263
|
+
if num_params > 0:
|
264
|
+
await listener(data)
|
225
265
|
|
226
266
|
except Exception as e:
|
227
267
|
callback = self.on_dispatch_error
|
228
268
|
if callback is not None:
|
229
269
|
try:
|
230
|
-
await callback(
|
231
|
-
|
270
|
+
await callback(event_name, e, listener)
|
232
271
|
except Exception as hook_error:
|
233
272
|
print(f"Error in on_dispatch_error hook itself: {hook_error}")
|
234
273
|
else:
|
235
|
-
# Default error handling if no hook is set
|
236
274
|
print(
|
237
|
-
f"Error in event listener {listener.__name__} for {
|
275
|
+
f"Error in event listener {listener.__name__} for {event_name}: {e}"
|
238
276
|
)
|
239
277
|
if hasattr(self._client, "on_error"):
|
240
278
|
try:
|
241
|
-
await self._client.on_error(
|
279
|
+
await self._client.on_error(event_name, e, listener)
|
242
280
|
except Exception as client_err_e:
|
243
281
|
print(f"Error in client.on_error itself: {client_err_e}")
|
282
|
+
|
283
|
+
async def dispatch(self, event_name: str, raw_data: Dict[str, Any]):
|
284
|
+
"""Dispatch an event and its raw counterpart to all listeners."""
|
285
|
+
|
286
|
+
event_name_upper = event_name.upper()
|
287
|
+
raw_event_name = f"RAW_{event_name_upper}"
|
288
|
+
|
289
|
+
await self._dispatch_to_listeners(raw_event_name, raw_data)
|
290
|
+
|
291
|
+
parsed_data: Any = raw_data
|
292
|
+
if event_name_upper in self._event_parsers:
|
293
|
+
try:
|
294
|
+
parser = self._event_parsers[event_name_upper]
|
295
|
+
parsed_data = parser(raw_data)
|
296
|
+
except Exception as e:
|
297
|
+
print(f"Error parsing event data for {event_name_upper}: {e}")
|
298
|
+
return
|
299
|
+
|
300
|
+
await self._dispatch_to_listeners(event_name_upper, parsed_data)
|
File without changes
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# disagreement/ext/app_commands/__init__.py
|
2
|
+
|
3
|
+
"""
|
4
|
+
Application Commands Extension for Disagreement.
|
5
|
+
|
6
|
+
This package provides the framework for creating and handling
|
7
|
+
Discord Application Commands (slash commands, user commands, message commands).
|
8
|
+
"""
|
9
|
+
|
10
|
+
from .commands import (
|
11
|
+
AppCommand,
|
12
|
+
SlashCommand,
|
13
|
+
UserCommand,
|
14
|
+
MessageCommand,
|
15
|
+
AppCommandGroup,
|
16
|
+
)
|
17
|
+
from .decorators import (
|
18
|
+
slash_command,
|
19
|
+
user_command,
|
20
|
+
message_command,
|
21
|
+
hybrid_command,
|
22
|
+
group,
|
23
|
+
subcommand,
|
24
|
+
subcommand_group,
|
25
|
+
OptionMetadata,
|
26
|
+
)
|
27
|
+
from .context import AppCommandContext
|
28
|
+
|
29
|
+
# from .handler import AppCommandHandler # Will be imported when defined
|
30
|
+
|
31
|
+
__all__ = [
|
32
|
+
"AppCommand",
|
33
|
+
"SlashCommand",
|
34
|
+
"UserCommand",
|
35
|
+
"MessageCommand",
|
36
|
+
"AppCommandGroup", # To be defined
|
37
|
+
"slash_command",
|
38
|
+
"user_command",
|
39
|
+
"message_command",
|
40
|
+
"hybrid_command",
|
41
|
+
"group",
|
42
|
+
"subcommand",
|
43
|
+
"subcommand_group",
|
44
|
+
"OptionMetadata",
|
45
|
+
"AppCommandContext", # To be defined
|
46
|
+
]
|