satori-python-core 0.17.7__tar.gz → 0.18.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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: satori-python-core
3
- Version: 0.17.7
3
+ Version: 0.18.0
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>
@@ -29,17 +29,18 @@ Description-Content-Type: text/markdown
29
29
  [![PyPI](https://img.shields.io/pypi/v/satori-python)](https://pypi.org/project/satori-python)
30
30
  [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/satori-python)](https://www.python.org/)
31
31
 
32
- 基于 [Satori](https://satori.js.org/zh-CN/) 协议的 Python 开发工具包
32
+ 基于 [Satori](https://satori.chat/zh-CN/) 协议的 Python 开发工具包
33
33
 
34
34
  ## 协议介绍
35
35
 
36
- [Satori Protocol](https://satori.js.org/zh-CN/)
36
+ [Satori Protocol](https://satori.chat/zh-CN/)
37
37
 
38
38
  ### 协议端
39
39
 
40
40
  目前提供了 `satori` 协议实现的有:
41
41
 
42
42
  - [Chronocat](https://chronocat.vercel.app)
43
+ - [LLBot](https://www.llonebot.com/guide/introduction)
43
44
  - [nekobox](https://github.com/wyapx/nekobox)
44
45
  - Koishi (搭配 `@koishijs/plugin-server`)
45
46
 
@@ -77,6 +78,7 @@ pip install satori-python-server
77
78
  | OneBot V11 | `pip install satori-python-adapter-onebot11` | satori.adapters.onebot11.forward, satori.adapters.onebot11.reverse |
78
79
  | Console | `pip install satori-python-adapter-console` | satori.adapters.console |
79
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.milky.main, satori.adapters.milky.websocket |
80
82
 
81
83
  ### 社区适配器
82
84
 
@@ -5,17 +5,18 @@
5
5
  [![PyPI](https://img.shields.io/pypi/v/satori-python)](https://pypi.org/project/satori-python)
6
6
  [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/satori-python)](https://www.python.org/)
7
7
 
8
- 基于 [Satori](https://satori.js.org/zh-CN/) 协议的 Python 开发工具包
8
+ 基于 [Satori](https://satori.chat/zh-CN/) 协议的 Python 开发工具包
9
9
 
10
10
  ## 协议介绍
11
11
 
12
- [Satori Protocol](https://satori.js.org/zh-CN/)
12
+ [Satori Protocol](https://satori.chat/zh-CN/)
13
13
 
14
14
  ### 协议端
15
15
 
16
16
  目前提供了 `satori` 协议实现的有:
17
17
 
18
18
  - [Chronocat](https://chronocat.vercel.app)
19
+ - [LLBot](https://www.llonebot.com/guide/introduction)
19
20
  - [nekobox](https://github.com/wyapx/nekobox)
20
21
  - Koishi (搭配 `@koishijs/plugin-server`)
21
22
 
@@ -53,6 +54,7 @@ pip install satori-python-server
53
54
  | OneBot V11 | `pip install satori-python-adapter-onebot11` | satori.adapters.onebot11.forward, satori.adapters.onebot11.reverse |
54
55
  | Console | `pip install satori-python-adapter-console` | satori.adapters.console |
55
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.milky.main, satori.adapters.milky.websocket |
56
58
 
57
59
  ### 社区适配器
58
60
 
@@ -23,7 +23,7 @@ classifiers = [
23
23
  "Programming Language :: Python :: 3.12",
24
24
  "Operating System :: OS Independent",
25
25
  ]
26
- version = "0.17.7"
26
+ version = "0.18.0"
27
27
 
28
28
  [project.license]
29
29
  text = "MIT"
@@ -42,4 +42,7 @@ from .model import Role as Role
42
42
  from .model import Upload as Upload
43
43
  from .model import User as User
44
44
 
45
- __version__ = "0.17.7"
45
+ __version__ = "0.18.0"
46
+
47
+
48
+ MessageReceipt = MessageObject
@@ -48,18 +48,23 @@ class Api(str, Enum):
48
48
 
49
49
 
50
50
  class EventType(str, Enum):
51
+ FRIEND_ADDED = "friend-added"
52
+ FRIEND_REMOVED = "friend-removed"
51
53
  FRIEND_REQUEST = "friend-request"
52
54
  GUILD_ADDED = "guild-added"
55
+ GUILD_UPDATED = "guild-updated"
56
+ GUILD_REMOVED = "guild-removed"
57
+ GUILD_REQUEST = "guild-request"
58
+ CHANNEL_ADDED = "channel-added"
59
+ CHANNEL_UPDATED = "channel-updated"
60
+ CHANNEL_REMOVED = "channel-removed"
53
61
  GUILD_MEMBER_ADDED = "guild-member-added"
54
62
  GUILD_MEMBER_REMOVED = "guild-member-removed"
55
63
  GUILD_MEMBER_REQUEST = "guild-member-request"
56
64
  GUILD_MEMBER_UPDATED = "guild-member-updated"
57
- GUILD_REMOVED = "guild-removed"
58
- GUILD_REQUEST = "guild-request"
59
65
  GUILD_ROLE_CREATED = "guild-role-created"
60
66
  GUILD_ROLE_DELETED = "guild-role-deleted"
61
67
  GUILD_ROLE_UPDATED = "guild-role-updated"
62
- GUILD_UPDATED = "guild-updated"
63
68
  LOGIN_ADDED = "login-added"
64
69
  LOGIN_REMOVED = "login-removed"
65
70
  LOGIN_UPDATED = "login-updated"
@@ -213,7 +213,7 @@ class Resource(Element):
213
213
  timeout: int | None = None,
214
214
  **kwargs,
215
215
  ):
216
- data: dict[str, Any] = {"extra": extra or kwargs}
216
+ data: dict[str, Any] = {"extra": extra, **kwargs}
217
217
  if url is not None:
218
218
  data |= {"src": url}
219
219
  elif path:
@@ -27,6 +27,10 @@ class GuildEvent(Event):
27
27
  guild: Guild
28
28
 
29
29
 
30
+ class ChannelEvent(GuildEvent):
31
+ channel: Channel
32
+
33
+
30
34
  class GuildMemberEvent(GuildEvent):
31
35
  user: User
32
36
  member: Member
@@ -1,28 +1,35 @@
1
1
  class ActionFailed(Exception):
2
+ CODE = 400
2
3
  pass
3
4
 
4
5
 
5
6
  class BadRequestException(ActionFailed):
7
+ CODE = 400
6
8
  pass
7
9
 
8
10
 
9
11
  class UnauthorizedException(ActionFailed):
12
+ CODE = 401
10
13
  pass
11
14
 
12
15
 
13
16
  class ForbiddenException(ActionFailed):
17
+ CODE = 403
14
18
  pass
15
19
 
16
20
 
17
21
  class NotFoundException(ActionFailed):
22
+ CODE = 404
18
23
  pass
19
24
 
20
25
 
21
26
  class MethodNotAllowedException(ActionFailed):
27
+ CODE = 405
22
28
  pass
23
29
 
24
30
 
25
31
  class ServerException(ActionFailed):
32
+ CODE = 500
26
33
  pass
27
34
 
28
35
 
@@ -205,9 +205,13 @@ class ArgvInteraction(ModelBase):
205
205
  @dataclass
206
206
  class ButtonInteraction(ModelBase):
207
207
  id: str
208
+ data: str | None = None
208
209
 
209
210
  def dump(self):
210
- return {"id": self.id}
211
+ res = {"id": self.id}
212
+ if self.data:
213
+ res["data"] = self.data
214
+ return res
211
215
 
212
216
 
213
217
  class Opcode(IntEnum):
@@ -281,13 +285,14 @@ class Meta(ModelBase):
281
285
  @dataclass
282
286
  class MessageObject(ModelBase):
283
287
  id: str
284
- content: str
288
+ content: str = ""
285
289
  channel: Channel | None = None
286
290
  guild: Guild | None = None
287
291
  member: Member | None = None
288
292
  user: User | None = None
289
293
  created_at: datetime | None = None
290
294
  updated_at: datetime | None = None
295
+ referrer: dict | None = None
291
296
 
292
297
  @classmethod
293
298
  def from_elements(
@@ -300,8 +305,9 @@ class MessageObject(ModelBase):
300
305
  user: User | None = None,
301
306
  created_at: datetime | None = None,
302
307
  updated_at: datetime | None = None,
308
+ referrer: dict | None = None,
303
309
  ):
304
- obj = cls(id, "".join(str(i) for i in content), channel, guild, member, user, created_at, updated_at)
310
+ obj = cls(id, "".join(str(i) for i in content), channel, guild, member, user, created_at, updated_at, referrer)
305
311
  obj._parsed_message = content
306
312
  return obj
307
313
 
@@ -347,41 +353,8 @@ class MessageObject(ModelBase):
347
353
  res["created_at"] = int(self.created_at.timestamp() * 1000)
348
354
  if self.updated_at:
349
355
  res["updated_at"] = int(self.updated_at.timestamp() * 1000)
350
- return res
351
-
352
-
353
- @dataclass
354
- class MessageReceipt(ModelBase):
355
- id: str
356
- content: str | None = None
357
-
358
- @classmethod
359
- def from_elements(
360
- cls,
361
- id: str,
362
- content: list[Element] | None = None,
363
- ):
364
- return cls(id, "".join(str(i) for i in content) if content else None)
365
-
366
- @property
367
- def message(self) -> list[Element] | None:
368
- return transform(parse(self.content)) if self.content else None
369
-
370
- @message.setter
371
- def message(self, value: list[Element] | None):
372
- self.content = "".join(str(i) for i in value) if value else None
373
-
374
- @classmethod
375
- def parse(cls, raw: dict):
376
- if "elements" in raw and "content" not in raw:
377
- content = [RawElement(*item.values()) for item in raw["elements"]]
378
- raw["content"] = "".join(str(i) for i in content)
379
- return super().parse(raw)
380
-
381
- def dump(self):
382
- res = {"id": self.id}
383
- if self.content:
384
- res["content"] = self.content
356
+ if self.referrer:
357
+ res["referrer"] = self.referrer
385
358
  return res
386
359
 
387
360
 
@@ -399,6 +372,7 @@ class Event(ModelBase):
399
372
  operator: User | None = None
400
373
  role: Role | None = None
401
374
  user: User | None = None
375
+ referrer: dict | None = None
402
376
 
403
377
  _type: str | None = None
404
378
  _data: dict | None = None
@@ -430,6 +404,10 @@ class Event(ModelBase):
430
404
  "user": {"id": raw["self_id"]},
431
405
  "status": LoginStatus.ONLINE,
432
406
  }
407
+ if "self_id" in raw and not raw.get("login", {}).get("user"):
408
+ if "login" not in raw:
409
+ raw["login"] = {"sn": 0, "status": LoginStatus.ONLINE, "platform": raw.get("platform", "unknown")}
410
+ raw["login"]["user"] = {"id": raw["self_id"]}
433
411
  return super().parse(raw)
434
412
 
435
413
  @property
@@ -467,6 +445,8 @@ class Event(ModelBase):
467
445
  res["role"] = self.role.dump()
468
446
  if self.user:
469
447
  res["user"] = self.user.dump()
448
+ if self.referrer:
449
+ res["referrer"] = self.referrer
470
450
  if self._type:
471
451
  res["_type"] = self._type
472
452
  if self._data: