nonebot-plugin-uninfo 0.1.0__py3-none-any.whl

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.
Files changed (38) hide show
  1. nonebot_plugin_uninfo/__init__.py +34 -0
  2. nonebot_plugin_uninfo/adapters/__init__.py +56 -0
  3. nonebot_plugin_uninfo/adapters/console/__init__.py +13 -0
  4. nonebot_plugin_uninfo/adapters/console/main.py +57 -0
  5. nonebot_plugin_uninfo/adapters/discord/__init__.py +13 -0
  6. nonebot_plugin_uninfo/adapters/discord/main.py +478 -0
  7. nonebot_plugin_uninfo/adapters/dodo/__init__.py +13 -0
  8. nonebot_plugin_uninfo/adapters/dodo/main.py +211 -0
  9. nonebot_plugin_uninfo/adapters/feishu/__init__.py +13 -0
  10. nonebot_plugin_uninfo/adapters/feishu/main.py +221 -0
  11. nonebot_plugin_uninfo/adapters/kook/__init__.py +13 -0
  12. nonebot_plugin_uninfo/adapters/kook/main.py +216 -0
  13. nonebot_plugin_uninfo/adapters/kritor/__init__.py +13 -0
  14. nonebot_plugin_uninfo/adapters/kritor/main.py +414 -0
  15. nonebot_plugin_uninfo/adapters/minecraft/__init__.py +13 -0
  16. nonebot_plugin_uninfo/adapters/minecraft/main.py +56 -0
  17. nonebot_plugin_uninfo/adapters/mirai/__init__.py +13 -0
  18. nonebot_plugin_uninfo/adapters/mirai/main.py +538 -0
  19. nonebot_plugin_uninfo/adapters/onebot11/__init__.py +13 -0
  20. nonebot_plugin_uninfo/adapters/onebot11/main.py +360 -0
  21. nonebot_plugin_uninfo/adapters/onebot12/__init__.py +13 -0
  22. nonebot_plugin_uninfo/adapters/onebot12/main.py +333 -0
  23. nonebot_plugin_uninfo/adapters/qq/__init__.py +13 -0
  24. nonebot_plugin_uninfo/adapters/qq/main.py +389 -0
  25. nonebot_plugin_uninfo/adapters/satori/__init__.py +13 -0
  26. nonebot_plugin_uninfo/adapters/satori/main.py +240 -0
  27. nonebot_plugin_uninfo/adapters/telegram/__init__.py +13 -0
  28. nonebot_plugin_uninfo/adapters/telegram/main.py +199 -0
  29. nonebot_plugin_uninfo/constraint.py +110 -0
  30. nonebot_plugin_uninfo/fetch.py +96 -0
  31. nonebot_plugin_uninfo/loader.py +12 -0
  32. nonebot_plugin_uninfo/model.py +135 -0
  33. nonebot_plugin_uninfo/params.py +86 -0
  34. nonebot_plugin_uninfo/permission.py +152 -0
  35. nonebot_plugin_uninfo-0.1.0.dist-info/METADATA +177 -0
  36. nonebot_plugin_uninfo-0.1.0.dist-info/RECORD +38 -0
  37. nonebot_plugin_uninfo-0.1.0.dist-info/WHEEL +4 -0
  38. nonebot_plugin_uninfo-0.1.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,34 @@
