mirror of
https://github.com/stoatchat/python-client-sdk.git
synced 2026-07-21 01:55:23 -04:00
qol updates
This commit is contained in:
+1
-1
@@ -88,7 +88,7 @@ class Channel(Ulid):
|
||||
async def _get_channel_id(self) -> str:
|
||||
return self.id
|
||||
|
||||
def _update(self, **_):
|
||||
def _update(self, **_: Any):
|
||||
pass
|
||||
|
||||
async def delete(self):
|
||||
|
||||
+12
-2
@@ -1,6 +1,8 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING, Any, Optional, Union
|
||||
from typing import TYPE_CHECKING, Optional, TypedDict, Union
|
||||
|
||||
from typing_extensions import Unpack, NotRequired
|
||||
|
||||
from .asset import Asset
|
||||
from .enums import EmbedType
|
||||
@@ -69,8 +71,16 @@ def to_embed(payload: EmbedPayload, state: State) -> Embed:
|
||||
else:
|
||||
return NoneEmbed()
|
||||
|
||||
class EmbedParameters(TypedDict):
|
||||
title: NotRequired[str]
|
||||
description: NotRequired[str]
|
||||
media: NotRequired[str]
|
||||
icon_url: NotRequired[str]
|
||||
colour: NotRequired[str]
|
||||
url: NotRequired[str]
|
||||
|
||||
class SendableEmbed:
|
||||
def __init__(self, **attrs: dict[str, Any]):
|
||||
def __init__(self, **attrs: Unpack[EmbedParameters]):
|
||||
self.title: Optional[str] = None
|
||||
self.description: Optional[str] = None
|
||||
self.media: Optional[str] = None
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any, Callable, Coroutine, TypeVar, Union
|
||||
from typing import Any, Callable, Coroutine, TypeVar, Union, cast
|
||||
|
||||
from .command import Command
|
||||
from .context import Context
|
||||
@@ -14,7 +14,6 @@ T = TypeVar("T", Callable[..., Any], Command)
|
||||
|
||||
Check = Callable[[Context[ClientT]], Union[Any, Coroutine[Any, Any, Any]]]
|
||||
|
||||
|
||||
def check(check: Check[ClientT]):
|
||||
"""A decorator for adding command checks
|
||||
|
||||
@@ -25,7 +24,8 @@ def check(check: Check[ClientT]):
|
||||
"""
|
||||
def inner(func: T) -> T:
|
||||
if isinstance(func, Command):
|
||||
func.checks.append(check)
|
||||
command = cast(Command[ClientT], func) # cant verify generic at runtime so must cast
|
||||
command.checks.append(check)
|
||||
else:
|
||||
checks = getattr(func, "_checks", [])
|
||||
checks.append(check)
|
||||
|
||||
@@ -56,8 +56,11 @@ class CaseInsensitiveDict(dict[str, V]):
|
||||
def __getitem__(self, key: str) -> V:
|
||||
return super().__getitem__(key.casefold())
|
||||
|
||||
def __contains__(self, key: str) -> bool:
|
||||
return super().__contains__(key.casefold())
|
||||
def __contains__(self, key: object) -> bool:
|
||||
if isinstance(key, str):
|
||||
return super().__contains__(key.casefold())
|
||||
else:
|
||||
return False
|
||||
|
||||
@overload
|
||||
def get(self, key: str) -> V | None:
|
||||
@@ -67,7 +70,7 @@ class CaseInsensitiveDict(dict[str, V]):
|
||||
def get(self, key: str, default: V | T) -> V | T:
|
||||
...
|
||||
|
||||
def get(self, key: str, default: Optional[T] = None) -> V | T:
|
||||
def get(self, key: str, default: Optional[T] = None) -> V | T | None:
|
||||
return super().get(key.casefold(), default)
|
||||
|
||||
def __delitem__(self, key: str) -> None:
|
||||
@@ -92,9 +95,11 @@ class CommandsClient(revolt.Client, metaclass=CommandsMeta):
|
||||
for alias in command.aliases:
|
||||
self.all_commands[alias] = command
|
||||
|
||||
if not isinstance(help_command, revolt.utils._Missing):
|
||||
if help_command is not None:
|
||||
self.help_command = help_command or DefaultHelpCommand[Self]()
|
||||
self.add_command(HelpCommandImpl(self))
|
||||
else:
|
||||
self.help_command = None
|
||||
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any, Generic, Optional
|
||||
from typing import Any, Generic, Optional, cast
|
||||
|
||||
from .command import Command
|
||||
from .utils import ClientT
|
||||
@@ -19,7 +19,7 @@ class CogMeta(type, Generic[ClientT]):
|
||||
for base in reversed(self.__mro__):
|
||||
for value in base.__dict__.values():
|
||||
if isinstance(value, Command):
|
||||
commands.append(value)
|
||||
commands.append(cast(Command[ClientT], value)) # cant verify generic at runtime so must cast
|
||||
|
||||
|
||||
self._commands = commands
|
||||
|
||||
@@ -165,11 +165,16 @@ class HelpCommandImpl(Command[ClientT]):
|
||||
|
||||
|
||||
async def help_command_impl(self: ClientT, context: Context[ClientT], *arguments: str):
|
||||
filtered_commands = await context.client.help_command.filter_commands(context, self.commands)
|
||||
commands = await self.help_command.group_commands(context, filtered_commands)
|
||||
help_command = self.help_command
|
||||
|
||||
if not help_command:
|
||||
return
|
||||
|
||||
filtered_commands = await help_command.filter_commands(context, self.commands)
|
||||
commands = await help_command.group_commands(context, filtered_commands)
|
||||
|
||||
if not arguments:
|
||||
payload = await self.help_command.create_bot_help(context, commands)
|
||||
payload = await help_command.create_bot_help(context, commands)
|
||||
else:
|
||||
command_name = arguments[0]
|
||||
|
||||
@@ -178,14 +183,14 @@ async def help_command_impl(self: ClientT, context: Context[ClientT], *arguments
|
||||
except KeyError:
|
||||
cog = self.cogs.get(command_name)
|
||||
if cog:
|
||||
payload = await self.help_command.create_cog_help(context, cog)
|
||||
payload = await help_command.create_cog_help(context, cog)
|
||||
else:
|
||||
return await self.help_command.handle_no_command_found(context, command_name)
|
||||
return await help_command.handle_no_command_found(context, command_name)
|
||||
else:
|
||||
if isinstance(command, Group):
|
||||
payload = await self.help_command.create_group_help(context, command)
|
||||
payload = await help_command.create_group_help(context, command)
|
||||
else:
|
||||
payload = await self.help_command.create_command_help(context, command)
|
||||
payload = await help_command.create_command_help(context, command)
|
||||
|
||||
msg_payload: MessagePayload
|
||||
|
||||
@@ -196,4 +201,4 @@ async def help_command_impl(self: ClientT, context: Context[ClientT], *arguments
|
||||
else:
|
||||
msg_payload = payload
|
||||
|
||||
await self.help_command.send_help_command(context, msg_payload)
|
||||
await help_command.send_help_command(context, msg_payload)
|
||||
|
||||
+1
-2
@@ -38,9 +38,8 @@ class Member(User):
|
||||
user = state.get_user(data["_id"]["user"])
|
||||
|
||||
# due to not having a user payload and only a user object we have to manually add all the attributes instead of calling User.__init__
|
||||
self._members = []
|
||||
flattern_user(self, user)
|
||||
user._members.append(self)
|
||||
user._members.add(self)
|
||||
|
||||
self.state = state
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ from .http import *
|
||||
from .invite import *
|
||||
from .member import *
|
||||
from .message import *
|
||||
from .permissions import Overwrite as Overwrite
|
||||
from .permissions import *
|
||||
from .role import *
|
||||
from .server import *
|
||||
from .user import *
|
||||
|
||||
@@ -8,7 +8,7 @@ if TYPE_CHECKING:
|
||||
from .file import File
|
||||
|
||||
|
||||
__all__ = ("Member",)
|
||||
__all__ = ("Member", "MemberID")
|
||||
|
||||
class MemberID(TypedDict):
|
||||
server: str
|
||||
|
||||
+5
-3
@@ -1,6 +1,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING, NamedTuple, Optional, Union
|
||||
from weakref import WeakSet
|
||||
|
||||
from .asset import Asset, PartialAsset
|
||||
from .channel import DMChannel
|
||||
@@ -65,7 +66,7 @@ class User(Messageable, Ulid):
|
||||
|
||||
def __init__(self, data: UserPayload, state: State):
|
||||
self.state = state
|
||||
self._members: list[Member] = [] # we store all member versions of this user to avoid having to check every guild when needing to update.
|
||||
self._members: WeakSet[Member] = WeakSet() # we store all member versions of this user to avoid having to check every guild when needing to update.
|
||||
self.id = data["_id"]
|
||||
self.original_name = data["username"]
|
||||
self.dm_channel = None
|
||||
@@ -160,8 +161,9 @@ class User(Messageable, Ulid):
|
||||
|
||||
# update user infomation for all members
|
||||
|
||||
for member in self._members:
|
||||
User._update(member, status=status, profile=profile, avatar=avatar, online=online)
|
||||
if self.__class__ is User:
|
||||
for member in self._members:
|
||||
User._update(member, status=status, profile=profile, avatar=avatar, online=online)
|
||||
|
||||
async def default_avatar(self) -> bytes:
|
||||
"""Returns the default avatar for this user
|
||||
|
||||
+4
-1
@@ -2,7 +2,7 @@ import inspect
|
||||
import datetime
|
||||
from contextlib import asynccontextmanager
|
||||
from operator import attrgetter
|
||||
from typing import Any, Callable, Coroutine, Iterable, TypeVar, Union
|
||||
from typing import Any, Callable, Coroutine, Iterable, Literal, TypeVar, Union
|
||||
import ulid
|
||||
|
||||
from aiohttp import ClientSession
|
||||
@@ -14,6 +14,9 @@ class _Missing:
|
||||
def __repr__(self):
|
||||
return "<Missing>"
|
||||
|
||||
def __bool__(self) -> Literal[False]:
|
||||
return False
|
||||
|
||||
Missing = _Missing()
|
||||
|
||||
T = TypeVar("T")
|
||||
|
||||
+13
-13
@@ -1,17 +1,16 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import time
|
||||
import logging
|
||||
from copy import copy
|
||||
from traceback import print_exception
|
||||
from typing import TYPE_CHECKING, Callable, cast
|
||||
|
||||
from .channel import GroupDMChannel, TextChannel, VoiceChannel
|
||||
from .enums import RelationshipType
|
||||
from .types import (ChannelCreateEventPayload, ChannelDeleteEventPayload,
|
||||
ChannelDeleteTypingEventPayload,
|
||||
ChannelStartTypingEventPayload, ChannelUpdateEventPayload)
|
||||
from .types import Member as MemberPayload
|
||||
from .types import Message as MessagePayload
|
||||
from .types import MemberID as MemberIDPayload
|
||||
from .types import (MessageDeleteEventPayload, MessageUpdateEventPayload,
|
||||
ServerDeleteEventPayload, ServerMemberJoinEventPayload,
|
||||
ServerMemberLeaveEventPayload,
|
||||
@@ -19,7 +18,9 @@ from .types import (MessageDeleteEventPayload, MessageUpdateEventPayload,
|
||||
ServerMemberUpdateEventPayload,
|
||||
ServerRoleDeleteEventPayload, ServerRoleUpdateEventPayload,
|
||||
ServerUpdateEventPayload, UserRelationshipEventPayload,
|
||||
UserUpdateEventPayload, MessageReactEventPayload, MessageUnreactEventPayload, MessageRemoveReactionEventPayload)
|
||||
UserUpdateEventPayload, MessageReactEventPayload, MessageUnreactEventPayload, MessageRemoveReactionEventPayload, ChannelCreateEventPayload, ChannelDeleteEventPayload,
|
||||
ChannelDeleteTypingEventPayload,
|
||||
ChannelStartTypingEventPayload, ChannelUpdateEventPayload)
|
||||
from .user import Status, UserProfile
|
||||
from . import utils
|
||||
|
||||
@@ -290,7 +291,7 @@ class WebsocketHandler:
|
||||
self.dispatch("member_update", old_member, member)
|
||||
|
||||
async def handle_servermemberjoin(self, payload: ServerMemberJoinEventPayload):
|
||||
member = self.state.add_member(payload["id"], {"_id": {"server": payload["id"], "user": payload["user"]}})
|
||||
member = self.state.add_member(payload["id"], MemberPayload(_id=MemberIDPayload(server=payload["id"], user=payload["user"]), joined_at=int(time.time()))) # revolt doesnt give us the joined at time
|
||||
|
||||
user = await self.state.http.fetch_user(member.id)
|
||||
self.state.add_user(user)
|
||||
@@ -423,13 +424,12 @@ class WebsocketHandler:
|
||||
|
||||
async for msg in self.websocket:
|
||||
if use_msgpack:
|
||||
payload = msgpack.unpackb(msg.data)
|
||||
data: bytes = cast(bytes, msg.data)
|
||||
|
||||
payload = msgpack.unpackb(data)
|
||||
else:
|
||||
payload = json.loads(msg.data)
|
||||
data = cast(str, msg.data)
|
||||
|
||||
payload = json.loads(data)
|
||||
|
||||
self.loop.create_task(self.handle_event(payload))
|
||||
# task.add_done_callback(task_done)
|
||||
|
||||
def task_done(task: asyncio.Task[None]):
|
||||
if exception := task.exception():
|
||||
print_exception(type(exception), exception, exception.__traceback__)
|
||||
|
||||
Reference in New Issue
Block a user