satori-python-core 0.18.1__tar.gz → 1.3.2__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.
@@ -8,8 +8,6 @@ authors = [
8
8
  {name = "RF-Tar-Railt", email = "rf_tar_railt@qq.com"}
9
9
  ]
10
10
  dependencies = [
11
- "loguru",
12
- "yarl",
13
11
  "typing-extensions",
14
12
  ]
15
13
  description = "Satori Protocol SDK for python, specify common part"
@@ -18,13 +16,13 @@ readme = "README.md"
18
16
  requires-python = ">=3.10,<4.0"
19
17
  classifiers = [
20
18
  "Typing :: Typed",
21
- "Development Status :: 4 - Beta",
19
+ "Development Status :: 5 - Production/Stable",
22
20
  "License :: OSI Approved :: MIT License",
23
- "Programming Language :: Python :: 3.8",
24
- "Programming Language :: Python :: 3.9",
25
21
  "Programming Language :: Python :: 3.10",
26
22
  "Programming Language :: Python :: 3.11",
27
23
  "Programming Language :: Python :: 3.12",
24
+ "Programming Language :: Python :: 3.13",
25
+ "Programming Language :: Python :: 3.14",
28
26
  "Operating System :: OS Independent",
29
27
  ]
30
28
 
@@ -1,24 +1,22 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: satori-python-core
3
- Version: 0.18.1
3
+ Version: 1.3.2
4
4
  Summary: Satori Protocol SDK for python, specify common part
5
5
  Home-page: https://github.com/RF-Tar-Railt/satori-python
6
6
  Author-Email: RF-Tar-Railt <rf_tar_railt@qq.com>
7
7
  License: MIT
8
8
  Classifier: Typing :: Typed
9
- Classifier: Development Status :: 4 - Beta
9
+ Classifier: Development Status :: 5 - Production/Stable
10
10
  Classifier: License :: OSI Approved :: MIT License
11
- Classifier: Programming Language :: Python :: 3.8
12
- Classifier: Programming Language :: Python :: 3.9
13
11
  Classifier: Programming Language :: Python :: 3.10
14
12
  Classifier: Programming Language :: Python :: 3.11
15
13
  Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Programming Language :: Python :: 3.13
15
+ Classifier: Programming Language :: Python :: 3.14
16
16
  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: <4.0,>=3.10
20
- Requires-Dist: loguru>=0.7.2
21
- Requires-Dist: yarl>=1.9.4
22
20
  Requires-Dist: typing-extensions>=4.7.0
23
21
  Description-Content-Type: text/markdown
24
22
 
@@ -72,13 +70,13 @@ pip install satori-python-server
72
70
 
73
71
  ### 官方适配器
74
72
 
75
- | 适配器 | 安装 | 路径 |
76
- |------------|----------------------------------------------|--------------------------------------------------------------------|
77
- | Satori | `pip install satori-python-adapter-satori` | satori.adapters.satori |
78
- | OneBot V11 | `pip install satori-python-adapter-onebot11` | satori.adapters.onebot11.forward, satori.adapters.onebot11.reverse |
79
- | Console | `pip install satori-python-adapter-console` | satori.adapters.console |
80
- | Milky | `pip install satori-python-adapter-milky` | satori.adapters.milky.main, satori.adapters.milky.webhook |
81
- | QQ | `pip install satori-python-adapter-qq` | satori.adapters.qq.main, satori.adapters.qq.websocket |
73
+ | 适配器 | 安装 | 路径 |
74
+ |------------|----------------------------------------------|--------------------------------------------------------------------------------------|
75
+ | Satori | `pip install satori-python-adapter-satori` | satori.adapters.satori |
76
+ | OneBot V11 | `pip install satori-python-adapter-onebot11` | satori.adapters.onebot11.forward, satori.adapters.onebot11.reverse |
77
+ | Console | `pip install satori-python-adapter-console` | satori.adapters.console |
78
+ | Milky | `pip install satori-python-adapter-milky` | satori.adapters.milky.main, satori.adapters.milky.webhook, satori.adapters.milky.sse |
79
+ | QQ | `pip install satori-python-adapter-qq` | satori.adapters.qq.main, satori.adapters.qq.websocket |
82
80
 
83
81
  ### 社区适配器
84
82
 
@@ -48,13 +48,13 @@ pip install satori-python-server
48
48
 
49
49
  ### 官方适配器
50
50
 
