disagreement 0.2.0rc1__py3-none-any.whl → 0.4.0__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 +2 -4
- disagreement/audio.py +42 -5
- disagreement/cache.py +43 -4
- disagreement/caching.py +121 -0
- disagreement/client.py +1682 -1535
- disagreement/enums.py +10 -3
- disagreement/error_handler.py +5 -1
- disagreement/errors.py +1341 -3
- disagreement/event_dispatcher.py +3 -5
- disagreement/ext/__init__.py +1 -0
- disagreement/ext/app_commands/__init__.py +0 -2
- disagreement/ext/app_commands/commands.py +0 -2
- disagreement/ext/app_commands/context.py +0 -2
- disagreement/ext/app_commands/converters.py +2 -4
- disagreement/ext/app_commands/decorators.py +5 -7
- disagreement/ext/app_commands/handler.py +1 -3
- disagreement/ext/app_commands/hybrid.py +0 -2
- disagreement/ext/commands/__init__.py +63 -61
- disagreement/ext/commands/cog.py +0 -2
- disagreement/ext/commands/converters.py +16 -5
- disagreement/ext/commands/core.py +728 -563
- disagreement/ext/commands/decorators.py +294 -219
- disagreement/ext/commands/errors.py +0 -2
- disagreement/ext/commands/help.py +0 -2
- disagreement/ext/commands/view.py +1 -3
- disagreement/gateway.py +632 -586
- disagreement/http.py +1362 -1041
- disagreement/interactions.py +0 -2
- disagreement/models.py +2682 -2263
- disagreement/shard_manager.py +0 -2
- disagreement/ui/view.py +167 -165
- disagreement/voice_client.py +263 -162
- {disagreement-0.2.0rc1.dist-info → disagreement-0.4.0.dist-info}/METADATA +33 -6
- disagreement-0.4.0.dist-info/RECORD +55 -0
- disagreement-0.2.0rc1.dist-info/RECORD +0 -54
- {disagreement-0.2.0rc1.dist-info → disagreement-0.4.0.dist-info}/WHEEL +0 -0
- {disagreement-0.2.0rc1.dist-info → disagreement-0.4.0.dist-info}/licenses/LICENSE +0 -0
- {disagreement-0.2.0rc1.dist-info → disagreement-0.4.0.dist-info}/top_level.txt +0 -0
disagreement/voice_client.py
CHANGED
@@ -1,162 +1,263 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
import
|
7
|
-
import
|
8
|
-
import
|
9
|
-
from
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
self
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
self.
|
58
|
-
self.
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
self.
|
76
|
-
self.
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
self.
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
1
|
+
"""Voice gateway and UDP audio client."""
|
2
|
+
|
3
|
+
from __future__ import annotations
|
4
|
+
|
5
|
+
import asyncio
|
6
|
+
import contextlib
|
7
|
+
import socket
|
8
|
+
import threading
|
9
|
+
from array import array
|
10
|
+
|
11
|
+
|
12
|
+
def _apply_volume(data: bytes, volume: float) -> bytes:
|
13
|
+
samples = array("h")
|
14
|
+
samples.frombytes(data)
|
15
|
+
for i, sample in enumerate(samples):
|
16
|
+
scaled = int(sample * volume)
|
17
|
+
if scaled > 32767:
|
18
|
+
scaled = 32767
|
19
|
+
elif scaled < -32768:
|
20
|
+
scaled = -32768
|
21
|
+
samples[i] = scaled
|
22
|
+
return samples.tobytes()
|
23
|
+
|
24
|
+
|
25
|
+
from typing import TYPE_CHECKING, Optional, Sequence
|
26
|
+
|
27
|
+
import aiohttp
|
28
|
+
|
29
|
+
# The following import is correct, but may be flagged by Pylance if the virtual
|
30
|
+
# environment is not configured correctly.
|
31
|
+
from nacl.secret import SecretBox
|
32
|
+
|
33
|
+
from .audio import AudioSink, AudioSource, FFmpegAudioSource
|
34
|
+
from .models import User
|
35
|
+
|
36
|
+
if TYPE_CHECKING:
|
37
|
+
from .client import Client
|
38
|
+
|
39
|
+
|
40
|
+
class VoiceClient:
|
41
|
+
"""Handles the Discord voice WebSocket connection and UDP streaming."""
|
42
|
+
|
43
|
+
def __init__(
|
44
|
+
self,
|
45
|
+
client: Client,
|
46
|
+
endpoint: str,
|
47
|
+
session_id: str,
|
48
|
+
token: str,
|
49
|
+
guild_id: int,
|
50
|
+
user_id: int,
|
51
|
+
*,
|
52
|
+
ws=None,
|
53
|
+
udp: Optional[socket.socket] = None,
|
54
|
+
loop: Optional[asyncio.AbstractEventLoop] = None,
|
55
|
+
verbose: bool = False,
|
56
|
+
) -> None:
|
57
|
+
self.client = client
|
58
|
+
self.endpoint = endpoint
|
59
|
+
self.session_id = session_id
|
60
|
+
self.token = token
|
61
|
+
self.guild_id = str(guild_id)
|
62
|
+
self.user_id = str(user_id)
|
63
|
+
self._ws: Optional[aiohttp.ClientWebSocketResponse] = ws
|
64
|
+
self._udp = udp
|
65
|
+
self._session: Optional[aiohttp.ClientSession] = None
|
66
|
+
self._heartbeat_task: Optional[asyncio.Task] = None
|
67
|
+
self._receive_task: Optional[asyncio.Task] = None
|
68
|
+
self._udp_receive_thread: Optional[threading.Thread] = None
|
69
|
+
self._heartbeat_interval: Optional[float] = None
|
70
|
+
try:
|
71
|
+
self._loop = loop or asyncio.get_running_loop()
|
72
|
+
except RuntimeError:
|
73
|
+
self._loop = asyncio.new_event_loop()
|
74
|
+
asyncio.set_event_loop(self._loop)
|
75
|
+
self.verbose = verbose
|
76
|
+
self.ssrc: Optional[int] = None
|
77
|
+
self.secret_key: Optional[Sequence[int]] = None
|
78
|
+
self._server_ip: Optional[str] = None
|
79
|
+
self._server_port: Optional[int] = None
|
80
|
+
self._current_source: Optional[AudioSource] = None
|
81
|
+
self._play_task: Optional[asyncio.Task] = None
|
82
|
+
self._sink: Optional[AudioSink] = None
|
83
|
+
self._ssrc_map: dict[int, int] = {}
|
84
|
+
self._ssrc_lock = threading.Lock()
|
85
|
+
|
86
|
+
async def connect(self) -> None:
|
87
|
+
if self._ws is None:
|
88
|
+
self._session = aiohttp.ClientSession()
|
89
|
+
self._ws = await self._session.ws_connect(self.endpoint)
|
90
|
+
|
91
|
+
hello = await self._ws.receive_json()
|
92
|
+
self._heartbeat_interval = hello["d"]["heartbeat_interval"] / 1000
|
93
|
+
self._heartbeat_task = self._loop.create_task(self._heartbeat())
|
94
|
+
|
95
|
+
await self._ws.send_json(
|
96
|
+
{
|
97
|
+
"op": 0,
|
98
|
+
"d": {
|
99
|
+
"server_id": self.guild_id,
|
100
|
+
"user_id": self.user_id,
|
101
|
+
"session_id": self.session_id,
|
102
|
+
"token": self.token,
|
103
|
+
},
|
104
|
+
}
|
105
|
+
)
|
106
|
+
|
107
|
+
ready = await self._ws.receive_json()
|
108
|
+
data = ready["d"]
|
109
|
+
self.ssrc = data["ssrc"]
|
110
|
+
self._server_ip = data["ip"]
|
111
|
+
self._server_port = data["port"]
|
112
|
+
|
113
|
+
if self._udp is None:
|
114
|
+
self._udp = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
115
|
+
self._udp.connect((self._server_ip, self._server_port))
|
116
|
+
|
117
|
+
await self._ws.send_json(
|
118
|
+
{
|
119
|
+
"op": 1,
|
120
|
+
"d": {
|
121
|
+
"protocol": "udp",
|
122
|
+
"data": {
|
123
|
+
"address": self._udp.getsockname()[0],
|
124
|
+
"port": self._udp.getsockname()[1],
|
125
|
+
"mode": "xsalsa20_poly1305",
|
126
|
+
},
|
127
|
+
},
|
128
|
+
}
|
129
|
+
)
|
130
|
+
|
131
|
+
session_desc = await self._ws.receive_json()
|
132
|
+
self.secret_key = session_desc["d"].get("secret_key")
|
133
|
+
|
134
|
+
async def _heartbeat(self) -> None:
|
135
|
+
assert self._ws is not None
|
136
|
+
assert self._heartbeat_interval is not None
|
137
|
+
try:
|
138
|
+
while True:
|
139
|
+
await self._ws.send_json({"op": 3, "d": int(self._loop.time() * 1000)})
|
140
|
+
await asyncio.sleep(self._heartbeat_interval)
|
141
|
+
except asyncio.CancelledError:
|
142
|
+
pass
|
143
|
+
|
144
|
+
async def _receive_loop(self) -> None:
|
145
|
+
assert self._ws is not None
|
146
|
+
while True:
|
147
|
+
try:
|
148
|
+
msg = await self._ws.receive_json()
|
149
|
+
op = msg.get("op")
|
150
|
+
data = msg.get("d")
|
151
|
+
if op == 5: # Speaking
|
152
|
+
user_id = int(data["user_id"])
|
153
|
+
ssrc = data["ssrc"]
|
154
|
+
with self._ssrc_lock:
|
155
|
+
self._ssrc_map[ssrc] = user_id
|
156
|
+
except (asyncio.CancelledError, aiohttp.ClientError):
|
157
|
+
break
|
158
|
+
|
159
|
+
def _udp_receive_loop(self) -> None:
|
160
|
+
assert self._udp is not None
|
161
|
+
assert self.secret_key is not None
|
162
|
+
box = SecretBox(bytes(self.secret_key))
|
163
|
+
while True:
|
164
|
+
try:
|
165
|
+
packet = self._udp.recv(4096)
|
166
|
+
if len(packet) < 12:
|
167
|
+
continue
|
168
|
+
|
169
|
+
ssrc = int.from_bytes(packet[8:12], "big")
|
170
|
+
with self._ssrc_lock:
|
171
|
+
if ssrc not in self._ssrc_map:
|
172
|
+
continue
|
173
|
+
user_id = self._ssrc_map[ssrc]
|
174
|
+
user = self.client._users.get(str(user_id))
|
175
|
+
if not user:
|
176
|
+
continue
|
177
|
+
|
178
|
+
decrypted = box.decrypt(packet[12:])
|
179
|
+
if self._sink:
|
180
|
+
self._sink.write(user, decrypted)
|
181
|
+
except (socket.error, asyncio.CancelledError):
|
182
|
+
break
|
183
|
+
except Exception as e:
|
184
|
+
if self.verbose:
|
185
|
+
print(f"Error in UDP receive loop: {e}")
|
186
|
+
|
187
|
+
async def send_audio_frame(self, frame: bytes) -> None:
|
188
|
+
if not self._udp:
|
189
|
+
raise RuntimeError("UDP socket not initialised")
|
190
|
+
self._udp.send(frame)
|
191
|
+
|
192
|
+
async def _play_loop(self) -> None:
|
193
|
+
assert self._current_source is not None
|
194
|
+
try:
|
195
|
+
while True:
|
196
|
+
data = await self._current_source.read()
|
197
|
+
if not data:
|
198
|
+
break
|
199
|
+
volume = getattr(self._current_source, "volume", 1.0)
|
200
|
+
if volume != 1.0:
|
201
|
+
data = _apply_volume(data, volume)
|
202
|
+
await self.send_audio_frame(data)
|
203
|
+
finally:
|
204
|
+
await self._current_source.close()
|
205
|
+
self._current_source = None
|
206
|
+
self._play_task = None
|
207
|
+
|
208
|
+
async def stop(self) -> None:
|
209
|
+
if self._play_task:
|
210
|
+
self._play_task.cancel()
|
211
|
+
with contextlib.suppress(asyncio.CancelledError):
|
212
|
+
await self._play_task
|
213
|
+
self._play_task = None
|
214
|
+
if self._current_source:
|
215
|
+
await self._current_source.close()
|
216
|
+
self._current_source = None
|
217
|
+
|
218
|
+
async def play(self, source: AudioSource, *, wait: bool = True) -> None:
|
219
|
+
"""|coro| Play an :class:`AudioSource` on the voice connection."""
|
220
|
+
|
221
|
+
await self.stop()
|
222
|
+
self._current_source = source
|
223
|
+
self._play_task = self._loop.create_task(self._play_loop())
|
224
|
+
if wait:
|
225
|
+
await self._play_task
|
226
|
+
|
227
|
+
async def play_file(self, filename: str, *, wait: bool = True) -> None:
|
228
|
+
"""|coro| Stream an audio file or URL using FFmpeg."""
|
229
|
+
|
230
|
+
await self.play(FFmpegAudioSource(filename), wait=wait)
|
231
|
+
|
232
|
+
def listen(self, sink: AudioSink) -> None:
|
233
|
+
"""Start listening to voice and routing to a sink."""
|
234
|
+
if not isinstance(sink, AudioSink):
|
235
|
+
raise TypeError("sink must be an AudioSink instance")
|
236
|
+
|
237
|
+
self._sink = sink
|
238
|
+
if not self._udp_receive_thread:
|
239
|
+
self._udp_receive_thread = threading.Thread(
|
240
|
+
target=self._udp_receive_loop, daemon=True
|
241
|
+
)
|
242
|
+
self._udp_receive_thread.start()
|
243
|
+
|
244
|
+
async def close(self) -> None:
|
245
|
+
await self.stop()
|
246
|
+
if self._heartbeat_task:
|
247
|
+
self._heartbeat_task.cancel()
|
248
|
+
with contextlib.suppress(asyncio.CancelledError):
|
249
|
+
await self._heartbeat_task
|
250
|
+
if self._receive_task:
|
251
|
+
self._receive_task.cancel()
|
252
|
+
with contextlib.suppress(asyncio.CancelledError):
|
253
|
+
await self._receive_task
|
254
|
+
if self._ws:
|
255
|
+
await self._ws.close()
|
256
|
+
if self._session:
|
257
|
+
await self._session.close()
|
258
|
+
if self._udp:
|
259
|
+
self._udp.close()
|
260
|
+
if self._udp_receive_thread:
|
261
|
+
self._udp_receive_thread.join(timeout=1)
|
262
|
+
if self._sink:
|
263
|
+
self._sink.close()
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: disagreement
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.4.0
|
4
4
|
Summary: A Python library for the Discord API.
|
5
5
|
Author-email: Slipstream <me@slipstreamm.dev>
|
6
6
|
License: BSD 3-Clause
|
@@ -23,6 +23,7 @@ Requires-Python: >=3.10
|
|
23
23
|
Description-Content-Type: text/markdown
|
24
24
|
License-File: LICENSE
|
25
25
|
Requires-Dist: aiohttp<4.0.0,>=3.9.0
|
26
|
+
Requires-Dist: PyNaCl<2.0.0,>=1.5.0
|
26
27
|
Provides-Extra: test
|
27
28
|
Requires-Dist: pytest>=8.0.0; extra == "test"
|
28
29
|
Requires-Dist: pytest-asyncio>=1.0.0; extra == "test"
|
@@ -37,6 +38,9 @@ A Python library for interacting with the Discord API, with a focus on bot devel
|
|
37
38
|
|
38
39
|
## Features
|
39
40
|
|
41
|
+
- Internationalization helpers
|
42
|
+
- Hybrid context for commands
|
43
|
+
- Built-in rate limiting
|
40
44
|
- Asynchronous design using `aiohttp`
|
41
45
|
- Gateway and HTTP API clients
|
42
46
|
- Slash command framework
|
@@ -56,6 +60,13 @@ pip install -e .
|
|
56
60
|
|
57
61
|
Requires Python 3.10 or newer.
|
58
62
|
|
63
|
+
To run the example scripts, you'll need the `python-dotenv` package to load
|
64
|
+
environment variables. Install the development extras with:
|
65
|
+
|
66
|
+
```bash
|
67
|
+
pip install "disagreement[dev]"
|
68
|
+
```
|
69
|
+
|
59
70
|
## Basic Usage
|
60
71
|
|
61
72
|
```python
|
@@ -64,6 +75,8 @@ import os
|
|
64
75
|
|
65
76
|
import disagreement
|
66
77
|
from disagreement.ext import commands
|
78
|
+
from dotenv import load_dotenv
|
79
|
+
load_dotenv()
|
67
80
|
|
68
81
|
|
69
82
|
class Basics(commands.Cog):
|
@@ -72,18 +85,17 @@ class Basics(commands.Cog):
|
|
72
85
|
|
73
86
|
@commands.command()
|
74
87
|
async def ping(self, ctx: commands.CommandContext) -> None:
|
75
|
-
await ctx.reply("Pong!")
|
88
|
+
await ctx.reply(f"Pong! Gateway Latency: {self.client.latency_ms} ms.")
|
76
89
|
|
77
90
|
|
78
91
|
token = os.getenv("DISCORD_BOT_TOKEN")
|
79
92
|
if not token:
|
80
93
|
raise RuntimeError("DISCORD_BOT_TOKEN environment variable not set")
|
81
94
|
|
82
|
-
|
83
|
-
client.
|
84
|
-
|
85
|
-
|
95
|
+
intents = disagreement.GatewayIntent.default() | disagreement.GatewayIntent.MESSAGE_CONTENT
|
96
|
+
client = disagreement.Client(token=token, command_prefix="!", intents=intents, mention_replies=True)
|
86
97
|
async def main() -> None:
|
98
|
+
client.add_cog(Basics(client))
|
87
99
|
await client.run()
|
88
100
|
|
89
101
|
|
@@ -135,6 +147,20 @@ These options are forwarded to ``HTTPClient`` when it creates the underlying
|
|
135
147
|
``aiohttp.ClientSession``. You can specify a custom ``connector`` or any other
|
136
148
|
session parameter supported by ``aiohttp``.
|
137
149
|
|
150
|
+
### Default Allowed Mentions
|
151
|
+
|
152
|
+
Specify default mention behaviour for all outgoing messages when constructing the client:
|
153
|
+
|
154
|
+
```python
|
155
|
+
client = disagreement.Client(
|
156
|
+
token=token,
|
157
|
+
allowed_mentions={"parse": [], "replied_user": False},
|
158
|
+
)
|
159
|
+
```
|
160
|
+
|
161
|
+
This dictionary is used whenever ``send_message`` is called without an explicit
|
162
|
+
``allowed_mentions`` argument.
|
163
|
+
|
138
164
|
### Defining Subcommands with `AppCommandGroup`
|
139
165
|
|
140
166
|
```python
|
@@ -153,6 +179,7 @@ async def show(ctx: AppCommandContext, key: str):
|
|
153
179
|
@slash_command(name="set", description="Update a setting.", parent=admin_group)
|
154
180
|
async def set_setting(ctx: AppCommandContext, key: str, value: str):
|
155
181
|
...
|
182
|
+
```
|
156
183
|
## Fetching Guilds
|
157
184
|
|
158
185
|
Use `Client.fetch_guild` to retrieve a guild from the Discord API if it
|
@@ -0,0 +1,55 @@
|
|
1
|
+
disagreement/__init__.py,sha256=-_a69aQUTp1AlZNLLbetYzvV4sEhvnfrHwlU673WkIE,1137
|
2
|
+
disagreement/audio.py,sha256=erBaupz-Hw8LR-5mGLDvhphCDAQeWk0ZBA0AMVwDUIM,4360
|
3
|
+
disagreement/cache.py,sha256=srmaw-x8iiqU53eh33JgLLkM-K-TgFnvOS2lYO7Z2FI,2866
|
4
|
+
disagreement/caching.py,sha256=KEicB8fIBRwc5Ifl1CCHHnPu-NfAvqdfArjxFuV557g,3841
|
5
|
+
disagreement/client.py,sha256=RBiprWFfW02Wkt8FwHaYvJfcK4vOR559Fn5p26ab9ME,67441
|
6
|
+
disagreement/color.py,sha256=0RumZU9geS51rmmywwotmkXFc8RyQghOviRGGrHmvW4,4495
|
7
|
+
disagreement/components.py,sha256=tEYJ2RHVpIFtZuPPxZ0v8ssUw_x7ybhYBzHNsRiXXvU,5250
|
8
|
+
disagreement/enums.py,sha256=F_DHgeAnnw17ILswOuxPR6G1OimL6aeuxIEAni1XPyY,11187
|
9
|
+
disagreement/error_handler.py,sha256=rj9AiJhRLPNAaAY6Gj0KQXgKNfPsgnZUtyTljclybD8,1161
|
10
|
+
disagreement/errors.py,sha256=Zi7x_hgGXCDw5ht2HpcQDba4NQbXkBbjQIVhU9RVyhE,32236
|
11
|
+
disagreement/event_dispatcher.py,sha256=o-PgfOYEwlCbmrWeLuycp-QT6tlXF2JEU3Dyv0VFZ0c,11419
|
12
|
+
disagreement/gateway.py,sha256=7ccRygL1gnd_w8DldsLFxreZy1iCdw6Nw65_UW8Ulz8,26831
|
13
|
+
disagreement/http.py,sha256=iYmX6QjBEkcZlHJTefJ-tHHYp8BV4TTQYE-vaHGjfUk,51729
|
14
|
+
disagreement/hybrid_context.py,sha256=VYCmcreTZdPBU9v-Cy48W38vgWO2t8nM2ulC6_z4HjU,1095
|
15
|
+
disagreement/i18n.py,sha256=1L4rcFuKP0XjHk9dVwbNh4BkLk2ZlxxZ_-tecGWa9S0,718
|
16
|
+
disagreement/interactions.py,sha256=moN2iQEE9ntC-Y2Q7uxUqoBBRYHegNwB00w-2UD30q4,21703
|
17
|
+
disagreement/logging_config.py,sha256=4q6baQPE6X_0lfaBTFMU1uqc03x5SbJqo2hsApdDFac,686
|
18
|
+
disagreement/models.py,sha256=ohpMS03K9Hs9lJ2uWLG_0P3VTJr8sSy9dNsc3uRerpM,97981
|
19
|
+
disagreement/oauth.py,sha256=TfDdCwg1J7osM9wDi61dtNBA5BrQk5DeQrrHsYycH34,2810
|
20
|
+
disagreement/permissions.py,sha256=7g5cIlg-evHXOL0-pmtT5EwqcB-stXot1HZSLz724sE,3008
|
21
|
+
disagreement/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
22
|
+
disagreement/rate_limiter.py,sha256=ubwR_UTPs2MotipBdtqpgwQKx0IHt2I3cdfFcXTFv7g,2521
|
23
|
+
disagreement/shard_manager.py,sha256=gE7562izYcN-5jTDWUP9kIFX5gffRjIryqNxk1mtnSM,2128
|
24
|
+
disagreement/typing.py,sha256=_1oFWfZ4HyH5Q3bnF7CO24s79z-3_B5Qb69kWiwLhhU,1242
|
25
|
+
disagreement/utils.py,sha256=mz7foTCOAmUv9n8EcdZeiFarwqB14xHOG8o0p8tFuKA,2014
|
26
|
+
disagreement/voice_client.py,sha256=AgBhId6syetP4wwHq47IgGlfNIqtLUt_5nbEE-c6KtQ,9250
|
27
|
+
disagreement/ext/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
28
|
+
disagreement/ext/loader.py,sha256=9_uULvNAa-a6UiaeQhWglwgIrHEPKbf9bnWtSL1KV5Q,1408
|
29
|
+
disagreement/ext/tasks.py,sha256=b14KI-btikbrjPlD76md3Ggt6znrxPqr7TDarU4PYBg,7269
|
30
|
+
disagreement/ext/app_commands/__init__.py,sha256=sVCAgeuu2EIqErP8SGqB8ytSsoL7YuYvD1xY3J2POJ4,969
|
31
|
+
disagreement/ext/app_commands/commands.py,sha256=yjMi-fc2gcRPjeXpcb3Re_HjDsvC8-zpUwGfTsxYXWU,18973
|
32
|
+
disagreement/ext/app_commands/context.py,sha256=MyEhXFgelxV6d4KZUrgGwFy60uSsr4v8mnC6z2Ivdxo,20787
|
33
|
+
disagreement/ext/app_commands/converters.py,sha256=CvkZwZ0xA8WgFiL018-vGA5JL0kl9rBE_68ME_ra37c,20877
|
34
|
+
disagreement/ext/app_commands/decorators.py,sha256=awnZICfZd9bjP4rDeS5YPBzFzldxbfVOBEneLqAjwHw,22661
|
35
|
+
disagreement/ext/app_commands/handler.py,sha256=T0T1jmFVozrfRewmeVdiHjzVLEzypEixnY9jchOJASM,28716
|
36
|
+
disagreement/ext/app_commands/hybrid.py,sha256=q07qjMOLBOvbjoZwsIoGkdFqnDzvZsdWuavcHXfuAPg,3287
|
37
|
+
disagreement/ext/commands/__init__.py,sha256=MzdDf3Gr9H745C-cA9xYOI1eLgmAl25qQVwtrEVj_DA,1320
|
38
|
+
disagreement/ext/commands/cog.py,sha256=VIx1kgO1HP_y1EdbeuFhnA9C_4QsstD7608akQmDP9c,6809
|
39
|
+
disagreement/ext/commands/converters.py,sha256=Xt4LkPxc4uX1ivOno75Y6smgwilaGhw_dSR8NH7EDzA,6300
|
40
|
+
disagreement/ext/commands/core.py,sha256=k2HgC40Jz0d6-1023LIi2S3UW5qP8gt_vQsV0mgU0B8,28352
|
41
|
+
disagreement/ext/commands/decorators.py,sha256=nsCF73fMH14Ox_dZbCEFD3KqwlLqqyJpEr7uAtfQ4Kg,10380
|
42
|
+
disagreement/ext/commands/errors.py,sha256=6Chp5FW8OVIUNdAnyu6cM8LXanhOzE95OvEZVR4DgJo,2262
|
43
|
+
disagreement/ext/commands/help.py,sha256=A0y-p18Vou0HG4KSHwTufZCgLXNJ8SDM-oMQEeNmaps,1419
|
44
|
+
disagreement/ext/commands/view.py,sha256=b4K83xGq5PmfDgA8uQZyOwVfKE4rzK8MyHQuUmDINJc,3215
|
45
|
+
disagreement/ui/__init__.py,sha256=PLA6eHiq9cu7JDOKS-7MKtaFhlqswjbI4AEUlpnbgO0,307
|
46
|
+
disagreement/ui/button.py,sha256=GHbY3-yMrvv6u674-qYONocuC1e2a0flEWjPKwJXKDo,3163
|
47
|
+
disagreement/ui/item.py,sha256=bm-EmQEZpe8Kt8JrRw-o0uQdccgjErORcFsBqaXOcV8,1112
|
48
|
+
disagreement/ui/modal.py,sha256=w0ZEVslXzx2-RWUP4jdVB54zDuT81jpueVWZ70byFnI,4137
|
49
|
+
disagreement/ui/select.py,sha256=XjWRlWkA09QZaDDLn-wDDOWIuj0Mb4VCWJEOAaExZXw,3018
|
50
|
+
disagreement/ui/view.py,sha256=UdOaoSe0NZXZMjOtM8CLCPcDHVf6Dn2yr2PHLSvoJsg,5834
|
51
|
+
disagreement-0.4.0.dist-info/licenses/LICENSE,sha256=zfmtgJhVFHnqT7a8LAQFthXu5bP7EEHmEL99trV66Ew,1474
|
52
|
+
disagreement-0.4.0.dist-info/METADATA,sha256=5kvSnyoSMfRzlbaDZoOaRX-6tWlA8Nuy_XX-PfxAQUQ,6268
|
53
|
+
disagreement-0.4.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
54
|
+
disagreement-0.4.0.dist-info/top_level.txt,sha256=t7FY_3iaYhdB6X6y9VybJ2j7UZbVeRUe9wRgH8d5Gtk,13
|
55
|
+
disagreement-0.4.0.dist-info/RECORD,,
|
@@ -1,54 +0,0 @@
|
|
1
|
-
disagreement/__init__.py,sha256=tZlZwEhqnBj3CEfPX2BWXXvGIc5OIiLtzuybRG7w1wA,1184
|
2
|
-
disagreement/audio.py,sha256=P6inobI8CNhNVkaRKU58RMYtLq1RrSREioF0Mui5VlA,3351
|
3
|
-
disagreement/cache.py,sha256=juabGFl4naQih5OUIVN2aN-vAfw2ZC2cI38s4nGEn8U,1525
|
4
|
-
disagreement/client.py,sha256=WJ1xLiXMha0_9i0rUDxXiMWXSG80_fXylq3Qmf9rr7k,59855
|
5
|
-
disagreement/color.py,sha256=0RumZU9geS51rmmywwotmkXFc8RyQghOviRGGrHmvW4,4495
|
6
|
-
disagreement/components.py,sha256=tEYJ2RHVpIFtZuPPxZ0v8ssUw_x7ybhYBzHNsRiXXvU,5250
|
7
|
-
disagreement/enums.py,sha256=Km9rzmbkYdBpba3fDAv9YYtXDROoRpKuQfkMavsiY0s,11069
|
8
|
-
disagreement/error_handler.py,sha256=c2lb6aTMnhTtITQuR6axZUtEaasYKUgmdSxAHEkeq50,1028
|
9
|
-
disagreement/errors.py,sha256=XiYVPy8uFUGVi_EIf81yK7QbC7KyN4JHplSJSWw2RRk,3185
|
10
|
-
disagreement/event_dispatcher.py,sha256=mp4LVhIj0SW1P2NruqbYpZoYH33X5rXvkAl3-RK40kE,11460
|
11
|
-
disagreement/gateway.py,sha256=AxfGsSxu4eOWwpL3LQiNfcQVR3hyj33N9KfaPy0h8OU,24487
|
12
|
-
disagreement/http.py,sha256=TOGF2LBnsg4hTrP0sFBscKz1VVM_qZ8eoPZfBoQQPQw,37063
|
13
|
-
disagreement/hybrid_context.py,sha256=VYCmcreTZdPBU9v-Cy48W38vgWO2t8nM2ulC6_z4HjU,1095
|
14
|
-
disagreement/i18n.py,sha256=1L4rcFuKP0XjHk9dVwbNh4BkLk2ZlxxZ_-tecGWa9S0,718
|
15
|
-
disagreement/interactions.py,sha256=aUZwwEOLsEds15i6G-rxmSSDCDmaxz_cfoTYS4tv6Ao,21735
|
16
|
-
disagreement/logging_config.py,sha256=4q6baQPE6X_0lfaBTFMU1uqc03x5SbJqo2hsApdDFac,686
|
17
|
-
disagreement/models.py,sha256=Km75XDUiRV3gzhSPYDm2AByQEw2koZ-gyY1urvYffTE,82512
|
18
|
-
disagreement/oauth.py,sha256=TfDdCwg1J7osM9wDi61dtNBA5BrQk5DeQrrHsYycH34,2810
|
19
|
-
disagreement/permissions.py,sha256=7g5cIlg-evHXOL0-pmtT5EwqcB-stXot1HZSLz724sE,3008
|
20
|
-
disagreement/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
21
|
-
disagreement/rate_limiter.py,sha256=ubwR_UTPs2MotipBdtqpgwQKx0IHt2I3cdfFcXTFv7g,2521
|
22
|
-
disagreement/shard_manager.py,sha256=e9F8tx_4IEOlTX3-S3t51lfJToc6Ue3RVBzoNAiVKxs,2161
|
23
|
-
disagreement/typing.py,sha256=_1oFWfZ4HyH5Q3bnF7CO24s79z-3_B5Qb69kWiwLhhU,1242
|
24
|
-
disagreement/utils.py,sha256=mz7foTCOAmUv9n8EcdZeiFarwqB14xHOG8o0p8tFuKA,2014
|
25
|
-
disagreement/voice_client.py,sha256=i_67gJ-SQWi9YH-pgtFM8N0lCYznyuQImyL-mf2O7KQ,5384
|
26
|
-
disagreement/ext/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
27
|
-
disagreement/ext/loader.py,sha256=9_uULvNAa-a6UiaeQhWglwgIrHEPKbf9bnWtSL1KV5Q,1408
|
28
|
-
disagreement/ext/tasks.py,sha256=b14KI-btikbrjPlD76md3Ggt6znrxPqr7TDarU4PYBg,7269
|
29
|
-
disagreement/ext/app_commands/__init__.py,sha256=mnQLIuGP9SzqGMPEn5YgOh2eIU7lcYoDXP06vtXZfTA,1014
|
30
|
-
disagreement/ext/app_commands/commands.py,sha256=xjrVPScEezdVxVq524_E2Gm2sTa-yq44TbGMu0gyA2o,19018
|
31
|
-
disagreement/ext/app_commands/context.py,sha256=Xcm4Ka5K5uTQGviixF5LeCDdOdF9YQS5F7lZi2m--8s,20831
|
32
|
-
disagreement/ext/app_commands/converters.py,sha256=J1VEmo-7H9K7kGPJodu5FX4RmFFI1BuzhlQAEs2MsD4,21036
|
33
|
-
disagreement/ext/app_commands/decorators.py,sha256=dKiD4ZEsafRoPvfgn9zuQ9vvXXo2qYTMquHvyUM1604,23251
|
34
|
-
disagreement/ext/app_commands/handler.py,sha256=KCMi5NEusuyLYo7Vk4sqLqXAJI5r3ppI0MNLUh0kU2c,28781
|
35
|
-
disagreement/ext/app_commands/hybrid.py,sha256=u3kHNbVfY3-liymgzEIkFO5YV3WM_DqwytzdN9EXWMY,3330
|
36
|
-
disagreement/ext/commands/__init__.py,sha256=miejXIfft2kq2Q4Lej28awSgQXIEEeEuaBhR3M7f9tk,1230
|
37
|
-
disagreement/ext/commands/cog.py,sha256=-F2ZOXXC07r96xlt9NomRgqlIqlcxzBiha2Zhg1DVp4,6845
|
38
|
-
disagreement/ext/commands/converters.py,sha256=mh8xJr1FIiah6bdYy0KsdccfYcPii2Yc_IdhzCTw5uE,5864
|
39
|
-
disagreement/ext/commands/core.py,sha256=4AO-U9xFyDetWeQUZiqX_g4zZfue0-9s8QBnHIb2BTc,21265
|
40
|
-
disagreement/ext/commands/decorators.py,sha256=fOhppBae8gt-9QI1YqUzDctwOXmMBdAK_JaUJLNWHww,7427
|
41
|
-
disagreement/ext/commands/errors.py,sha256=L6losXKye62BqDl42fXxgkuAkG92W-OcqH9uwEgabb8,2301
|
42
|
-
disagreement/ext/commands/help.py,sha256=yw0ydupOsPwmnhsIIoxa93xjj9MAcBcGfD8BXa7V8G8,1456
|
43
|
-
disagreement/ext/commands/view.py,sha256=3Wo4gGJX9fb65qw8yHFwMjnAeJvMJAx19rZNHz-ZDUs,3315
|
44
|
-
disagreement/ui/__init__.py,sha256=PLA6eHiq9cu7JDOKS-7MKtaFhlqswjbI4AEUlpnbgO0,307
|
45
|
-
disagreement/ui/button.py,sha256=GHbY3-yMrvv6u674-qYONocuC1e2a0flEWjPKwJXKDo,3163
|
46
|
-
disagreement/ui/item.py,sha256=bm-EmQEZpe8Kt8JrRw-o0uQdccgjErORcFsBqaXOcV8,1112
|
47
|
-
disagreement/ui/modal.py,sha256=w0ZEVslXzx2-RWUP4jdVB54zDuT81jpueVWZ70byFnI,4137
|
48
|
-
disagreement/ui/select.py,sha256=XjWRlWkA09QZaDDLn-wDDOWIuj0Mb4VCWJEOAaExZXw,3018
|
49
|
-
disagreement/ui/view.py,sha256=QhWoYt39QKXwl1X6Mkm5gNNEqd8bt7O505lSpiG0L04,5567
|
50
|
-
disagreement-0.2.0rc1.dist-info/licenses/LICENSE,sha256=zfmtgJhVFHnqT7a8LAQFthXu5bP7EEHmEL99trV66Ew,1474
|
51
|
-
disagreement-0.2.0rc1.dist-info/METADATA,sha256=ZEw0xKaAbZyXurATHmXCYwODfC6pr98jo27SlubhC_Q,5382
|
52
|
-
disagreement-0.2.0rc1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
53
|
-
disagreement-0.2.0rc1.dist-info/top_level.txt,sha256=t7FY_3iaYhdB6X6y9VybJ2j7UZbVeRUe9wRgH8d5Gtk,13
|
54
|
-
disagreement-0.2.0rc1.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|