split up types into its own folder

This commit is contained in:
Zomatree
2021-08-29 17:04:24 +01:00
parent f2adeb343a
commit 48f00c080b
25 changed files with 314 additions and 225 deletions
+1 -1
View File
@@ -3,7 +3,7 @@ from __future__ import annotations
from typing import TYPE_CHECKING, Union
if TYPE_CHECKING:
from .payloads import File as FilePayload
from .types import File as FilePayload
from .state import State
from io import IOBase
class Asset:
+1 -1
View File
@@ -5,7 +5,7 @@ from .messageable import Messageable
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from .payloads import Channel as ChannelPayload
from .types import Channel as ChannelPayload
from .state import State
class Channel:
+1 -1
View File
@@ -15,7 +15,7 @@ except ImportError:
import json
if TYPE_CHECKING:
from .payloads import ApiInfo
from .types import ApiInfo
from .user import User
from .server import Server
from .channel import Channel
+1 -1
View File
@@ -3,7 +3,7 @@ from __future__ import annotations
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from .payloads import Embed as EmbedPayload
from .types import Embed as EmbedPayload
class Embed:
@classmethod
+1 -1
View File
@@ -14,7 +14,7 @@ except ImportError:
if TYPE_CHECKING:
import aiohttp
from .payloads import ApiInfo, Autumn as AutumnPayload, Message as MessagePayload, Embed as EmbedPayload
from .types import ApiInfo, Autumn as AutumnPayload, Message as MessagePayload, Embed as EmbedPayload, GetServerMembers
from .file import File
class HttpClient:
+1 -1
View File
@@ -4,7 +4,7 @@ from typing import TYPE_CHECKING
if TYPE_CHECKING:
from .state import State
from .payloads import Member as MemberPayload
from .types import Member as MemberPayload
from .server import Server
class Member:
+1 -1
View File
@@ -9,7 +9,7 @@ from .channel import TextChannel
if TYPE_CHECKING:
from .state import State
from .payloads import Message as MessagePayload
from .types import Message as MessagePayload
class Message:
def __init__(self, data: MessagePayload, state: State):
-204
View File
@@ -1,204 +0,0 @@
from typing import Literal, Type, TypedDict, Union
class ApiFeature(TypedDict):
enabled: bool
url: str
class VosoFeature(ApiFeature):
ws: str
class Features(TypedDict):
email: bool
invite_only: bool
captcha: ApiFeature
autumn: ApiFeature
january: ApiFeature
voso: VosoFeature
class ApiInfo(TypedDict):
revolt: str
features: Features
ws: str
app: str
vapid: str
class BasePayload(TypedDict):
type: str
class AuthenticatePayload(BasePayload):
token: str
class UserBot(TypedDict):
owner: str
class SizedMetadata(TypedDict):
type: Literal["Image", "Video"]
height: int
width: int
class SimpleMetadata(TypedDict):
type: Literal["File", "Text", "Audio"]
FileMetadata = Union[SizedMetadata, SimpleMetadata]
class File(TypedDict):
_id: str
tag: str
size: int
filename: str
metadata: FileMetadata
content_type: str
class Status(TypedDict, total=False):
text: str
presence: Literal["Busy", "Idle", "Invisible", "Online"]
class _OptionalUser(TypedDict, total=False):
avatar: File
relations: list
badges: int
status: Status
relationship: Literal["Blocked", "BlockedOther", "Friend", "Incoming", "None", "Outgoing", "User"]
online: bool
flags: int
bot: UserBot
class User(_OptionalUser):
_id: str
username: str
class Server(TypedDict):
_id: str
class UserAddContent(TypedDict):
id: str
by: str
class UserRemoveContent(TypedDict):
id: str
by: str
class UserJoinedContent(TypedDict):
id: str
by: str
class UserLeftContent(TypedDict):
id: str
class UserKickedContent(TypedDict):
id: str
class UserBanned(TypedDict):
id: str
class ChannelRenameContent(TypedDict):
name: str
by: str
class ChannelDescriptionChangeContent(TypedDict):
by: str
class ChannelIconChanged(TypedDict):
by: str
class Embed(TypedDict):
pass # TODO
class _OptionalMessage(TypedDict):
attachments: list[File]
embeds: list[Embed]
class Message(_OptionalMessage):
_id: str
channel: str
author: str
content: Union[str, UserAddContent, UserRemoveContent, UserJoinedContent, UserLeftContent, UserKickedContent, UserBanned, ChannelRenameContent, ChannelDescriptionChangeContent, ChannelIconChanged]
class _NonceChannel(TypedDict, total=False):
nonce: str
class BaseChannel(TypedDict):
_id: str
class SavedMessages(_NonceChannel, BaseChannel):
user: str
channel_type: Literal["SavedMessage"]
class DirectMessage(_NonceChannel, BaseChannel):
active: bool
recipients: list[str]
last_message: Message
channel_type: Literal["DirectMessage"]
class _GroupOptional(TypedDict):
icon: File
permissions: int
description: str
class Group(_NonceChannel, _GroupOptional, BaseChannel):
recipients: list[str]
name: str
owner: str
channel_type: Literal["Group"]
class _TextChannelOptional(TypedDict, total=False):
icon: File
default_permissions: int
role_permissions: int
class TextChannel(_NonceChannel, _TextChannelOptional, BaseChannel):
server: str
name: str
description: str
last_message: Message
channel_type: Literal["TextChannel"]
class _VoiceChannelOptional(TypedDict, total=False):
icon: File
default_permissions: int
role_permissions: int
class VoiceChannel(_NonceChannel, _TextChannelOptional, BaseChannel):
server: str
name: str
description: str
channel_type: Literal["VoiceChannel"]
Channel = Union[SavedMessages, DirectMessage, Group, TextChannel, VoiceChannel]
class _MemberOptional(TypedDict, total=False):
nickname: str
avatar: File
roles: list[str]
class Member(_MemberOptional):
_id: str
class ReadyMemberUser(TypedDict):
server: str
user: str
class ReadyMember(_MemberOptional):
_id: ReadyMemberUser
class ReadyEventPayload(BasePayload):
users: list[User]
servers: list[Server]
channels: list[Channel]
members: list[ReadyMember]
class MessageEventPayload(BasePayload, Message):
pass
class Autumn(TypedDict):
id: str
Permission = tuple[int, int]
class _RoleOptional(TypedDict, total=False):
colour: str
hoist: bool
rank: int
class Role(_RoleOptional):
name: str
permissions: Permission
+1 -1
View File
@@ -1,7 +1,7 @@
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from .payloads import Permission as PermissionTuple
from .types import Permission as PermissionTuple
class Permissions:
def __init__(self, permission_tuple: PermissionTuple):
+1 -1
View File
@@ -3,7 +3,7 @@ from typing import TYPE_CHECKING
if TYPE_CHECKING:
from .state import State
from .payloads import Role as RolePayload
from .types import Role as RolePayload
class Role:
def __init__(self, data: RolePayload, role_id: str, state: State):
+1 -1
View File
@@ -3,7 +3,7 @@ from __future__ import annotations
from typing import TYPE_CHECKING, Optional
if TYPE_CHECKING:
from .payloads import Server as ServerPayload
from .types import Server as ServerPayload
from .state import State
from .member import Member
from .role import Role
+1 -1
View File
@@ -11,7 +11,7 @@ from .member import Member
if TYPE_CHECKING:
from .http import HttpClient
from .payloads import ApiInfo, User as UserPayload, Channel as ChannelPayload, Server as ServerPayload, Message as MessagePayload, Member as MemberPayload
from .types import ApiInfo, User as UserPayload, Channel as ChannelPayload, Server as ServerPayload, Message as MessagePayload, Member as MemberPayload
class State:
def __init__(self, http: HttpClient, api_info: ApiInfo, max_messages: int):
+10
View File
@@ -0,0 +1,10 @@
from .channel import *
from .embed import *
from .file import *
from .gateway import *
from .http import *
from .member import *
from .message import *
from .role import *
from .server import *
from .user import *
+59
View File
@@ -0,0 +1,59 @@
from __future__ import annotations
from typing import TYPE_CHECKING, TypedDict, Literal, Union
if TYPE_CHECKING:
from .message import Message
from .file import File
class _NonceChannel(TypedDict, total=False):
nonce: str
class BaseChannel(TypedDict):
_id: str
class SavedMessages(_NonceChannel, BaseChannel):
user: str
channel_type: Literal["SavedMessage"]
class DirectMessage(_NonceChannel, BaseChannel):
active: bool
recipients: list[str]
last_message: Message
channel_type: Literal["DirectMessage"]
class _GroupOptional(TypedDict):
icon: File
permissions: int
description: str
class Group(_NonceChannel, _GroupOptional, BaseChannel):
recipients: list[str]
name: str
owner: str
channel_type: Literal["Group"]
class _TextChannelOptional(TypedDict, total=False):
icon: File
default_permissions: int
role_permissions: int
class TextChannel(_NonceChannel, _TextChannelOptional, BaseChannel):
server: str
name: str
description: str
last_message: Message
channel_type: Literal["TextChannel"]
class _VoiceChannelOptional(TypedDict, total=False):
icon: File
default_permissions: int
role_permissions: int
class VoiceChannel(_NonceChannel, _TextChannelOptional, BaseChannel):
server: str
name: str
description: str
channel_type: Literal["VoiceChannel"]
Channel = Union[SavedMessages, DirectMessage, Group, TextChannel, VoiceChannel]
+6
View File
@@ -0,0 +1,6 @@
from __future__ import annotations
from typing import TYPE_CHECKING, TypedDict
class Embed(TypedDict):
pass # TODO
+21
View File
@@ -0,0 +1,21 @@
from __future__ import annotations
from typing import TYPE_CHECKING, TypedDict, Literal, Union
class SizedMetadata(TypedDict):
type: Literal["Image", "Video"]
height: int
width: int
class SimpleMetadata(TypedDict):
type: Literal["File", "Text", "Audio"]
FileMetadata = Union[SizedMetadata, SimpleMetadata]
class File(TypedDict):
_id: str
tag: str
size: int
filename: str
metadata: FileMetadata
content_type: str
+26
View File
@@ -0,0 +1,26 @@
from __future__ import annotations
from typing import TYPE_CHECKING, TypedDict
from .message import Message
if TYPE_CHECKING:
from .user import User
from .server import Server
from .channel import Channel
from .member import Member
class BasePayload(TypedDict):
type: str
class AuthenticatePayload(BasePayload):
token: str
class ReadyEventPayload(BasePayload):
users: list[User]
servers: list[Server]
channels: list[Channel]
members: list[Member]
class MessageEventPayload(BasePayload, Message):
pass
+36
View File
@@ -0,0 +1,36 @@
from __future__ import annotations
from typing import TYPE_CHECKING, TypedDict
if TYPE_CHECKING:
from .user import User
from .member import Member
class ApiFeature(TypedDict):
enabled: bool
url: str
class VosoFeature(ApiFeature):
ws: str
class Features(TypedDict):
email: bool
invite_only: bool
captcha: ApiFeature
autumn: ApiFeature
january: ApiFeature
voso: VosoFeature
class ApiInfo(TypedDict):
revolt: str
features: Features
ws: str
app: str
vapid: str
class Autumn(TypedDict):
id: str
class GetServerMembers(TypedDict):
members: list[Member]
users: list[User]
+18
View File
@@ -0,0 +1,18 @@
from __future__ import annotations
from typing import TYPE_CHECKING, TypedDict
if TYPE_CHECKING:
from .file import File
class _MemberOptional(TypedDict, total=False):
nickname: str
avatar: File
roles: list[str]
class MemberID(TypedDict):
server: str
user: str
class Member(_MemberOptional):
_id: MemberID
+48
View File
@@ -0,0 +1,48 @@
from __future__ import annotations
from typing import TYPE_CHECKING, TypedDict, Union
if TYPE_CHECKING:
from .file import File
from .embed import Embed
class UserAddContent(TypedDict):
id: str
by: str
class UserRemoveContent(TypedDict):
id: str
by: str
class UserJoinedContent(TypedDict):
id: str
by: str
class UserLeftContent(TypedDict):
id: str
class UserKickedContent(TypedDict):
id: str
class UserBanned(TypedDict):
id: str
class ChannelRenameContent(TypedDict):
name: str
by: str
class ChannelDescriptionChangeContent(TypedDict):
by: str
class ChannelIconChanged(TypedDict):
by: str
class _OptionalMessage(TypedDict):
attachments: list[File]
embeds: list[Embed]
class Message(_OptionalMessage):
_id: str
channel: str
author: str
content: Union[str, UserAddContent, UserRemoveContent, UserJoinedContent, UserLeftContent, UserKickedContent, UserBanned, ChannelRenameContent, ChannelDescriptionChangeContent, ChannelIconChanged]
+14
View File
@@ -0,0 +1,14 @@
from __future__ import annotations
from typing import TypedDict
Permission = tuple[int, int]
class _RoleOptional(TypedDict, total=False):
colour: str
hoist: bool
rank: int
class Role(_RoleOptional):
name: str
permissions: Permission
+9
View File
@@ -0,0 +1,9 @@
from __future__ import annotations
from typing import TYPE_CHECKING, TypedDict
if TYPE_CHECKING:
pass
class Server(TypedDict):
_id: str
+27
View File
@@ -0,0 +1,27 @@
from __future__ import annotations
from typing import TYPE_CHECKING, TypedDict, Literal
if TYPE_CHECKING:
from .file import File
class UserBot(TypedDict):
owner: str
class Status(TypedDict, total=False):
text: str
presence: Literal["Busy", "Idle", "Invisible", "Online"]
class _OptionalUser(TypedDict, total=False):
avatar: File
relations: list
badges: int
status: Status
relationship: Literal["Blocked", "BlockedOther", "Friend", "Incoming", "None", "Outgoing", "User"]
online: bool
flags: int
bot: UserBot
class User(_OptionalUser):
_id: str
username: str
+1 -1
View File
@@ -4,7 +4,7 @@ from typing import TYPE_CHECKING
if TYPE_CHECKING:
from .state import State
from .payloads import User as UserPayload
from .types import User as UserPayload
class User:
def __init__(self, data: UserPayload, state: State):
+28 -9
View File
@@ -4,16 +4,22 @@ from typing import Callable, TYPE_CHECKING, cast
import logging
import asyncio
from .payloads import Message as MessagePayload
from .types import Message as MessagePayload
try:
import ujson as json
except ImportError:
import json
try:
import msgpack
use_msgpack = True
except ImportError:
use_msgpack = False
if TYPE_CHECKING:
import aiohttp
from .payloads import BasePayload, AuthenticatePayload, ReadyEventPayload, MessageEventPayload, Member as MemberPayload
from .types import BasePayload, AuthenticatePayload, ReadyEventPayload, MessageEventPayload, Member as MemberPayload
from .state import State
logger = logging.getLogger("revolt")
@@ -28,10 +34,14 @@ class WebsocketHandler:
self.websocket: aiohttp.ClientWebSocketResponse
async def send_payload(self, payload: BasePayload):
await self.websocket.send_str(json.dumps(payload))
if use_msgpack:
await self.websocket.send_bytes(msgpack.packb(payload)) # type: ignore
else:
await self.websocket.send_str(json.dumps(payload))
async def heartbeat(self):
while not self.websocket.closed:
logger.info("Sending hearbeat")
await self.send_payload({"type": "Ping"})
await asyncio.sleep(15)
@@ -45,7 +55,7 @@ class WebsocketHandler:
async def handle_event(self, payload: BasePayload):
event_type = payload["type"].lower()
logger.debug("Recieved event %s %s", event_type, payload)
try:
func = getattr(self, f"handle_{event_type}")
except:
@@ -68,9 +78,9 @@ class WebsocketHandler:
self.state.add_channel(channel)
for member in payload["members"]:
server_id = member["_id"]["server"]
member_payload: MemberPayload = member | {"_id": member["_id"]["user"]} # type: ignore
self.state.add_member(server_id, member_payload)
self.state.add_member(member["_id"]["server"], member)
await self.state.fetch_all_server_members()
self.dispatch("ready")
@@ -79,10 +89,19 @@ class WebsocketHandler:
self.dispatch("message", message)
async def start(self):
self.websocket = await self.session.ws_connect(self.ws_url)
if use_msgpack:
url = f"{self.ws_url}?format=msgpack"
else:
url = f"{self.ws_url}?format=json"
self.websocket = await self.session.ws_connect(url)
await self.send_authenticate()
asyncio.create_task(self.heartbeat())
async for msg in self.websocket:
await self.handle_event(json.loads(msg.data))
if use_msgpack:
payload = msgpack.unpackb(msg.data)
else:
payload = json.loads(msg.data)
await self.handle_event(payload)