51
- | 适配器 | 安装 | 路径 |
52
- |------------|----------------------------------------------|--------------------------------------------------------------------|
53
- | Satori | `pip install satori-python-adapter-satori` | satori.adapters.satori |
54
- | OneBot V11 | `pip install satori-python-adapter-onebot11` | satori.adapters.onebot11.forward, satori.adapters.onebot11.reverse |
55
- | Console | `pip install satori-python-adapter-console` | satori.adapters.console |
56
- | Milky | `pip install satori-python-adapter-milky` | satori.adapters.milky.main, satori.adapters.milky.webhook |
57
- | QQ | `pip install satori-python-adapter-qq` | satori.adapters.qq.main, satori.adapters.qq.websocket |
51
+ | 适配器 | 安装 | 路径 |
52
+ |------------|----------------------------------------------|--------------------------------------------------------------------------------------|
53
+ | Satori | `pip install satori-python-adapter-satori` | satori.adapters.satori |
54
+ | OneBot V11 | `pip install satori-python-adapter-onebot11` | satori.adapters.onebot11.forward, satori.adapters.onebot11.reverse |
55
+ | Console | `pip install satori-python-adapter-console` | satori.adapters.console |
56
+ | Milky | `pip install satori-python-adapter-milky` | satori.adapters.milky.main, satori.adapters.milky.webhook, satori.adapters.milky.sse |
57
+ | QQ | `pip install satori-python-adapter-qq` | satori.adapters.qq.main, satori.adapters.qq.websocket |
58
58
 
59
59
  ### 社区适配器
60
60
 
@@ -5,8 +5,6 @@ authors = [
5
5
  { name = "RF-Tar-Railt", email = "rf_tar_railt@qq.com" },
6
6
  ]
7
7
  dependencies = [
8
- "loguru>=0.7.2",
9
- "yarl>=1.9.4",
10
8
  "typing-extensions>=4.7.0",
11
9
  ]
12
10
  description = "Satori Protocol SDK for python, specify common part"
@@ -14,16 +12,16 @@ readme = "README.md"
14
12
  requires-python = ">=3.10,<4.0"
15
13
  classifiers = [
16
14
  "Typing :: Typed",
17
- "Development Status :: 4 - Beta",
15
+ "Development Status :: 5 - Production/Stable",
18
16
  "License :: OSI Approved :: MIT License",
19
- "Programming Language :: Python :: 3.8",
20
- "Programming Language :: Python :: 3.9",
21
17
  "Programming Language :: Python :: 3.10",
22
18
  "Programming Language :: Python :: 3.11",
23
19
  "Programming Language :: Python :: 3.12",
20
+ "Programming Language :: Python :: 3.13",
21
+ "Programming Language :: Python :: 3.14",
24
22
  "Operating System :: OS Independent",
25
23
  ]
26
- version = "0.18.1"
24
+ version = "1.3.2"
27
25
 
28
26
  [project.license]
29
27
  text = "MIT"
@@ -8,6 +8,7 @@ from .element import Button as Button
8
8
  from .element import Code as Code
9
9
  from .element import E as E
10
10
  from .element import Element as Element
11
+ from .element import Emoji as Emoji
11
12
  from .element import File as File
12
13
  from .element import Image as Image
13
14
  from .element import Italic as Italic
@@ -30,7 +31,9 @@ from .model import ArgvInteraction as ArgvInteraction
30
31
  from .model import ButtonInteraction as ButtonInteraction
31
32
  from .model import Channel as Channel
32
33
  from .model import ChannelType as ChannelType
34
+ from .model import EmojiObject as EmojiObject
33
35
  from .model import Event as Event
36
+ from .model import Friend as Friend
34
37
  from .model import Guild as Guild
35
38
  from .model import Login as Login
36
39
  from .model import LoginStatus as LoginStatus
@@ -42,7 +45,7 @@ from .model import Role as Role
42
45
  from .model import Upload as Upload
43
46
  from .model import User as User
44
47
 
45
- __version__ = "0.18.1"
48
+ __version__ = "1.3.2"
46
49
 
47
50
 
48
51
  MessageReceipt = MessageObject
@@ -40,10 +40,11 @@ class Api(str, Enum):
40
40
 
41
41
  LOGIN_GET = "login.get"
42
42
 
43
- USER_GET = "user.get"
44
43
  FRIEND_LIST = "friend.list"
44
+ FRIEND_DELETE = "friend.delete"
45
45
  FRIEND_APPROVE = "friend.approve"
46
46
 
47
+ USER_GET = "user.get"
47
48
  UPLOAD_CREATE = "upload.create"
48
49
 
