Voice et bot modif

This commit is contained in:
pi 2026-06-16 17:09:34 +00:00
parent 189d56026b
commit 7333a22bcd
10774 changed files with 634644 additions and 933308 deletions

View file

@ -56,6 +56,8 @@ from typing import (
TYPE_CHECKING,
)
import unicodedata
import collections.abc
from itertools import islice
from base64 import b64encode, b64decode
from bisect import bisect_left
import datetime
@ -74,11 +76,6 @@ import logging
import yarl
if sys.version_info >= (3, 14):
import compression.zstd
else:
import zlib
try:
import orjson # type: ignore
except ModuleNotFoundError:
@ -86,12 +83,20 @@ except ModuleNotFoundError:
else:
HAS_ORJSON = True
_ZSTD_SOURCE: Literal['zstandard', 'compression.zstd'] | None = None
try:
import zstandard # type: ignore
from zstandard import ZstdDecompressor # type: ignore
_ZSTD_SOURCE = 'zstandard'
except ImportError:
_HAS_ZSTD = False
else:
_HAS_ZSTD = True
try:
from compression.zstd import ZstdDecompressor # type: ignore
_ZSTD_SOURCE = 'compression.zstd'
except ImportError:
import zlib
__all__ = (
'oauth_url',
@ -113,6 +118,7 @@ __all__ = (
DISCORD_EPOCH = 1420070400000
DEFAULT_FILE_SIZE_LIMIT_BYTES = 10485760
TIMESTAMP_PATTERN: re.Pattern[str] = re.compile(r'<t:(-?\d+)(?::[tTdDfFsSR])?>')
class _MissingSentinel:
@ -431,7 +437,7 @@ def time_snowflake(dt: datetime.datetime, /, *, high: bool = False) -> int:
def _find(predicate: Callable[[T], Any], iterable: Iterable[T], /) -> Optional[T]:
return next((element for element in iterable if predicate(element)), None)
return next(filter(predicate, iterable), None)
async def _afind(predicate: Callable[[T], Any], iterable: AsyncIterable[T], /) -> Optional[T]:
@ -1034,17 +1040,18 @@ def escape_mentions(text: str) -> str:
def _chunk(iterator: Iterable[T], max_size: int) -> Iterator[List[T]]:
ret = []
n = 0
for item in iterator:
ret.append(item)
n += 1
if n == max_size:
yield ret
ret = []
n = 0
if ret:
yield ret
# Specialise iterators that can be sliced as it is much faster
if isinstance(iterator, collections.abc.Sequence):
for i in range(0, len(iterator), max_size):
yield list(iterator[i : i + max_size])
else:
# Fallback to slower path
iterator = iter(iterator)
while True:
batch = list(islice(iterator, max_size))
if not batch:
break
yield batch
async def _achunk(iterator: AsyncIterable[T], max_size: int) -> AsyncIterator[List[T]]:
@ -1221,7 +1228,7 @@ def is_inside_class(func: Callable[..., Any]) -> bool:
return not remaining.endswith('<locals>')
TimestampStyle = Literal['f', 'F', 'd', 'D', 't', 'T', 'R']
TimestampStyle = Literal['f', 'F', 'd', 'D', 't', 'T', 's', 'S', 'R']
def format_dt(dt: datetime.datetime, /, style: Optional[TimestampStyle] = None) -> str:
@ -1229,23 +1236,27 @@ def format_dt(dt: datetime.datetime, /, style: Optional[TimestampStyle] = None)
This allows for a locale-independent way of presenting data using Discord specific Markdown.
+-------------+----------------------------+-----------------+
| Style | Example Output | Description |
+=============+============================+=================+
| t | 22:57 | Short Time |
+-------------+----------------------------+-----------------+
| T | 22:57:58 | Long Time |
+-------------+----------------------------+-----------------+
| d | 17/05/2016 | Short Date |
+-------------+----------------------------+-----------------+
| D | 17 May 2016 | Long Date |
+-------------+----------------------------+-----------------+
| f (default) | 17 May 2016 22:57 | Short Date Time |
+-------------+----------------------------+-----------------+
| F | Tuesday, 17 May 2016 22:57 | Long Date Time |
+-------------+----------------------------+-----------------+
| R | 5 years ago | Relative Time |
+-------------+----------------------------+-----------------+
+-------------+--------------------------------+-------------------------+
| Style | Example Output | Description |
+=============+================================+=========================+
| t | 22:57 | Short Time |
+-------------+--------------------------------+-------------------------+
| T | 22:57:58 | Medium Time |
+-------------+--------------------------------+-------------------------+
| d | 17/05/2016 | Short Date |
+-------------+--------------------------------+-------------------------+
| D | May 17, 2016 | Long Date |
+-------------+--------------------------------+-------------------------+
| f (default) | May 17, 2016 at 22:57 | Long Date, Short Time |
+-------------+--------------------------------+-------------------------+
| F | Tuesday, May 17, 2016 at 22:57 | Full Date, Short Time |
+-------------+--------------------------------+-------------------------+
| s | 17/05/2016, 22:57 | Short Date, Short Time |
+-------------+--------------------------------+-------------------------+
| S | 17/05/2016, 22:57:58 | Short Date, Medium Time |
+-------------+--------------------------------+-------------------------+
| R | 5 years ago | Relative Time |
+-------------+--------------------------------+-------------------------+
Note that the exact output depends on the user's locale setting in the client. The example output
presented is using the ``en-GB`` locale.
@ -1426,35 +1437,25 @@ def _human_join(seq: Sequence[str], /, *, delimiter: str = ', ', final: str = 'o
return delimiter.join(seq[:-1]) + f' {final} {seq[-1]}'
if _HAS_ZSTD:
if _ZSTD_SOURCE is not None:
class _ZstdDecompressionContext:
__slots__ = ('context',)
__slots__ = ('decompressor',)
COMPRESSION_TYPE: str = 'zstd-stream'
def __init__(self) -> None:
decompressor = zstandard.ZstdDecompressor()
self.context = decompressor.decompressobj()
self.decompressor = ZstdDecompressor()
if _ZSTD_SOURCE == 'zstandard':
# The default API for zstandard requires a size hint when
# the size is not included in the zstandard frame.
# This constructs an instance of zstandard.ZstdDecompressionObj
# which dynamically allocates a buffer, matching stdlib module's behavior.
self.decompressor = self.decompressor.decompressobj()
def decompress(self, data: bytes, /) -> str | None:
# Each WS message is a complete gateway message
return self.context.decompress(data).decode('utf-8')
_ActiveDecompressionContext: Type[_DecompressionContext] = _ZstdDecompressionContext
elif sys.version_info >= (3, 14):
class _ZstdDecompressionContext:
__slots__ = ('context',)
COMPRESSION_TYPE: str = 'zstd-stream'
def __init__(self) -> None:
self.context = compression.zstd.ZstdDecompressor()
def decompress(self, data: bytes, /) -> str | None:
# Each WS message is a complete gateway message
return self.context.decompress(data).decode('utf-8')
return self.decompressor.decompress(data).decode('utf-8')
_ActiveDecompressionContext: Type[_DecompressionContext] = _ZstdDecompressionContext
else: