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.
- nonebot_plugin_uninfo/__init__.py +34 -0
- nonebot_plugin_uninfo/adapters/__init__.py +56 -0
- nonebot_plugin_uninfo/adapters/console/__init__.py +13 -0
- nonebot_plugin_uninfo/adapters/console/main.py +57 -0
- nonebot_plugin_uninfo/adapters/discord/__init__.py +13 -0
- nonebot_plugin_uninfo/adapters/discord/main.py +478 -0
- nonebot_plugin_uninfo/adapters/dodo/__init__.py +13 -0
- nonebot_plugin_uninfo/adapters/dodo/main.py +211 -0
- nonebot_plugin_uninfo/adapters/feishu/__init__.py +13 -0
- nonebot_plugin_uninfo/adapters/feishu/main.py +221 -0
- nonebot_plugin_uninfo/adapters/kook/__init__.py +13 -0
- nonebot_plugin_uninfo/adapters/kook/main.py +216 -0
- nonebot_plugin_uninfo/adapters/kritor/__init__.py +13 -0
- nonebot_plugin_uninfo/adapters/kritor/main.py +414 -0
- nonebot_plugin_uninfo/adapters/minecraft/__init__.py +13 -0
- nonebot_plugin_uninfo/adapters/minecraft/main.py +56 -0
- nonebot_plugin_uninfo/adapters/mirai/__init__.py +13 -0
- nonebot_plugin_uninfo/adapters/mirai/main.py +538 -0
- nonebot_plugin_uninfo/adapters/onebot11/__init__.py +13 -0
- nonebot_plugin_uninfo/adapters/onebot11/main.py +360 -0
- nonebot_plugin_uninfo/adapters/onebot12/__init__.py +13 -0
- nonebot_plugin_uninfo/adapters/onebot12/main.py +333 -0
- nonebot_plugin_uninfo/adapters/qq/__init__.py +13 -0
- nonebot_plugin_uninfo/adapters/qq/main.py +389 -0
- nonebot_plugin_uninfo/adapters/satori/__init__.py +13 -0
- nonebot_plugin_uninfo/adapters/satori/main.py +240 -0
- nonebot_plugin_uninfo/adapters/telegram/__init__.py +13 -0
- nonebot_plugin_uninfo/adapters/telegram/main.py +199 -0
- nonebot_plugin_uninfo/constraint.py +110 -0
- nonebot_plugin_uninfo/fetch.py +96 -0
- nonebot_plugin_uninfo/loader.py +12 -0
- nonebot_plugin_uninfo/model.py +135 -0
- nonebot_plugin_uninfo/params.py +86 -0
- nonebot_plugin_uninfo/permission.py +152 -0
- nonebot_plugin_uninfo-0.1.0.dist-info/METADATA +177 -0
- nonebot_plugin_uninfo-0.1.0.dist-info/RECORD +38 -0
- nonebot_plugin_uninfo-0.1.0.dist-info/WHEEL +4 -0
- 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
|