1
+ from nonebot.plugin import PluginMetadata
2
+
3
+ from .constraint import SupportAdapterModule
4
+ from .fetch import InfoFetcher as InfoFetcher
5
+ from .model import Session as Session
6
+ from .params import Interface as Interface
7
+ from .params import QryItrface as QryItrface
8
+ from .params import QueryInterface as QueryInterface
9
+ from .params import UniSession as UniSession
10
+ from .params import Uninfo as Uninfo
11
+ from .params import get_interface as get_interface
12
+ from .params import get_session as get_session
13
+ from .permission import ADMIN as ADMIN
14
+ from .permission import GROUP as GROUP
15
+ from .permission import GUILD as GUILD
16
+ from .permission import MEMBER as MEMBER
17
+ from .permission import OWNER as OWNER
18
+ from .permission import PRIVATE as PRIVATE
19
+ from .permission import ROLE_IN as ROLE_IN
20
+ from .permission import ROLE_LEVEL as ROLE_LEVEL
21
+ from .permission import ROLE_NOT_IN as ROLE_NOT_IN
22
+ from .permission import SCENE_IN as SCENE_IN
23
+ from .permission import SCENE_NOT_IN as SCENE_NOT_IN
24
+ from .permission import USER_IN as USER_IN
25
+ from .permission import USER_NOT_IN as USER_NOT_IN
26
+
27
+ __plugin_meta__ = PluginMetadata(
28
+ name="通用信息",
29
+ description="多平台的会话信息(用户、群组、频道)获取插件",
30
+ usage="session_info: Uninfo",
31
+ type="library",
32
+ homepage="https://github.com/RF-Tar-Railt/nonebot-plugin-uninfo",
33
+ supported_adapters=set(SupportAdapterModule.__members__.values()),
34
+ )
@@ -0,0 +1,56 @@
1
+ import importlib
2
+ import os
3
+ from pathlib import Path
4
+ from typing import cast
5
+ from warnings import warn
6
+
7
+ from nonebot import get_adapters
8
+
9
+ from ..fetch import InfoFetcher
10
+ from ..loader import BaseLoader
11
+
12
+ root = Path(__file__).parent
13
+ loaders: dict[str, BaseLoader] = {}
14
+ _adapters = [path.stem for path in root.iterdir() if path.is_dir() and not path.stem.startswith("_")]
15
+ for name in _adapters:
16
+ try:
17
+ module = importlib.import_module(f".{name}", __package__)
18
+ loader = cast(BaseLoader, getattr(module, "Loader")())
19
+ loaders[loader.get_adapter().value] = loader
20
+ except Exception as e:
21
+ warn(f"Failed to import uniseg adapter {name}: {e}", RuntimeWarning, 5)
22
+
23
+
24
+ INFO_FETCHER_MAPPING: dict[str, InfoFetcher] = {}
25
+ adapters = {}
26
+ try:
27
+ adapters = get_adapters()
28
+ except Exception as e:
29
+ warn(f"Failed to get nonebot adapters: {e}", RuntimeWarning, 5)
30
+
31
+ if os.environ.get("PLUGIN_UNINFO_TESTENV"):
32
+ for adapter, loader in loaders.items():
33
+ try:
34
+ INFO_FETCHER_MAPPING[adapter] = loaders[adapter].get_fetcher()
35
+ except Exception as e:
36
+ warn(f"Failed to load uniseg adapter {adapter}: {e}", RuntimeWarning, 5)
37
+ elif not adapters:
38
+ warn(
39
+ "No adapters found, please make sure you have installed at least one adapter.",
40
+ RuntimeWarning,
41
+ 5,
42
+ )
43
+ else:
44
+ for adapter in adapters:
45
+ if adapter in loaders:
46
+ try:
47
+ INFO_FETCHER_MAPPING[adapter] = loaders[adapter].get_fetcher()
48
+ except Exception as e:
49
+ warn(f"Failed to load uniseg adapter {adapter}: {e}", RuntimeWarning, 5)
50
+ else:
51
+ warn(
52
+ f"Adapter {adapter} is not found in the uniseg.adapters,"
53
+ f"please go to the github repo and create an issue for it.",
54
+ RuntimeWarning,
55
+ 5,
56
+ )
@@ -0,0 +1,13 @@
1
+ from nonebot_plugin_uninfo.constraint import SupportAdapter
2
+ from nonebot_plugin_uninfo.fetch import InfoFetcher
3
+ from nonebot_plugin_uninfo.loader import BaseLoader
4
+
5
+
6
+ class Loader(BaseLoader):
7
+ def get_adapter(self) -> SupportAdapter:
8
+ return SupportAdapter.console
9
+
10
+ def get_fetcher(self) -> InfoFetcher:
11
+ from .main import fetcher
12
+
13
+ return fetcher
@@ -0,0 +1,57 @@
1
+ from typing import Optional
2
+
3
+ from nonebot.adapters.console import Bot
4
+ from nonebot.adapters.console.event import Event
5
+
6
+ from nonebot_plugin_uninfo.constraint import SupportAdapter, SupportScope
7
+ from nonebot_plugin_uninfo.fetch import InfoFetcher as BaseInfoFetcher
8
+ from nonebot_plugin_uninfo.fetch import SuppliedData
9
+ from nonebot_plugin_uninfo.model import Scene, SceneType, User
10
+
11
+
12
+ class InfoFetcher(BaseInfoFetcher):
13
+ def extract_user(self, data):
14
+ return User(
15
+ id=data["user_id"],
16
+ name=data["name"],
17
+ avatar=data["avatar"],
18
+ )
19
+
20
+ def extract_scene(self, data):
21
+ return Scene(
22
+ id=data["user_id"],
23
+ type=SceneType.PRIVATE,
24
+ name=data["name"],
25
+ avatar=data["avatar"],
26
+ )
27
+
28
+ def extract_member(self, data, user: Optional[User]):
29
+ return None
30
+
31
+ async def query_user(self, bot: Bot):
32
+ raise NotImplementedError
33
+
34
+ async def query_scene(self, bot: Bot, guild_id: Optional[str]):
35
+ raise NotImplementedError
36
+
37
+ async def query_member(self, bot: Bot, guild_id: str):
38
+ raise NotImplementedError
39
+
40
+ def supply_self(self, bot: Bot) -> SuppliedData:
41
+ return {
42
+ "self_id": str(bot.self_id),
43
+ "adapter": SupportAdapter.console,
44
+ "scope": SupportScope.console,
45
+ }
46
+
47
+
48
+ fetcher = InfoFetcher(SupportAdapter.console)
49
+
50
+
51
+ @fetcher.supply_wildcard
52
+ async def _(bot: Bot, event: Event):
53
+ return {
54
+ "user_id": event.user.id,
55
+ "name": event.user.nickname,
56
+ "avatar": f"https://emojicdn.elk.sh/{event.user.avatar}?style=twitter",
57
+ }
@@ -0,0 +1,13 @@
1
+ from nonebot_plugin_uninfo.constraint import SupportAdapter
2
+ from nonebot_plugin_uninfo.fetch import InfoFetcher
3
+ from nonebot_plugin_uninfo.loader import BaseLoader
4
+
5
+
6
+ class Loader(BaseLoader):
7
+ def get_adapter(self) -> SupportAdapter:
8
+ return SupportAdapter.discord
9
+
10
+ def get_fetcher(self) -> InfoFetcher:
11
+ from .main import fetcher
12
+
13
+ return fetcher
@@ -0,0 +1,478 @@
1
+ from datetime import timedelta
2
+ from typing import Optional, Union
3
+
4
+ from nonebot.adapters.discord import Bot
5
+ from nonebot.adapters.discord.api.model import Channel as DiscordChannel
6
+ from nonebot.adapters.discord.api.model import GuildMember, Snowflake
7
+ from nonebot.adapters.discord.api.model import User as DiscordUser
8
+ from nonebot.adapters.discord.api.types import ChannelType as DiscordChannelType
9
+ from nonebot.adapters.discord.api.types import UNSET
10
+ from nonebot.adapters.discord.event import (
11
+ ChannelCreateEvent,
12
+ ChannelDeleteEvent,
13
+ ChannelUpdateEvent,
14
+ DirectMessageCreateEvent,
15
+ DirectMessageDeleteBulkEvent,
16
+ DirectMessageDeleteEvent,
17
+ DirectMessageReactionAddEvent,
18
+ DirectMessageReactionRemoveAllEvent,
19
+ DirectMessageReactionRemoveEmojiEvent,
20
+ DirectMessageReactionRemoveEvent,
21
+ DirectMessageUpdateEvent,
22
+ Event,
23
+ GuildBanAddEvent,
24
+ GuildBanRemoveEvent,
25
+ GuildCreateEvent,
26
+ GuildDeleteEvent,
27
+ GuildMemberAddEvent,
28
+ GuildMemberRemoveEvent,
29
+ GuildMemberUpdateEvent,
30
+ GuildMessageCreateEvent,
31
+ GuildMessageDeleteBulkEvent,
32
+ GuildMessageDeleteEvent,
33
+ GuildMessageReactionAddEvent,
34
+ GuildMessageReactionRemoveAllEvent,
35
+ GuildMessageReactionRemoveEmojiEvent,
36
+ GuildMessageReactionRemoveEvent,
37
+ GuildMessageUpdateEvent,
38
+ GuildUpdateEvent,
39
+ InteractionCreateEvent,
40
+ )
41
+
42
+ from nonebot_plugin_uninfo.constraint import SupportAdapter, SupportScope
43
+ from nonebot_plugin_uninfo.fetch import InfoFetcher as BaseInfoFetcher
44
+ from nonebot_plugin_uninfo.fetch import SuppliedData
45
+ from nonebot_plugin_uninfo.model import Member, MuteInfo, Role, Scene, SceneType, User
46
+
47
+ CHANNEL_TYPE = {
48
+ DiscordChannelType.GUILD_TEXT: SceneType.CHANNEL_TEXT,
49
+ DiscordChannelType.GUILD_VOICE: SceneType.CHANNEL_VOICE,
50
+ DiscordChannelType.GUILD_CATEGORY: SceneType.CHANNEL_CATEGORY,
51
+ DiscordChannelType.DM: SceneType.PRIVATE,
52
+ DiscordChannelType.GROUP_DM: SceneType.GROUP,
53
+ DiscordChannelType.GUILD_STAGE_VOICE: SceneType.CHANNEL_VOICE,
54
+ DiscordChannelType.GUILD_DIRECTORY: SceneType.CHANNEL_CATEGORY,
55
+ }
56
+
57
+ BASE_URL = "https://cdn.discordapp.com/"
58
+
59
+
60
+ def avatar_url(id: str, avatar: str):
61
+ if not avatar:
62
+ return None
63
+ return f"{BASE_URL}avatars/{id}/{avatar}.png?size=1024"
64
+
65
+
66
+ async def _handle_role(bot: Bot, guild_id: str, roles: list[Snowflake]):
67
+ if not roles:
68
+ return Role("MEMBER", 1, "member")
69
+ res = []
70
+ resp = await bot.get_guild_roles(guild_id=int(guild_id))
71
+ for role in resp:
72
+ if role.id not in roles:
73
+ continue
74
+ perm = int(role.permissions)
75
+ if perm & (1 << 3) == (1 << 3):
76
+ if perm & (1 << 5) == (1 << 5):
77
+ res.append(("OWNER", 100, role.name))
78
+ res.append(("ADMINISTRATOR", 10, role.name))
79
+ if perm & (1 << 4) == (1 << 4):
80
+ res.append(("CHANNEL_ADMINISTRATOR", 9, role.name))
81
+ res.append((str(role.id), 1, role.name))
82
+ if not res:
83
+ return Role("MEMBER", 1, "member")
84
+ return Role(*sorted(res, key=lambda x: x[1], reverse=True)[0])
85
+
86
+
87
+ class InfoFetcher(BaseInfoFetcher):
88
+ def extract_user(self, data):
89
+ return User(
90
+ id=data["user_id"],
91
+ name=data["name"],
92
+ avatar=avatar_url(data["user_id"], data["avatar"]),
93
+ )
94
+
95
+ def extract_scene(self, data):
96
+ if "guild_id" in data:
97
+ if "channel_id" in data:
98
+ return Scene(
99
+ id=data["channel_id"],
100
+ name=data.get("channel_name"),
101
+ type=data.get("channel_type", SceneType.CHANNEL_TEXT),
102
+ avatar=avatar_url(data["channel_id"], data.get("channel_avatar") or ""),
103
+ parent=Scene(
104
+ id=data["guild_id"],
105
+ name=data.get("guild_name"),
106
+ type=SceneType.GUILD,
107
+ avatar=avatar_url(data["guild_id"], data.get("guild_avatar") or ""),
108
+ ),
109
+ )
110
+ return Scene(
111
+ id=data["guild_id"],
112
+ name=data.get("guild_name"),
113
+ type=SceneType.GUILD,
114
+ avatar=avatar_url(data["guild_id"], data.get("guild_avatar") or ""),
115
+ )
116
+ if "channel_id" in data:
117
+ return Scene(
118
+ id=data["channel_id"],
119
+ name=data.get("channel_name"),
120
+ type=data.get("channel_type", SceneType.CHANNEL_TEXT),
121
+ avatar=avatar_url(data["channel_id"], data.get("channel_avatar") or ""),
122
+ )
123
+ return Scene(
124
+ id=data["user_id"],
125
+ type=SceneType.PRIVATE,
126
+ name=data["name"],
127
+ avatar=avatar_url(data["user_id"], data.get("avatar") or ""),
128
+ )
129
+
130
+ def extract_member(self, data, user: Optional[User]):
131
+ if "guild_id" in data or "channel_id" in data:
132
+ if user:
133
+ return Member(user, nick=data["nickname"], role=data.get("role"), joined_at=data.get("joined_at"))
134
+ return Member(
135
+ User(
136
+ id=data["user_id"],
137
+ name=data["name"],
138
+ avatar=avatar_url(data["user_id"], data.get("avatar") or ""),
139
+ ),
140
+ nick=data["nickname"],
141
+ role=data.get("role"),
142
+ joined_at=data.get("joined_at"),
143
+ )
144
+ return None
145
+
146
+ async def query_user(self, bot: Bot):
147
+ raise NotImplementedError
148
+
149
+ async def query_scene(self, bot: Bot, guild_id: Optional[str]):
150
+ guilds = await bot.get_current_user_guilds(limit=100)
151
+ while guilds:
152
+ for guild in guilds:
153
+ if not guild_id or str(guild.id) == guild_id:
154
+ _guild = Scene(
155
+ id=str(guild.id),
156
+ type=SceneType.GUILD,
157
+ name=guild.name,
158
+ avatar=avatar_url(str(guild.id), guild.icon or ""),
159
+ )
160
+ yield _guild
161
+ channels = await bot.get_guild_channels(guild_id=guild.id)
162
+ for channel in channels:
163
+ yield Scene(
164
+ id=str(channel.id),
165
+ type=CHANNEL_TYPE.get(channel.type, SceneType.CHANNEL_TEXT),
166
+ name=channel.name,
167
+ avatar=avatar_url(str(channel.id), channel.icon or ""),
168
+ parent=_guild,
169
+ )
170
+ if len(guilds) < 100:
171
+ break
172
+ guilds = await bot.get_current_user_guilds(limit=100, after=guilds[-1].id)
173
+
174
+ async def query_member(self, bot: Bot, guild_id: str):
175
+ members = await bot.list_guild_members(guild_id=int(guild_id), limit=100)
176
+ while members:
177
+ for member in members:
178
+ if isinstance(member.user, DiscordUser):
179
+ user = User(
180
+ id=str(member.user.id),
181
+ name=member.user.username,
182
+ avatar=member.user.avatar,
183
+ )
184
+ else:
185
+ continue
186
+ yield Member(
187
+ user=user,
188
+ nick="" if member.nick is UNSET else member.nick,
189
+ role=await _handle_role(bot, guild_id, member.roles),
190
+ joined_at=member.joined_at,
191
+ mute=None if member.mute is UNSET else MuteInfo(muted=member.mute, duration=timedelta(60)),
192
+ )
193
+ if len(members) < 100:
194
+ break
195
+ members = await bot.list_guild_members(guild_id=int(guild_id), limit=100, after=members[-1].user.id)
196
+
197
+ def supply_self(self, bot) -> SuppliedData:
198
+ return {
199
+ "self_id": str(bot.self_id),
200
+ "adapter": SupportAdapter.discord,
201
+ "scope": SupportScope.discord,
202
+ }
203
+
204
+
205
+ fetcher = InfoFetcher(SupportAdapter.discord)
206
+
207
+
208
+ @fetcher.supply
209
+ async def _(bot: Bot, event: InteractionCreateEvent):
210
+ if isinstance(event.user, DiscordUser):
211
+ base = {
212
+ "user_id": str(event.user.id),
213
+ "name": event.user.username,
214
+ "nickname": "",
215
+ "avatar": event.user.avatar,
216
+ }
217
+ return base
218
+ assert isinstance(event.member, GuildMember)
219
+ assert isinstance(event.guild_id, int)
220
+ assert isinstance(event.channel_id, int)
221
+ guild_info = await bot.get_guild(guild_id=event.guild_id)
222
+ base = {
223
+ "user_id": str(event.member.user.id),
224
+ "name": event.member.user.username,
225
+ "nickname": event.member.nick,
226
+ "avatar": event.member.user.avatar,
227
+ "guild_id": str(event.guild_id),
228
+ "guild_name": guild_info.name,
229
+ "guild_avatar": guild_info.icon,
230
+ }
231
+ if isinstance(event.channel, DiscordChannel):
232
+ base |= {
233
+ "channel_id": str(event.channel.id),
234
+ "channel_name": event.channel.name or "",
235
+ "channel_type": CHANNEL_TYPE.get(event.channel.type, SceneType.CHANNEL_TEXT),
236
+ "channel_avatar": event.channel.icon or "",
237
+ }
238
+ else:
239
+ channel = await bot.get_channel(channel_id=event.channel_id)
240
+ base |= {
241
+ "channel_id": str(channel.id),
242
+ "channel_name": channel.name or "",
243
+ "channel_type": CHANNEL_TYPE.get(channel.type, SceneType.CHANNEL_TEXT),
244
+ "channel_avatar": channel.icon or "",
245
+ }
246
+ return base
247
+
248
+
249
+ @fetcher.supply
250
+ async def _(
251
+ bot: Bot,
252
+ event: Union[DirectMessageCreateEvent, GuildMessageCreateEvent, DirectMessageUpdateEvent, GuildMessageUpdateEvent],
253
+ ):
254
+ base = {
255
+ "user_id": str(event.author.id),
256
+ "name": event.author.username,
257
+ "nickname": event.author.username,
258
+ "avatar": event.author.avatar,
259
+ }
260
+ if isinstance(event.guild_id, Snowflake):
261
+ guild = await bot.get_guild(guild_id=int(event.guild_id))
262
+ base |= {
263
+ "guild_id": str(event.guild_id),
264
+ "guild_name": guild.name,
265
+ "guild_avatar": guild.icon,
266
+ }
267
+ channel = await bot.get_channel(channel_id=int(event.channel_id))
268
+ base |= {
269
+ "channel_id": str(event.channel_id),
270
+ "channel_name": channel.name,
271
+ "channel_type": CHANNEL_TYPE.get(channel.type, SceneType.CHANNEL_TEXT),
272
+ "channel_avatar": channel.icon,
273
+ }
274
+ if isinstance(event.member, GuildMember):
275
+ base |= {
276
+ "nickname": event.member.nick or event.author.username,
277
+ "role": await _handle_role(bot, str(event.guild_id), event.member.roles),
278
+ "joined_at": event.member.joined_at,
279
+ }
280
+ else:
281
+ member = await bot.get_guild_member(guild_id=event.guild_id, user_id=event.author.id)
282
+ base |= {
283
+ "nickname": member.nick or event.author.username,
284
+ "role": await _handle_role(bot, str(event.guild_id), member.roles),
285
+ "joined_at": member.joined_at,
286
+ }
287
+ return base
288
+
289
+
290
+ @fetcher.supply
291
+ async def _(
292
+ bot: Bot,
293
+ event: Union[
294
+ DirectMessageDeleteEvent,
295
+ DirectMessageDeleteBulkEvent,
296
+ GuildMessageDeleteEvent,
297
+ GuildMessageDeleteBulkEvent,
298
+ GuildMessageReactionRemoveAllEvent,
299
+ DirectMessageReactionRemoveAllEvent,
300
+ DirectMessageReactionRemoveEmojiEvent,
301
+ GuildMessageReactionRemoveEmojiEvent,
302
+ ],
303
+ ):
304
+ self_info = await bot.get_current_user()
305
+ base = {
306
+ "user_id": str(self_info.id),
307
+ "name": self_info.username,
308
+ "nickname": self_info.username,
309
+ "avatar": self_info.avatar,
310
+ }
311
+ if isinstance(event.guild_id, Snowflake):
312
+ guild = await bot.get_guild(guild_id=int(event.guild_id))
313
+ base |= {
314
+ "guild_id": str(event.guild_id),
315
+ "guild_name": guild.name,
316
+ "guild_avatar": guild.icon,
317
+ }
318
+ channel = await bot.get_channel(channel_id=int(event.channel_id))
319
+ base |= {
320
+ "channel_id": str(event.channel_id),
321
+ "channel_name": channel.name,
322
+ "channel_type": CHANNEL_TYPE.get(channel.type, SceneType.CHANNEL_TEXT),
323
+ "channel_avatar": channel.icon,
324
+ }
325
+ return base
326
+
327
+
328
+ @fetcher.supply
329
+ async def _(
330
+ bot: Bot,
331
+ event: Union[
332
+ DirectMessageReactionAddEvent,
333
+ DirectMessageReactionRemoveEvent,
334
+ GuildMessageReactionAddEvent,
335
+ GuildMessageReactionRemoveEvent,
336
+ ],
337
+ ):
338
+ user = await bot.get_user(user_id=event.user_id)
339
+ base = {
340
+ "user_id": str(event.user_id),
341
+ "name": user.username,
342
+ "nickname": user.username,
343
+ "avatar": user.avatar,
344
+ }
345
+ if isinstance(event.guild_id, Snowflake):
346
+ guild = await bot.get_guild(guild_id=int(event.guild_id))
347
+ base |= {
348
+ "guild_id": str(event.guild_id),
349
+ "guild_name": guild.name,
350
+ "guild_avatar": guild.icon,
351
+ }
352
+ channel = await bot.get_channel(channel_id=int(event.channel_id))
353
+ base |= {
354
+ "channel_id": str(event.channel_id),
355
+ "channel_name": channel.name,
356
+ "channel_type": CHANNEL_TYPE.get(channel.type, SceneType.CHANNEL_TEXT),
357
+ "channel_avatar": channel.icon,
358
+ }
359
+ member = await bot.get_guild_member(guild_id=event.guild_id, user_id=event.user_id)
360
+ base |= {
361
+ "nickname": member.nick or user.username,
362
+ "role": await _handle_role(bot, str(event.guild_id), member.roles),
363
+ "joined_at": member.joined_at,
364
+ }
365
+ return base
366
+
367
+
368
+ @fetcher.supply_wildcard
369
+ async def _(bot: Bot, event: Event):
370
+ if isinstance(event, (ChannelCreateEvent, ChannelDeleteEvent, ChannelUpdateEvent)):
371
+ self_info = await bot.get_current_user()
372
+ base = {
373
+ "user_id": str(self_info.id),
374
+ "name": self_info.username,
375
+ "nickname": self_info.username,
376
+ "avatar": self_info.avatar,
377
+ }
378
+ base |= {
379
+ "channel_id": str(event.id),
380
+ "channel_name": event.name,
381
+ "channel_type": CHANNEL_TYPE.get(event.type, SceneType.CHANNEL_TEXT),
382
+ "channel_avatar": event.icon,
383
+ }
384
+ if isinstance(event.guild_id, Snowflake):
385
+ guild = await bot.get_guild(guild_id=int(event.guild_id))
386
+ base |= {
387
+ "guild_id": str(event.guild_id),
388
+ "guild_name": guild.name,
389
+ "guild_avatar": guild.icon,
390
+ }
391
+ return base
392
+ if isinstance(event, (GuildBanAddEvent, GuildBanRemoveEvent)):
393
+ base = {
394
+ "user_id": str(event.user.id),
395
+ "name": event.user.username,
396
+ "nickname": event.user.username,
397
+ "avatar": event.user.avatar,
398
+ }
399
+ guild = await bot.get_guild(guild_id=int(event.guild_id))
400
+ base |= {
401
+ "guild_id": str(event.guild_id),
402
+ "guild_name": guild.name,
403
+ "guild_avatar": guild.icon,
404
+ }
405
+ return base
406
+ if isinstance(event, (GuildCreateEvent, GuildUpdateEvent)):
407
+ self_info = await bot.get_current_user()
408
+ base = {
409
+ "user_id": str(self_info.id),
410
+ "name": self_info.username,
411
+ "nickname": self_info.username,
412
+ "avatar": self_info.avatar,
413
+ }
414
+ base |= {
415
+ "guild_id": str(event.id),
416
+ "guild_name": event.name,
417
+ "guild_avatar": event.icon,
418
+ }
419
+ return base
420
+ if isinstance(event, GuildDeleteEvent):
421
+ self_info = await bot.get_current_user()
422
+ base = {
423
+ "user_id": str(self_info.id),
424
+ "name": self_info.username,
425
+ "nickname": self_info.username,
426
+ "avatar": self_info.avatar,
427
+ "guild_id": str(event.id),
428
+ "guild_name": "",
429
+ "guild_avatar": "",
430
+ }
431
+ return base
432
+ if isinstance(event, GuildMemberAddEvent):
433
+ base = {
434
+ "user_id": str(event.user.id),
435
+ "name": event.user.username,
436
+ "nickname": event.nick or "",
437
+ "avatar": event.avatar or event.user.avatar,
438
+ "role": await _handle_role(bot, str(event.guild_id), event.roles),
439
+ "joined_at": event.joined_at,
440
+ }
441
+ guild = await bot.get_guild(guild_id=int(event.guild_id))
442
+ base |= {
443
+ "guild_id": str(event.guild_id),
444
+ "guild_name": guild.name,
445
+ "guild_avatar": guild.icon,
446
+ }
447
+ return base
448
+ if isinstance(event, GuildMemberUpdateEvent):
449
+ base = {
450
+ "user_id": str(event.user.id),
451
+ "name": event.user.username,
452
+ "nickname": event.nick or "",
453
+ "avatar": event.user.avatar,
454
+ "role": await _handle_role(bot, str(event.guild_id), event.roles),
455
+ "joined_at": event.joined_at,
456
+ }
457
+ guild = await bot.get_guild(guild_id=int(event.guild_id))
458
+ base |= {
459
+ "guild_id": str(event.guild_id),
460
+ "guild_name": guild.name,
461
+ "guild_avatar": guild.icon,
462
+ }
463
+ return base
464
+ if isinstance(event, GuildMemberRemoveEvent):
465
+ base = {
466
+ "user_id": str(event.user.id),
467
+ "name": event.user.username,
468
+ "nickname": event.user.username,
469
+ "avatar": event.user.avatar,
470
+ }
471
+ guild = await bot.get_guild(guild_id=int(event.guild_id))
472
+ base |= {
473
+ "guild_id": str(event.guild_id),
474
+ "guild_name": guild.name,
475
+ "guild_avatar": guild.icon,
476
+ }
477
+ return base
478
+ raise NotImplementedError
@@ -0,0 +1,13 @@
1
+ from nonebot_plugin_uninfo.constraint import SupportAdapter
2
+ from nonebot_plugin_uninfo.fetch import InfoFetcher
3
+ from nonebot_plugin_uninfo.loader import BaseLoader
4
+
5
+
6
+ class Loader(BaseLoader):
7
+ def get_adapter(self) -> SupportAdapter:
8
+ return SupportAdapter.dodo
9
+
10
+ def get_fetcher(self) -> InfoFetcher:
11
+ from .main import fetcher
12
+
13
+ return fetcher