使用uninfo进行群组成员更新 (#1690)

This commit is contained in:
HibiKier 2024-10-10 23:25:46 +08:00 committed by GitHub
parent 2f459719e8
commit 9e5266a491
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 144 additions and 210 deletions

22
poetry.lock generated
View File

@ -2511,6 +2511,26 @@ type = "legacy"
url = "https://mirrors.aliyun.com/pypi/simple" url = "https://mirrors.aliyun.com/pypi/simple"
reference = "ali" reference = "ali"
[[package]]
name = "nonebot-plugin-uninfo"
version = "0.4.0"
description = "Universal Information Model for Nonebot2"
optional = false
python-versions = ">=3.9"
files = [
{file = "nonebot_plugin_uninfo-0.4.0-py3-none-any.whl", hash = "sha256:d60a8491af52b1b2c0cdb3f2e4a4a8d02e66216a33e8d162f1da8bec73b3b701"},
{file = "nonebot_plugin_uninfo-0.4.0.tar.gz", hash = "sha256:3e1a494d05639a0227a8565d5cde90ec9724934a7ec32bf1e0bd40404faf9713"},
]
[package.dependencies]
importlib-metadata = ">=4.13.0"
nonebot2 = ">=2.3.0"
[package.source]
type = "legacy"
url = "https://mirrors.aliyun.com/pypi/simple"
reference = "ali"
[[package]] [[package]]
name = "nonebot-plugin-userinfo" name = "nonebot-plugin-userinfo"
version = "0.1.3" version = "0.1.3"
@ -4925,4 +4945,4 @@ reference = "ali"
[metadata] [metadata]
lock-version = "2.0" lock-version = "2.0"
python-versions = "^3.10" python-versions = "^3.10"
content-hash = "e66133515a2b17715ddf5f887ec31f128751acda1ea67736e9d27b29a9b16b65" content-hash = "527819a6117da3c41931d968f9238468aee98f2ca97f06e1ba1e7948b6cbe65c"

View File

@ -51,6 +51,7 @@ nonebot-plugin-alconna = "0.51.1"
arclet-alconna = "1.8.23" arclet-alconna = "1.8.23"
aiocache = "^0.12.2" aiocache = "^0.12.2"
py-cpuinfo = "^9.0.0" py-cpuinfo = "^9.0.0"
nonebot-plugin-uninfo = "^0.4.1"
[tool.poetry.dev-dependencies] [tool.poetry.dev-dependencies]
nonebug = "^0.3.2" nonebug = "^0.3.2"

View File

@ -49,18 +49,15 @@ _notice = on_notice(priority=1, block=False, rule=notice_rule(GroupIncreaseNotic
async def _(bot: Bot, session: EventSession, arparma: Arparma): async def _(bot: Bot, session: EventSession, arparma: Arparma):
if gid := session.id3 or session.id2: if gid := session.id3 or session.id2:
logger.info("更新群组成员信息", arparma.header_result, session=session) logger.info("更新群组成员信息", arparma.header_result, session=session)
await MemberUpdateManage.update(bot, gid) result = await MemberUpdateManage.update_group_member(bot, gid)
await MessageUtils.build_message("已经成功更新了群组成员信息!").finish( await MessageUtils.build_message(result).finish(reply_to=True)
reply_to=True
)
await MessageUtils.build_message("群组id为空...").send() await MessageUtils.build_message("群组id为空...").send()
@_notice.handle() @_notice.handle()
async def _(bot: Bot, event: GroupIncreaseNoticeEvent): async def _(bot: Bot, event: GroupIncreaseNoticeEvent):
# TODO: 其他适配器的加群自动更新群组成员信息
if str(event.user_id) == bot.self_id: if str(event.user_id) == bot.self_id:
await MemberUpdateManage.update(bot, str(event.group_id)) await MemberUpdateManage.update_group_member(bot, str(event.group_id))
logger.info( logger.info(
f"{BotConfig.self_nickname}加入群聊更新群组信息", f"{BotConfig.self_nickname}加入群聊更新群组信息",
"更新群组成员列表", "更新群组成员列表",
@ -81,7 +78,9 @@ async def _():
if group_list: if group_list:
for group in group_list: for group in group_list:
try: try:
await MemberUpdateManage.update(bot, group.group_id) await MemberUpdateManage.update_group_member(
bot, group.group_id
)
logger.debug("自动更新群组成员信息成功...") logger.debug("自动更新群组成员信息成功...")
except Exception as e: except Exception as e:
logger.error( logger.error(

View File

@ -1,213 +1,129 @@
from datetime import datetime, timezone, timedelta import nonebot
from nonebot.adapters import Bot from nonebot.adapters import Bot
from nonebot_plugin_uninfo import Member, SceneType, get_interface
# from nonebot.adapters.kaiheila import Bot as KaiheilaBot
from nonebot.adapters.onebot.v11 import Bot as v11Bot
from nonebot.adapters.onebot.v12 import Bot as v12Bot
from zhenxun.services.log import logger from zhenxun.services.log import logger
from zhenxun.configs.config import Config from zhenxun.configs.config import Config
from zhenxun.models.level_user import LevelUser from zhenxun.models.level_user import LevelUser
from zhenxun.utils.platform import PlatformUtils
from zhenxun.models.group_member_info import GroupInfoUser from zhenxun.models.group_member_info import GroupInfoUser
# from nonebot.adapters.discord import Bot as DiscordBot
# from nonebot.adapters.dodo import Bot as DodoBot
class MemberUpdateManage: class MemberUpdateManage:
@classmethod @classmethod
async def update(cls, bot: Bot, group_id: str): async def __handle_user(
if not group_id: cls,
return logger.warning( member: Member,
f"bot: {bot.self_id}group_id为空无法更新群成员信息..." db_user: list[GroupInfoUser],
) group_id: str,
if isinstance(bot, v11Bot): data_list: tuple[list, list, list],
await cls.v11(bot, group_id) platform: str | None,
elif isinstance(bot, v12Bot): ):
await cls.v12(bot, group_id) """单个成员操作
# elif isinstance(bot, KaiheilaBot):
# await cls.kaiheila(bot, group_id)
# elif isinstance(bot, DodoBot):
# await cls.dodo(bot, group_id)
# elif isinstance(bot, DiscordBot):
# await cls.discord(bot, group_id)
# @classmethod 参数:
# async def discord(cls, bot: DiscordBot, group_id: str): member: Member
# # TODO: discord更新群组成员信息 db_user: db成员数据
# pass group_id: 群组id
data_list: 数据列表
# @classmethod platform: 平台
# async def dodo(cls, bot: DodoBot, group_id: str): """
# page_size = 100 driver = nonebot.get_driver()
# result_size = 100
# max_id = 0
# exist_member_list = []
# group_member_list: list[MemberInfo] = []
# while result_size == page_size:
# group_member_data = await bot.get_member_list(
# island_source_id=group_id, page_size=page_size
# )
# result_size = len(group_member_data.list)
# group_member_list += group_member_data.list
# max_id = group_member_data.max_id
# if group_member_list:
# for user in group_member_list:
# exist_member_list.append(user.dodo_source_id)
# await GroupInfoUser.update_or_create(
# user_id=user.dodo_source_id,
# group_id=group_id,
# defaults={
# "user_name": user.nick_name or user.personal_nick_name,
# "user_join_time": user.join_time,
# "platform": "dodo",
# },
# )
# if delete_member_list := list(
# set(exist_member_list).difference(
# set(await GroupInfoUser.get_group_member_id_list(group_id))
# )
# ):
# await GroupInfoUser.filter(
# user_id__in=delete_member_list, group_id=group_id
# ).delete()
# logger.info(
# f"删除已退群用户",
# "更新群组成员信息",
# group_id=group_id,
# platform="dodo",
# )
# @classmethod
# async def kaiheila(cls, bot: KaiheilaBot, group_id: str):
# # TODO: kaiheila 更新群组成员信息
# pass
@classmethod
async def v11(cls, bot: v11Bot, group_id: str):
exist_member_list = []
default_auth = Config.get_config("admin_bot_manage", "ADMIN_DEFAULT_AUTH") default_auth = Config.get_config("admin_bot_manage", "ADMIN_DEFAULT_AUTH")
group_member_list = await bot.get_group_member_list(group_id=int(group_id)) nickname = member.nick or member.user.name or ""
db_user = await GroupInfoUser.filter(group_id=group_id).all() role = member.role
db_user_uid = [u.user_id for u in db_user] db_user_uid = [u.user_id for u in db_user]
uid2name = {u.user_id: u.user_name for u in db_user} uid2name = {u.user_id: u.user_name for u in db_user}
create_list = [] if member.id in driver.config.superusers:
update_list = [] await LevelUser.set_level(member.id, group_id, 9)
delete_list = [] elif default_auth:
for user_info in group_member_list: if role != "MEMBER" and not await LevelUser.is_group_flag(
user_id = str(user_info["user_id"]) member.id, group_id
nickname = user_info["card"] or user_info["nickname"]
role = user_info["role"]
if (
default_auth
and role in ["owner", "admin"]
and not await LevelUser.is_group_flag(user_id, group_id)
): ):
if role == "owner": if role == "OWNER":
await LevelUser.set_level(user_id, group_id, default_auth + 1) await LevelUser.set_level(member.id, group_id, default_auth + 1)
else: elif role == "ADMINISTRATOR":
await LevelUser.set_level(user_id, group_id, default_auth) await LevelUser.set_level(member.id, group_id, default_auth)
if user_id in bot.config.superusers: if cnt := db_user_uid.count(member.id):
await LevelUser.set_level(user_id, group_id, 9) users = [u for u in db_user if u.user_id == member.id]
join_time = datetime.fromtimestamp( if cnt > 1:
user_info["join_time"], timezone(timedelta(hours=8)) for u in users[1:]:
) data_list[2].append(u.id)
if cnt := db_user_uid.count(user_id): if nickname != uid2name.get(member.id):
users = [u for u in db_user if u.user_id == user_id] user = users[0]
if cnt > 1: user.user_name = nickname
for u in users[1:]: data_list[1].append(user)
delete_list.append(u.id) else:
if nickname != uid2name.get(user_id): data_list[0].append(
user = users[0] GroupInfoUser(
user.user_name = nickname user_id=member.id,
update_list.append(user) group_id=group_id,
else: user_name=nickname,
create_list.append( user_join_time=member.joined_at,
GroupInfoUser( platform=platform,
user_id=user_id,
group_id=group_id,
user_name=nickname,
user_join_time=join_time,
platform="qq",
)
) )
exist_member_list.append(user_id)
if create_list:
await GroupInfoUser.bulk_create(create_list, 30)
logger.debug(
f"创建用户数据 {len(create_list)}",
"更新群组成员信息",
target=group_id,
)
if update_list:
await GroupInfoUser.bulk_update(update_list, ["user_name"], 30)
logger.debug(
f"更新户数据 {len(update_list)}", "更新群组成员信息", target=group_id
)
if delete_list:
await GroupInfoUser.filter(id__in=delete_list).delete()
logger.debug(f"删除重复数据 Ids: {delete_list}", "更新群组成员信息")
if delete_member_list := [
uid for uid in db_user_uid if uid not in exist_member_list
]:
await GroupInfoUser.filter(
user_id__in=delete_member_list, group_id=group_id
).delete()
logger.info(
f"删除已退群用户 {len(delete_member_list)}",
"更新群组成员信息",
group_id=group_id,
platform="qq",
) )
@classmethod @classmethod
async def v12(cls, bot: v12Bot, group_id: str): async def update_group_member(cls, bot: Bot, group_id: str) -> str:
# TODO: v12更新群组成员信息 """更新群组成员信息
pass
# exist_member_list = [] 参数:
# default_auth = Config.get_config("admin_bot_manage", "ADMIN_DEFAULT_AUTH") bot: Bot
# group_member_list: list[GetGroupMemberInfoResp] = group_id: 群组id
# await bot.get_group_member_list(
# group_id=group_id 返回:
# ) str: 返回消息
# for user_info in group_member_list: """
# user_id = user_info.user_id if not group_id:
# nickname = user_info.user_displayname or user_info.user_name logger.warning(f"bot: {bot.self_id}group_id为空无法更新群成员信息...")
# role = user_info["role"] return "群组id为空..."
# if default_auth: if interface := get_interface(bot):
# if role in ["owner", "admin"] and not LevelUser.is_group_flag( scenes = await interface.get_scenes()
# str(user_id), group_id platform = PlatformUtils.get_platform(bot)
# ): group_list = [s for s in scenes if s.is_group and s.id == group_id]
# await LevelUser.set_level(user_id, group_id, default_auth) if not group_list:
# if str(user_id) in bot.config.superusers: logger.warning(
# await LevelUser.set_level(str(user_id), group_id, 9) f"bot: {bot.self_id}group_id: {group_id},群组不存在,"
# join_time = datetime.strptime( "无法更新群成员信息..."
# time.strftime("%Y-%m-%d %H:%M:%S", )
# time.localtime(user_info["join_time"])), return "更新群组失败,群组不存在..."
# "%Y-%m-%d %H:%M:%S", members = await interface.get_members(SceneType.GROUP, group_list[0].id)
# ) db_user = await GroupInfoUser.filter(group_id=group_id).all()
# await GroupInfoUser.update_or_create( db_user_uid = [u.user_id for u in db_user]
# user_id=str(user_id), data_list = ([], [], [])
# group_id=group_id, exist_member_list = []
# defaults={ for member in members:
# "user_name": nickname, await cls.__handle_user(member, db_user, group_id, data_list, platform)
# "user_join_time": join_time.replace( exist_member_list.append(member.id)
# tzinfo=timezone(timedelta(hours=8)) if data_list[0]:
# ), await GroupInfoUser.bulk_create(data_list[0], 30)
# }, logger.debug(
# ) f"创建用户数据 {len(data_list[0])}",
# exist_member_list.append(str(user_id)) "更新群组成员信息",
# logger.debug("更新成功", "更新群组成员信息", target=group_id,
# session=user_id, group_id=group_id) )
# if delete_member_list := list( if data_list[1]:
# set(exist_member_list).difference( await GroupInfoUser.bulk_update(data_list[1], ["user_name"], 30)
# set(await GroupInfoUser.get_group_member_id_list(group_id)) logger.debug(
# ) f"更新户数据 {len(data_list[1])}",
# ): "更新群组成员信息",
# await GroupInfoUser.filter( target=group_id,
# user_id__in=delete_member_list, group_id=group_id )
# ).delete() if data_list[2]:
# logger.info(f"删除已退群用户", "更新群组成员信息", group_id=group_id) await GroupInfoUser.filter(id__in=data_list[2]).delete()
logger.debug(f"删除重复数据 Ids: {data_list[2]}", "更新群组成员信息")
if delete_member_list := [
uid for uid in db_user_uid if uid not in exist_member_list
]:
await GroupInfoUser.filter(
user_id__in=delete_member_list, group_id=group_id
).delete()
logger.info(
f"删除已退群用户 {len(delete_member_list)}",
"更新群组成员信息",
group_id=group_id,
platform="qq",
)
return "群组成员信息更新完成!"

View File

@ -7,10 +7,10 @@ import nonebot
from pydantic import BaseModel from pydantic import BaseModel
from nonebot.adapters import Bot from nonebot.adapters import Bot
from nonebot.utils import is_coroutine_callable from nonebot.utils import is_coroutine_callable
from nonebot_plugin_uninfo import get_interface
from nonebot.adapters.dodo import Bot as DodoBot from nonebot.adapters.dodo import Bot as DodoBot
from nonebot.adapters.onebot.v11 import Bot as v11Bot from nonebot.adapters.onebot.v11 import Bot as v11Bot
from nonebot.adapters.onebot.v12 import Bot as v12Bot from nonebot.adapters.onebot.v12 import Bot as v12Bot
from nonebot.adapters.discord import Bot as DiscordBot
from nonebot.adapters.kaiheila import Bot as KaiheilaBot from nonebot.adapters.kaiheila import Bot as KaiheilaBot
from nonebot_plugin_alconna.uniseg import Target, Receipt, UniMessage from nonebot_plugin_alconna.uniseg import Target, Receipt, UniMessage
@ -380,13 +380,11 @@ class PlatformUtils:
返回: 返回:
str | None: 平台 str | None: 平台
""" """
if isinstance(bot, v11Bot | v12Bot): if interface := get_interface(bot):
return "qq" info = interface.basic_info()
if isinstance(bot, DodoBot): platform = info["scope"].lower()
return "dodo" return "qq" if platform.startswith("qq") else platform
if isinstance(bot, KaiheilaBot): return "unknown"
return "kaiheila"
return "discord" if isinstance(bot, DiscordBot) else None
@classmethod @classmethod
async def get_group_list(cls, bot: Bot) -> tuple[list[GroupConsole], str]: async def get_group_list(cls, bot: Bot) -> tuple[list[GroupConsole], str]: