satori-python 0.9.2__tar.gz → 0.11.0__tar.gz
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.
- {satori_python-0.9.2 → satori_python-0.11.0}/PKG-INFO +7 -7
- {satori_python-0.9.2 → satori_python-0.11.0}/pyproject.toml +25 -17
- {satori_python-0.9.2 → satori_python-0.11.0}/src/satori/__init__.py +2 -1
- satori_python-0.11.0/src/satori/client/__init__.py +218 -0
- {satori_python-0.9.2 → satori_python-0.11.0}/src/satori/client/account.py +7 -4
- {satori_python-0.9.2 → satori_python-0.11.0}/src/satori/client/account.pyi +11 -4
- {satori_python-0.9.2 → satori_python-0.11.0}/src/satori/client/network/base.py +2 -4
- {satori_python-0.9.2 → satori_python-0.11.0}/src/satori/client/network/websocket.py +5 -3
- {satori_python-0.9.2 → satori_python-0.11.0}/src/satori/const.py +2 -0
- {satori_python-0.9.2 → satori_python-0.11.0}/src/satori/element.py +187 -172
- satori_python-0.11.0/src/satori/event.py +63 -0
- {satori_python-0.9.2 → satori_python-0.11.0}/src/satori/model.py +75 -23
- satori_python-0.11.0/src/satori/parser.py +406 -0
- {satori_python-0.9.2 → satori_python-0.11.0}/src/satori/server/__init__.py +175 -5
- {satori_python-0.9.2 → satori_python-0.11.0}/src/satori/server/adapter.py +7 -16
- satori_python-0.11.0/src/satori/server/model.py +36 -0
- satori_python-0.11.0/src/satori/server/route.py +240 -0
- satori_python-0.9.2/src/satori/client/__init__.py +0 -108
- satori_python-0.9.2/src/satori/parser.py +0 -124
- satori_python-0.9.2/src/satori/server/model.py +0 -40
- {satori_python-0.9.2 → satori_python-0.11.0}/LICENSE +0 -0
- {satori_python-0.9.2 → satori_python-0.11.0}/README.md +0 -0
- {satori_python-0.9.2 → satori_python-0.11.0}/src/satori/client/network/__init__.py +0 -0
- {satori_python-0.9.2 → satori_python-0.11.0}/src/satori/client/network/webhook.py +0 -0
- {satori_python-0.9.2 → satori_python-0.11.0}/src/satori/client/session.py +0 -0
- {satori_python-0.9.2 → satori_python-0.11.0}/src/satori/config.py +0 -0
- {satori_python-0.9.2 → satori_python-0.11.0}/src/satori/exception.py +0 -0
- {satori_python-0.9.2 → satori_python-0.11.0}/src/satori/server/conection.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: satori-python
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.11.0
|
|
4
4
|
Summary: Satori Protocol SDK for python
|
|
5
5
|
Home-page: https://github.com/RF-Tar-Railt/satori-python
|
|
6
6
|
Author-Email: RF-Tar-Railt <rf_tar_railt@qq.com>
|
|
@@ -17,14 +17,14 @@ Classifier: Operating System :: OS Independent
|
|
|
17
17
|
Project-URL: Homepage, https://github.com/RF-Tar-Railt/satori-python
|
|
18
18
|
Project-URL: Repository, https://github.com/RF-Tar-Railt/satori-python
|
|
19
19
|
Requires-Python: >=3.9
|
|
20
|
-
Requires-Dist: aiohttp>=3.
|
|
20
|
+
Requires-Dist: aiohttp>=3.9.3
|
|
21
21
|
Requires-Dist: loguru>=0.7.2
|
|
22
22
|
Requires-Dist: launart>=0.8.2
|
|
23
|
-
Requires-Dist: typing-extensions>=4.
|
|
24
|
-
Requires-Dist: graia-amnesia>=0.
|
|
25
|
-
Requires-Dist: starlette>=0.
|
|
26
|
-
Requires-Dist: uvicorn[standard]>=0.
|
|
27
|
-
Requires-Dist: yarl>=1.9.
|
|
23
|
+
Requires-Dist: typing-extensions>=4.10.0
|
|
24
|
+
Requires-Dist: graia-amnesia>=0.9.0
|
|
25
|
+
Requires-Dist: starlette>=0.37.2
|
|
26
|
+
Requires-Dist: uvicorn[standard]>=0.28.0
|
|
27
|
+
Requires-Dist: yarl>=1.9.4
|
|
28
28
|
Description-Content-Type: text/markdown
|
|
29
29
|
|
|
30
30
|
# satori-python
|
|
@@ -6,14 +6,14 @@ authors = [
|
|
|
6
6
|
]
|
|
7
7
|
dynamic = []
|
|
8
8
|
dependencies = [
|
|
9
|
-
"aiohttp>=3.
|
|
9
|
+
"aiohttp>=3.9.3",
|
|
10
10
|
"loguru>=0.7.2",
|
|
11
11
|
"launart>=0.8.2",
|
|
12
|
-
"typing-extensions>=4.
|
|
13
|
-
"graia-amnesia>=0.
|
|
14
|
-
"starlette>=0.
|
|
15
|
-
"uvicorn[standard]>=0.
|
|
16
|
-
"yarl>=1.9.
|
|
12
|
+
"typing-extensions>=4.10.0",
|
|
13
|
+
"graia-amnesia>=0.9.0",
|
|
14
|
+
"starlette>=0.37.2",
|
|
15
|
+
"uvicorn[standard]>=0.28.0",
|
|
16
|
+
"yarl>=1.9.4",
|
|
17
17
|
]
|
|
18
18
|
requires-python = ">=3.9"
|
|
19
19
|
readme = "README.md"
|
|
@@ -28,7 +28,7 @@ classifiers = [
|
|
|
28
28
|
"Programming Language :: Python :: 3.12",
|
|
29
29
|
"Operating System :: OS Independent",
|
|
30
30
|
]
|
|
31
|
-
version = "0.
|
|
31
|
+
version = "0.11.0"
|
|
32
32
|
|
|
33
33
|
[project.license]
|
|
34
34
|
text = "MIT"
|
|
@@ -39,19 +39,19 @@ repository = "https://github.com/RF-Tar-Railt/satori-python"
|
|
|
39
39
|
|
|
40
40
|
[build-system]
|
|
41
41
|
requires = [
|
|
42
|
-
"mina-build
|
|
42
|
+
"mina-build<0.6,>=0.5.1",
|
|
43
43
|
]
|
|
44
44
|
build-backend = "mina.backend"
|
|
45
45
|
|
|
46
46
|
[tool.pdm.dev-dependencies]
|
|
47
47
|
dev = [
|
|
48
|
-
"isort>=5.
|
|
49
|
-
"black>=
|
|
50
|
-
"ruff>=0.
|
|
51
|
-
"pre-commit>=3.
|
|
48
|
+
"isort>=5.13.2",
|
|
49
|
+
"black>=24.2.0",
|
|
50
|
+
"ruff>=0.3.2",
|
|
51
|
+
"pre-commit>=3.6.2",
|
|
52
52
|
"fix-future-annotations>=0.5.0",
|
|
53
|
-
"mina-build
|
|
54
|
-
"pdm-mina>=0.3.
|
|
53
|
+
"mina-build<0.6,>=0.5.1",
|
|
54
|
+
"pdm-mina>=0.3.2",
|
|
55
55
|
]
|
|
56
56
|
|
|
57
57
|
[tool.pdm.build]
|
|
@@ -63,7 +63,7 @@ includes = [
|
|
|
63
63
|
composite = [
|
|
64
64
|
"isort ./src/ ./example/",
|
|
65
65
|
"black ./src/ ./example/",
|
|
66
|
-
"ruff ./src/ ./example/",
|
|
66
|
+
"ruff check ./src/ ./example/",
|
|
67
67
|
]
|
|
68
68
|
|
|
69
69
|
[tool.pdm.version]
|
|
@@ -84,6 +84,13 @@ extra_standard_library = [
|
|
|
84
84
|
]
|
|
85
85
|
|
|
86
86
|
[tool.ruff]
|
|
87
|
+
line-length = 110
|
|
88
|
+
target-version = "py38"
|
|
89
|
+
exclude = [
|
|
90
|
+
"exam.py",
|
|
91
|
+
]
|
|
92
|
+
|
|
93
|
+
[tool.ruff.lint]
|
|
87
94
|
select = [
|
|
88
95
|
"E",
|
|
89
96
|
"W",
|
|
@@ -100,9 +107,10 @@ ignore = [
|
|
|
100
107
|
"C901",
|
|
101
108
|
"UP037",
|
|
102
109
|
]
|
|
103
|
-
line-length = 110
|
|
104
|
-
target-version = "py38"
|
|
105
110
|
|
|
106
111
|
[tool.pyright]
|
|
107
112
|
pythonPlatform = "All"
|
|
108
113
|
pythonVersion = "3.8"
|
|
114
|
+
typeCheckingMode = "basic"
|
|
115
|
+
reportShadowedImports = false
|
|
116
|
+
disableBytesTypePromotions = true
|
|
@@ -15,6 +15,7 @@ from .element import Image as Image
|
|
|
15
15
|
from .element import Italic as Italic
|
|
16
16
|
from .element import Link as Link
|
|
17
17
|
from .element import Message as Message
|
|
18
|
+
from .element import Paragraph as Paragraph
|
|
18
19
|
from .element import Quote as Quote
|
|
19
20
|
from .element import Sharp as Sharp
|
|
20
21
|
from .element import Spoiler as Spoiler
|
|
@@ -38,4 +39,4 @@ from .model import MessageObject as MessageObject
|
|
|
38
39
|
from .model import Role as Role
|
|
39
40
|
from .model import User as User
|
|
40
41
|
|
|
41
|
-
__version__ = "0.
|
|
42
|
+
__version__ = "0.11.0"
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import asyncio
|
|
4
|
+
import signal
|
|
5
|
+
from functools import wraps
|
|
6
|
+
from typing import Any, Awaitable, Callable, Iterable, Literal, TypeVar, overload
|
|
7
|
+
|
|
8
|
+
from creart import it
|
|
9
|
+
from launart import Launart, Service, any_completed
|
|
10
|
+
from loguru import logger
|
|
11
|
+
|
|
12
|
+
from satori import event
|
|
13
|
+
from satori.config import Config, WebhookInfo, WebsocketsInfo
|
|
14
|
+
from satori.const import EventType
|
|
15
|
+
from satori.model import Event, LoginStatus
|
|
16
|
+
|
|
17
|
+
from .account import Account as Account
|
|
18
|
+
from .account import ApiInfo as ApiInfo
|
|
19
|
+
from .network.base import BaseNetwork as BaseNetwork
|
|
20
|
+
from .network.webhook import WebhookNetwork
|
|
21
|
+
from .network.websocket import WsNetwork
|
|
22
|
+
|
|
23
|
+
TConfig = TypeVar("TConfig", bound=Config)
|
|
24
|
+
TE = TypeVar("TE", bound=Event, contravariant=True)
|
|
25
|
+
|
|
26
|
+
MAPPING: dict[type[Config], type[BaseNetwork]] = {
|
|
27
|
+
WebhookInfo: WebhookNetwork,
|
|
28
|
+
WebsocketsInfo: WsNetwork,
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class App(Service):
|
|
33
|
+
id = "satori-python.client"
|
|
34
|
+
required: set[str] = set()
|
|
35
|
+
stages: set[str] = {"preparing", "blocking", "cleanup"}
|
|
36
|
+
|
|
37
|
+
accounts: dict[str, Account]
|
|
38
|
+
connections: list[BaseNetwork]
|
|
39
|
+
event_callbacks: list[Callable[[Account, Event], Awaitable[Any]]]
|
|
40
|
+
lifecycle_callbacks: list[Callable[[Account, LoginStatus], Awaitable[Any]]]
|
|
41
|
+
|
|
42
|
+
@classmethod
|
|
43
|
+
def register_config(cls, tc: type[TConfig], tn: type[BaseNetwork[TConfig]]):
|
|
44
|
+
MAPPING[tc] = tn
|
|
45
|
+
|
|
46
|
+
def __init__(self, *configs: Config):
|
|
47
|
+
self.accounts = {}
|
|
48
|
+
self.connections = []
|
|
49
|
+
self.event_callbacks = []
|
|
50
|
+
self.lifecycle_callbacks = []
|
|
51
|
+
super().__init__()
|
|
52
|
+
for config in configs:
|
|
53
|
+
self.apply(config)
|
|
54
|
+
|
|
55
|
+
def apply(self, config: Config):
|
|
56
|
+
try:
|
|
57
|
+
connection = MAPPING[config.__class__](self, config)
|
|
58
|
+
except KeyError:
|
|
59
|
+
raise TypeError(f"Unknown config type: {config}")
|
|
60
|
+
self.connections.append(connection)
|
|
61
|
+
|
|
62
|
+
def get_account(self, self_id: str) -> Account:
|
|
63
|
+
return self.accounts[self_id]
|
|
64
|
+
|
|
65
|
+
def register(self, callback: Callable[[Account, Event], Awaitable[Any]]):
|
|
66
|
+
self.event_callbacks.append(callback)
|
|
67
|
+
|
|
68
|
+
@overload
|
|
69
|
+
def register_on(self, event_type: Literal[EventType.FRIEND_REQUEST]) -> Callable[
|
|
70
|
+
[Callable[[Account, event.UserEvent], Awaitable[Any]]],
|
|
71
|
+
Callable[[Account, event.UserEvent], Awaitable[Any]],
|
|
72
|
+
]: ...
|
|
73
|
+
|
|
74
|
+
@overload
|
|
75
|
+
def register_on(
|
|
76
|
+
self,
|
|
77
|
+
event_type: Literal[
|
|
78
|
+
EventType.GUILD_ADDED, EventType.GUILD_REMOVED, EventType.GUILD_REQUEST, EventType.GUILD_UPDATED
|
|
79
|
+
],
|
|
80
|
+
) -> Callable[
|
|
81
|
+
[Callable[[Account, event.GuildEvent], Awaitable[Any]]],
|
|
82
|
+
Callable[[Account, event.GuildEvent], Awaitable[Any]],
|
|
83
|
+
]: ...
|
|
84
|
+
|
|
85
|
+
@overload
|
|
86
|
+
def register_on(
|
|
87
|
+
self,
|
|
88
|
+
event_type: Literal[
|
|
89
|
+
EventType.GUILD_MEMBER_ADDED,
|
|
90
|
+
EventType.GUILD_MEMBER_REMOVED,
|
|
91
|
+
EventType.GUILD_MEMBER_UPDATED,
|
|
92
|
+
EventType.GUILD_MEMBER_REQUEST,
|
|
93
|
+
],
|
|
94
|
+
) -> Callable[
|
|
95
|
+
[Callable[[Account, event.GuildMemberEvent], Awaitable[Any]]],
|
|
96
|
+
Callable[[Account, event.GuildMemberEvent], Awaitable[Any]],
|
|
97
|
+
]: ...
|
|
98
|
+
|
|
99
|
+
@overload
|
|
100
|
+
def register_on(
|
|
101
|
+
self,
|
|
102
|
+
event_type: Literal[
|
|
103
|
+
EventType.GUILD_ROLE_CREATED, EventType.GUILD_ROLE_DELETED, EventType.GUILD_ROLE_UPDATED
|
|
104
|
+
],
|
|
105
|
+
) -> Callable[
|
|
106
|
+
[Callable[[Account, event.GuildRoleEvent], Awaitable[Any]]],
|
|
107
|
+
Callable[[Account, event.GuildRoleEvent], Awaitable[Any]],
|
|
108
|
+
]: ...
|
|
109
|
+
|
|
110
|
+
@overload
|
|
111
|
+
def register_on(
|
|
112
|
+
self, event_type: Literal[EventType.LOGIN_ADDED, EventType.LOGIN_REMOVED, EventType.LOGIN_UPDATED]
|
|
113
|
+
) -> Callable[
|
|
114
|
+
[Callable[[Account, event.LoginEvent], Awaitable[Any]]],
|
|
115
|
+
Callable[[Account, event.LoginEvent], Awaitable[Any]],
|
|
116
|
+
]: ...
|
|
117
|
+
|
|
118
|
+
@overload
|
|
119
|
+
def register_on(
|
|
120
|
+
self,
|
|
121
|
+
event_type: Literal[EventType.MESSAGE_CREATED, EventType.MESSAGE_DELETED, EventType.MESSAGE_UPDATED],
|
|
122
|
+
) -> Callable[
|
|
123
|
+
[Callable[[Account, event.MessageEvent], Awaitable[Any]]],
|
|
124
|
+
Callable[[Account, event.MessageEvent], Awaitable[Any]],
|
|
125
|
+
]: ...
|
|
126
|
+
|
|
127
|
+
@overload
|
|
128
|
+
def register_on(
|
|
129
|
+
self, event_type: Literal[EventType.REACTION_ADDED, EventType.REACTION_REMOVED]
|
|
130
|
+
) -> Callable[
|
|
131
|
+
[Callable[[Account, event.ReactionEvent], Awaitable[Any]]],
|
|
132
|
+
Callable[[Account, event.ReactionEvent], Awaitable[Any]],
|
|
133
|
+
]: ...
|
|
134
|
+
|
|
135
|
+
@overload
|
|
136
|
+
def register_on(self, event_type: Literal[EventType.INTERACTION_BUTTON]) -> Callable[
|
|
137
|
+
[Callable[[Account, event.ButtonInteractionEvent], Awaitable[Any]]],
|
|
138
|
+
Callable[[Account, event.ButtonInteractionEvent], Awaitable[Any]],
|
|
139
|
+
]: ...
|
|
140
|
+
|
|
141
|
+
@overload
|
|
142
|
+
def register_on(self, event_type: Literal[EventType.INTERACTION_COMMAND]) -> Callable[
|
|
143
|
+
[Callable[[Account, event.ArgvInteractionEvent | event.MessageEvent], Awaitable[Any]]],
|
|
144
|
+
Callable[[Account, event.ArgvInteractionEvent | event.MessageEvent], Awaitable[Any]],
|
|
145
|
+
]: ...
|
|
146
|
+
|
|
147
|
+
@overload
|
|
148
|
+
def register_on(self, event_type: Literal[EventType.INTERNAL]) -> Callable[
|
|
149
|
+
[Callable[[Account, event.InternalEvent], Awaitable[Any]]],
|
|
150
|
+
Callable[[Account, event.InternalEvent], Awaitable[Any]],
|
|
151
|
+
]: ...
|
|
152
|
+
|
|
153
|
+
def register_on(self, event_type: EventType):
|
|
154
|
+
def decorator(
|
|
155
|
+
func: Callable[[Account, Any], Awaitable[Any]], /
|
|
156
|
+
) -> Callable[[Account, Any], Awaitable[Any]]:
|
|
157
|
+
@wraps(func)
|
|
158
|
+
async def wrapper(account: Account, event: Event) -> Any:
|
|
159
|
+
if event.type == event_type.value:
|
|
160
|
+
return await func(account, event)
|
|
161
|
+
|
|
162
|
+
self.register(wrapper)
|
|
163
|
+
return wrapper
|
|
164
|
+
|
|
165
|
+
return decorator
|
|
166
|
+
|
|
167
|
+
def lifecycle(self, callback: Callable[[Account, LoginStatus], Awaitable[Any]]):
|
|
168
|
+
self.lifecycle_callbacks.append(callback)
|
|
169
|
+
|
|
170
|
+
async def account_update(self, account: Account, state: LoginStatus):
|
|
171
|
+
if self.lifecycle_callbacks:
|
|
172
|
+
await asyncio.gather(*(callback(account, state) for callback in self.lifecycle_callbacks))
|
|
173
|
+
|
|
174
|
+
async def post(self, event: Event):
|
|
175
|
+
if not self.event_callbacks:
|
|
176
|
+
return
|
|
177
|
+
identity = f"{event.platform}/{event.self_id}"
|
|
178
|
+
if identity not in self.accounts:
|
|
179
|
+
logger.warning(f"Received event for unknown account: {event}")
|
|
180
|
+
return
|
|
181
|
+
account = self.accounts[identity]
|
|
182
|
+
await asyncio.gather(*(callback(account, event) for callback in self.event_callbacks))
|
|
183
|
+
|
|
184
|
+
async def launch(self, manager: Launart):
|
|
185
|
+
for conn in self.connections:
|
|
186
|
+
manager.add_component(conn)
|
|
187
|
+
|
|
188
|
+
async with self.stage("preparing"):
|
|
189
|
+
...
|
|
190
|
+
|
|
191
|
+
async with self.stage("blocking"):
|
|
192
|
+
await any_completed(
|
|
193
|
+
manager.status.wait_for_sigexit(),
|
|
194
|
+
*(conn.status.wait_for("blocking-completed") for conn in self.connections),
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
async with self.stage("cleanup"):
|
|
198
|
+
for account in self.accounts.values():
|
|
199
|
+
await self.account_update(account, LoginStatus.OFFLINE)
|
|
200
|
+
self.accounts.clear()
|
|
201
|
+
|
|
202
|
+
def run(
|
|
203
|
+
self,
|
|
204
|
+
manager: Launart | None = None,
|
|
205
|
+
*,
|
|
206
|
+
loop: asyncio.AbstractEventLoop | None = None,
|
|
207
|
+
stop_signal: Iterable[signal.Signals] = (signal.SIGINT,),
|
|
208
|
+
):
|
|
209
|
+
if manager is None:
|
|
210
|
+
manager = it(Launart)
|
|
211
|
+
manager.add_component(self)
|
|
212
|
+
manager.launch_blocking(loop=loop, stop_signal=stop_signal)
|
|
213
|
+
|
|
214
|
+
async def run_async(self, manager: Launart | None = None):
|
|
215
|
+
if manager is None:
|
|
216
|
+
manager = it(Launart)
|
|
217
|
+
manager.add_component(self)
|
|
218
|
+
await manager.launch()
|
|
@@ -2,11 +2,14 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import asyncio
|
|
4
4
|
from dataclasses import dataclass
|
|
5
|
+
from typing import TypeVar
|
|
5
6
|
|
|
6
7
|
from yarl import URL
|
|
7
8
|
|
|
8
9
|
from .session import Session
|
|
9
10
|
|
|
11
|
+
TS = TypeVar("TS", bound="Session")
|
|
12
|
+
|
|
10
13
|
|
|
11
14
|
@dataclass
|
|
12
15
|
class ApiInfo:
|
|
@@ -25,15 +28,15 @@ class ApiInfo:
|
|
|
25
28
|
|
|
26
29
|
|
|
27
30
|
class Account:
|
|
28
|
-
def __init__(self, platform: str, self_id: str, config: ApiInfo):
|
|
31
|
+
def __init__(self, platform: str, self_id: str, config: ApiInfo, session_cls: type[Session] = Session):
|
|
29
32
|
self.platform = platform
|
|
30
33
|
self.self_id = self_id
|
|
31
34
|
self.config = config
|
|
32
|
-
self.session =
|
|
35
|
+
self.session = session_cls(self) # type: ignore
|
|
33
36
|
self.connected = asyncio.Event()
|
|
34
37
|
|
|
35
|
-
def custom(self, config: ApiInfo | None = None, **kwargs):
|
|
36
|
-
return Account(self.platform, self.self_id, config or ApiInfo(**kwargs)).session
|
|
38
|
+
def custom(self, config: ApiInfo | None = None, session_cls: type[TS] = Session, **kwargs) -> TS:
|
|
39
|
+
return Account(self.platform, self.self_id, config or ApiInfo(**kwargs), session_cls).session # type: ignore
|
|
37
40
|
|
|
38
41
|
@property
|
|
39
42
|
def identity(self):
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import asyncio
|
|
2
|
-
from typing import Any, Iterable, Protocol, overload
|
|
2
|
+
from typing import Any, Iterable, Protocol, TypeVar, overload
|
|
3
3
|
|
|
4
4
|
from yarl import URL
|
|
5
5
|
|
|
@@ -8,6 +8,8 @@ from satori.model import Channel, Event, Guild, Login, Member, MessageObject, Pa
|
|
|
8
8
|
|
|
9
9
|
from .session import Session
|
|
10
10
|
|
|
11
|
+
TS = TypeVar("TS", bound="Session")
|
|
12
|
+
|
|
11
13
|
class Api(Protocol):
|
|
12
14
|
token: str | None = None
|
|
13
15
|
|
|
@@ -26,13 +28,15 @@ class Account:
|
|
|
26
28
|
session: Session
|
|
27
29
|
connected: asyncio.Event
|
|
28
30
|
|
|
29
|
-
def __init__(self, platform: str, self_id: str, config: Api): ...
|
|
31
|
+
def __init__(self, platform: str, self_id: str, config: Api, session_cls: type[Session] = Session): ...
|
|
30
32
|
@property
|
|
31
33
|
def identity(self) -> str: ...
|
|
32
34
|
@overload
|
|
33
|
-
def custom(self, config: Api) ->
|
|
35
|
+
def custom(self, config: Api, session_cls: type[TS] = Session) -> TS: ...
|
|
34
36
|
@overload
|
|
35
|
-
def custom(
|
|
37
|
+
def custom(
|
|
38
|
+
self, *, session_cls: type[TS] = Session, host: str, port: int, token: str | None = None
|
|
39
|
+
) -> TS: ...
|
|
36
40
|
async def send(
|
|
37
41
|
self,
|
|
38
42
|
event: Event,
|
|
@@ -51,6 +55,7 @@ class Account:
|
|
|
51
55
|
message: 要发送的消息
|
|
52
56
|
"""
|
|
53
57
|
...
|
|
58
|
+
|
|
54
59
|
async def send_private_message(
|
|
55
60
|
self,
|
|
56
61
|
user_id: str,
|
|
@@ -63,6 +68,7 @@ class Account:
|
|
|
63
68
|
message: 要发送的消息
|
|
64
69
|
"""
|
|
65
70
|
...
|
|
71
|
+
|
|
66
72
|
async def update_message(
|
|
67
73
|
self,
|
|
68
74
|
channel_id: str,
|
|
@@ -77,6 +83,7 @@ class Account:
|
|
|
77
83
|
message: 要更新的消息
|
|
78
84
|
"""
|
|
79
85
|
...
|
|
86
|
+
|
|
80
87
|
async def message_create(
|
|
81
88
|
self,
|
|
82
89
|
*,
|
|
@@ -27,12 +27,10 @@ class BaseNetwork(Generic[TConfig], Service):
|
|
|
27
27
|
self.close_signal = asyncio.Event()
|
|
28
28
|
self.sequence = -1
|
|
29
29
|
|
|
30
|
-
async def wait_for_available(self):
|
|
31
|
-
...
|
|
30
|
+
async def wait_for_available(self): ...
|
|
32
31
|
|
|
33
32
|
@property
|
|
34
|
-
def alive(self) -> bool:
|
|
35
|
-
...
|
|
33
|
+
def alive(self) -> bool: ...
|
|
36
34
|
|
|
37
35
|
async def connection_closed(self):
|
|
38
36
|
self.close_signal.set()
|
|
@@ -101,9 +101,11 @@ class WsNetwork(BaseNetwork[WebsocketsInfo]):
|
|
|
101
101
|
else:
|
|
102
102
|
account = Account(platform, self_id, self.config)
|
|
103
103
|
logger.info(f"account registered: {account}")
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
104
|
+
(
|
|
105
|
+
account.connected.set()
|
|
106
|
+
if login["status"] == LoginStatus.ONLINE
|
|
107
|
+
else account.connected.clear()
|
|
108
|
+
)
|
|
107
109
|
self.app.accounts[identity] = account
|
|
108
110
|
self.accounts[identity] = account
|
|
109
111
|
await self.app.account_update(account, LoginStatus.ONLINE)
|
|
@@ -13,6 +13,7 @@ class Api(str, Enum):
|
|
|
13
13
|
CHANNEL_CREATE = "channel.create"
|
|
14
14
|
CHANNEL_UPDATE = "channel.update"
|
|
15
15
|
CHANNEL_DELETE = "channel.delete"
|
|
16
|
+
CHANNEL_MUTE = "channel.mute"
|
|
16
17
|
USER_CHANNEL_CREATE = "user.channel.create"
|
|
17
18
|
|
|
18
19
|
GUILD_GET = "guild.get"
|
|
@@ -22,6 +23,7 @@ class Api(str, Enum):
|
|
|
22
23
|
GUILD_MEMBER_LIST = "guild.member.list"
|
|
23
24
|
GUILD_MEMBER_GET = "guild.member.get"
|
|
24
25
|
GUILD_MEMBER_KICK = "guild.member.kick"
|
|
26
|
+
GUILD_MEMBER_MUTE = "guild.member.mute"
|
|
25
27
|
GUILD_MEMBER_APPROVE = "guild.member.approve"
|
|
26
28
|
GUILD_MEMBER_ROLE_SET = "guild.member.role.set"
|
|
27
29
|
GUILD_MEMBER_ROLE_UNSET = "guild.member.role.unset"
|