49
50
 
@@ -65,6 +66,9 @@ class EventType(str, Enum):
65
66
  GUILD_ROLE_CREATED = "guild-role-created"
66
67
  GUILD_ROLE_DELETED = "guild-role-deleted"
67
68
  GUILD_ROLE_UPDATED = "guild-role-updated"
69
+ GUILD_EMOJI_ADDED = "guild-emoji-added"
70
+ GUILD_EMOJI_REMOVED = "guild-emoji-removed"
71
+ GUILD_EMOJI_UPDATED = "guild-emoji-updated"
68
72
  LOGIN_ADDED = "login-added"
69
73
  LOGIN_REMOVED = "login-removed"
70
74
  LOGIN_UPDATED = "login-updated"
@@ -5,7 +5,7 @@ from io import BytesIO
5
5
  from pathlib import Path
6
6
  from types import UnionType
7
7
  from typing import Any, ClassVar, Final, TypeVar, Union, final, get_args, get_origin, overload
8
- from typing_extensions import override
8
+ from typing_extensions import Self, override
9
9
 
10
10
  from ._vendor.fleep import get
11
11
  from .parser import Element as RawElement
@@ -157,6 +157,19 @@ class At(Element):
157
157
  return At(type="here" if here else "all")
158
158
 
159
159
 
160
+ @dataclass(repr=False)
161
+ class Emoji(Element):
162
+ """<emoji> 元素用于表示一个表情。"""
163
+
164
+ id: str
165
+ name: str | None = None
166
+
167
+ def to_model(self):
168
+ from .model import EmojiObject
169
+
170
+ return EmojiObject(self.id, self.name)
171
+
172
+
160
173
  @dataclass(repr=False)
161
174
  class Sharp(Element):
162
175
  """<sharp> 元素用于提及某个频道。"""
@@ -200,7 +213,7 @@ class Resource(Element):
200
213
 
201
214
  @classmethod
202
215
  def of(
203
- cls,
216
+ cls: type[Self],
204
217
  url: str | None = None,
205
218
  path: str | Path | None = None,
206
219
  raw: bytes | BytesIO | None = None,
@@ -212,7 +225,7 @@ class Resource(Element):
212
225
  cache: bool | None = None,
213
226
  timeout: int | None = None,
214
227
  **kwargs,
215
- ):
228
+ ) -> Self:
216
229
  data: dict[str, Any] = {"extra": extra, **kwargs}
217
230
  if url is not None:
218
231
  data |= {"src": url}
@@ -537,6 +550,7 @@ def register_element(cls: type[TE], tag: str | None = None) -> type[TE]:
537
550
  ELEMENT_TYPE_MAP = {
538
551
  "text": Text,
539
552
  "at": At,
553
+ "emoji": Emoji,
540
554
  "sharp": Sharp,
541
555
  "img": Image,
542
556
  "image": Image,
@@ -637,6 +651,7 @@ class _E:
637
651
  self.at = At
638
652
  self.at_role = At.role_
639
653
  self.at_all = At.all
654
+ self.emoji = Emoji
640
655
  self.sharp = Sharp
641
656
  self.link = Link
642
657
  self.image = Image.of
@@ -2,6 +2,7 @@ from satori.model import (
2
2
  ArgvInteraction,
3
3
  ButtonInteraction,
4
4
  Channel,
5
+ EmojiObject,
5
6
  Event,
6
7
  Guild,
7
8
  LoginPartial,
@@ -40,6 +41,10 @@ class GuildRoleEvent(GuildEvent):
40
41
  role: Role
41
42
 
42
43
 
44
+ class GuildEmojiEvent(GuildEvent):
45
+ emoji: EmojiObject
46
+
47
+
43
48
  class LoginEvent(Event):
44
49
  login: LoginPartial
45
50
 
@@ -48,6 +53,7 @@ class ReactionEvent(Event):
48
53
  channel: Channel
49
54
  user: User
50
55
  message: MessageObject
56
+ emoji: EmojiObject
51
57
 
52
58
 
53
59
  class ButtonInteractionEvent(Event):
@@ -8,7 +8,7 @@ from pathlib import Path
8
8
  from typing import IO, Any, ClassVar, Generic, Literal, TypeAlias, TypeVar
9
9
  from typing_extensions import Self
10
10
 
11
- from .element import Element, transform
11
+ from .element import Element, Emoji, transform
12
12
  from .parser import Element as RawElement
13
13
  from .parser import parse
14
14
 
@@ -98,13 +98,15 @@ class User(ModelBase):
98
98
 
99
99
 
100
100
  @dataclass
101
- class Member(ModelBase):
101
+ class Friend(ModelBase):
102
102
  user: User | None = None
103
103
  nick: str | None = None
104
- avatar: str | None = None
105
- joined_at: datetime | None = None
106
104
 
107
- __converter__ = {"user": User.parse, "joined_at": lambda ts: datetime.fromtimestamp(int(ts) / 1000)}
105
+ @property
106
+ def remark(self) -> str | None:
107
+ return self.nick
108
+
109
+ __converter__ = {"user": User.parse}
108
110
 
109
111
  def dump(self):
110
112
  res = {}
@@ -112,10 +114,6 @@ class Member(ModelBase):
112
114
  res["user"] = self.user.dump()
113
115
  if self.nick:
114
116
  res["nick"] = self.nick
115
- if self.avatar:
116
- res["avatar"] = self.avatar
117
- if self.joined_at:
118
- res["joined_at"] = int(self.joined_at.timestamp() * 1000)
119
117
  return res
120
118
 
121
119
 
@@ -124,6 +122,12 @@ class Role(ModelBase):
124
122
  id: str
125
123
  name: str | None = None
126
124
 
125
+ @classmethod
126
+ def parse(cls, raw: str | dict):
127
+ if isinstance(raw, str):
128
+ return cls(id=raw)
129
+ return super().parse(raw)
130
+
127
131
  def dump(self):
128
132
  res = {"id": self.id}
129
133
  if self.name:
@@ -131,6 +135,35 @@ class Role(ModelBase):
131
135
  return res
132
136
 
133
137
 
138
+ @dataclass
139
+ class Member(ModelBase):
140
+ user: User | None = None
141
+ nick: str | None = None
142
+ avatar: str | None = None
143
+ joined_at: datetime | None = None
144
+ roles: list[Role] = field(default_factory=list)
145
+
146
+ __converter__ = {
147
+ "user": User.parse,
148
+ "joined_at": lambda ts: datetime.fromtimestamp(int(ts) / 1000),
149
+ "roles": lambda raw: [Role.parse(role) for role in raw],
150
+ } # noqa: E501
151
+
152
+ def dump(self):
153
+ res = {}
154
+ if self.user:
155
+ res["user"] = self.user.dump()
156
+ if self.nick:
157
+ res["nick"] = self.nick
158
+ if self.avatar:
159
+ res["avatar"] = self.avatar
160
+ if self.joined_at:
161
+ res["joined_at"] = int(self.joined_at.timestamp() * 1000)
162
+ if self.roles:
163
+ res["roles"] = [role.dump() for role in self.roles]
164
+ return res
165
+
166
+
134
167
  class LoginStatus(IntEnum):
135
168
  OFFLINE = 0
136
169
  """离线"""
@@ -282,6 +315,21 @@ class Meta(ModelBase):
282
315
  return {"logins": [login.dump() for login in self.logins], "proxy_urls": self.proxy_urls}
283
316
 
284
317
 
318
+ @dataclass
319
+ class EmojiObject(ModelBase):
320
+ id: str
321
+ name: str | None = None
322
+
323
+ def dump(self):
324
+ res = {"id": self.id}
325
+ if self.name:
326
+ res["name"] = self.name
327
+ return res
328
+
329
+ def to_element(self) -> Emoji:
330
+ return Emoji(self.id, self.name)
331
+
332
+
285
333
  @dataclass
286
334
  class MessageObject(ModelBase):
287
335
  id: str
@@ -373,6 +421,7 @@ class Event(ModelBase):
373
421
  role: Role | None = None
374
422
  user: User | None = None
375
423
  referrer: dict | None = None
424
+ emoji: EmojiObject | None = None
376
425
 
377
426
  _type: str | None = None
378
427
  _data: dict | None = None
@@ -391,6 +440,7 @@ class Event(ModelBase):
391
440
  "operator": User.parse,
392
441
  "role": Role.parse,
393
442
  "user": User.parse,
443
+ "emoji": EmojiObject.parse,
394
444
  }
395
445
 
396
446
  @classmethod
@@ -447,6 +497,8 @@ class Event(ModelBase):
447
497
  res["user"] = self.user.dump()
448
498
  if self.referrer:
449
499
  res["referrer"] = self.referrer
500
+ if self.emoji:
501
+ res["emoji"] = self.emoji.dump()
450
502
  if self._type:
451
503
  res["_type"] = self._type
452
504
  if self._data: