mirror of
https://github.com/zhenxun-org/zhenxun_bot.git
synced 2026-10-03 02:30:01 +08:00
数据库中所有user_qq改名以及user_id和group_id改为字符串
This commit is contained in:
@@ -9,6 +9,7 @@ from nonebot.typing import T_State
|
||||
from configs.config import Config
|
||||
from models.level_user import LevelUser
|
||||
from services.log import logger
|
||||
from utils.depends import GetConfig
|
||||
from utils.image_utils import text2image
|
||||
from utils.manager import group_manager
|
||||
from utils.message_builder import image
|
||||
@@ -89,7 +90,12 @@ async def _():
|
||||
|
||||
@add_sub.handle()
|
||||
@del_sub.handle()
|
||||
async def _(event: MessageEvent, state: T_State, arg: Message = CommandArg()):
|
||||
async def _(
|
||||
event: MessageEvent,
|
||||
state: T_State,
|
||||
arg: Message = CommandArg(),
|
||||
sub_level: Optional[int] = GetConfig(config="GROUP_BILIBILI_SUB_LEVEL"),
|
||||
):
|
||||
msg = arg.extract_plain_text().strip().split()
|
||||
if len(msg) < 2:
|
||||
await add_sub.finish("参数不完全,请查看订阅帮助...")
|
||||
@@ -99,10 +105,10 @@ async def _(event: MessageEvent, state: T_State, arg: Message = CommandArg()):
|
||||
if not await LevelUser.check_level(
|
||||
event.user_id,
|
||||
event.group_id,
|
||||
Config.get_config("bilibili_sub", "GROUP_BILIBILI_SUB_LEVEL"), # type: ignore
|
||||
sub_level, # type: ignore
|
||||
):
|
||||
await add_sub.finish(
|
||||
f"您的权限不足,群内订阅的需要 {Config.get_config('bilibili_sub', 'GROUP_BILIBILI_SUB_LEVEL')} 级权限..",
|
||||
f"您的权限不足,群内订阅的需要 {sub_level} 级权限..",
|
||||
at_sender=True,
|
||||
)
|
||||
sub_user = f"{event.user_id}:{event.group_id}"
|
||||
@@ -155,9 +161,10 @@ async def _(
|
||||
else:
|
||||
await add_sub.finish("参数错误,第一参数必须为:主播/up/番剧!")
|
||||
logger.info(
|
||||
f"(USER {event.user_id}, GROUP "
|
||||
f"{event.group_id if isinstance(event, GroupMessageEvent) else 'private'})"
|
||||
f" 添加订阅:{sub_type} -> {sub_user} -> {id_}"
|
||||
f"添加订阅:{sub_type} -> {sub_user} -> {id_}",
|
||||
"添加订阅",
|
||||
event.user_id,
|
||||
getattr(event, "group_id", None),
|
||||
)
|
||||
|
||||
|
||||
@@ -171,20 +178,27 @@ async def _(
|
||||
sub_user: str = ArgStr("sub_user"),
|
||||
):
|
||||
if sub_type in ["主播", "直播"]:
|
||||
result = await BilibiliSub.delete_bilibili_sub(int(id_), sub_user, "live")
|
||||
result = await BilibiliSub.delete_bilibili_sub(id_, sub_user, "live")
|
||||
elif sub_type.lower() in ["up", "用户"]:
|
||||
result = await BilibiliSub.delete_bilibili_sub(int(id_), sub_user, "up")
|
||||
result = await BilibiliSub.delete_bilibili_sub(id_, sub_user, "up")
|
||||
else:
|
||||
result = await BilibiliSub.delete_bilibili_sub(int(id_), sub_user)
|
||||
result = await BilibiliSub.delete_bilibili_sub(id_, sub_user)
|
||||
if result:
|
||||
await del_sub.send(f"删除订阅id:{id_} 成功...")
|
||||
logger.info(
|
||||
f"(USER {event.user_id}, GROUP "
|
||||
f"{event.group_id if isinstance(event, GroupMessageEvent) else 'private'})"
|
||||
f" 删除订阅 {id_}"
|
||||
f"删除订阅 {id_}",
|
||||
"删除订阅",
|
||||
event.user_id,
|
||||
getattr(event, "group_id", None),
|
||||
)
|
||||
else:
|
||||
await del_sub.send(f"删除订阅id:{id_} 失败...")
|
||||
logger.info(
|
||||
f"删除订阅 {id_} 失败",
|
||||
"删除订阅",
|
||||
event.user_id,
|
||||
getattr(event, "group_id", None),
|
||||
)
|
||||
|
||||
|
||||
@show_sub_info.handle()
|
||||
@@ -236,18 +250,18 @@ async def _():
|
||||
bot = get_bot()
|
||||
sub = None
|
||||
if bot:
|
||||
# try:
|
||||
await sub_manager.reload_sub_data()
|
||||
sub = await sub_manager.random_sub_data()
|
||||
if sub:
|
||||
logger.debug(f"Bilibili订阅开始检测:{sub.sub_id}")
|
||||
rst = await get_sub_status(sub.sub_id, sub.sub_type)
|
||||
await send_sub_msg(rst or "", sub, bot) # type: ignore
|
||||
if sub.sub_type == "live":
|
||||
rst = await get_sub_status(sub.sub_id, "up")
|
||||
try:
|
||||
logger.debug(f"Bilibili订阅开始检测:{sub.sub_id}")
|
||||
rst = await get_sub_status(sub.sub_id, sub.sub_type)
|
||||
await send_sub_msg(rst or "", sub, bot) # type: ignore
|
||||
# except Exception as e:
|
||||
# logger.error(f"B站订阅推送发生错误 sub_id:{sub.sub_id if sub else 0} {type(e)}:{e}")
|
||||
if sub.sub_type == "live":
|
||||
rst = await get_sub_status(sub.sub_id, "up")
|
||||
await send_sub_msg(rst or "", sub, bot) # type: ignore
|
||||
except Exception as e:
|
||||
logger.error(f"B站订阅推送发生错误 sub_id:{sub.sub_id}", e=e)
|
||||
|
||||
|
||||
async def send_sub_msg(rst: str, sub: BilibiliSub, bot: Bot):
|
||||
@@ -284,4 +298,4 @@ async def send_sub_msg(rst: str, sub: BilibiliSub, bot: Bot):
|
||||
else:
|
||||
await bot.send_private_msg(user_id=int(x), message=Message(rst))
|
||||
except Exception as e:
|
||||
logger.error(f"B站订阅推送发生错误 sub_id:{sub.sub_id} {type(e)}:{e}")
|
||||
logger.error(f"B站订阅推送发生错误 sub_id:{sub.sub_id}", e=e)
|
||||
|
||||
@@ -38,12 +38,16 @@ async def add_live_sub(live_id: str, sub_user: str) -> str:
|
||||
:return:
|
||||
"""
|
||||
try:
|
||||
if await BilibiliSub.exists(
|
||||
sub_type="live", sub_id=live_id, sub_users__contains=sub_user + ","
|
||||
):
|
||||
return "该订阅Id已存在..."
|
||||
try:
|
||||
"""bilibili_api.live库的LiveRoom类中get_room_info改为bilireq.live库的get_room_info_by_id方法"""
|
||||
live_info = await get_room_info_by_id(live_id)
|
||||
except ResponseCodeError:
|
||||
return f"未找到房间号Id:{live_id} 的信息,请检查Id是否正确"
|
||||
uid = live_info["uid"]
|
||||
uid = str(live_info["uid"])
|
||||
room_id = live_info["room_id"]
|
||||
short_id = live_info["short_id"]
|
||||
title = live_info["title"]
|
||||
@@ -56,7 +60,10 @@ async def add_live_sub(live_id: str, sub_user: str) -> str:
|
||||
live_short_id=short_id,
|
||||
live_status=live_status,
|
||||
):
|
||||
await _get_up_status(room_id)
|
||||
try:
|
||||
await _get_up_status(room_id)
|
||||
except Exception as e:
|
||||
logger.error(f"获取主播UP信息失败: {live_id} 错误", e=e)
|
||||
if data := await BilibiliSub.get_or_none(sub_id=room_id):
|
||||
uname = data.uname
|
||||
return (
|
||||
@@ -66,11 +73,9 @@ async def add_live_sub(live_id: str, sub_user: str) -> str:
|
||||
f"\tlive_id:{room_id}\n"
|
||||
f"\tuid:{uid}"
|
||||
)
|
||||
return "添加订阅失败..."
|
||||
else:
|
||||
return "添加订阅失败..."
|
||||
return "添加订阅失败..."
|
||||
except Exception as e:
|
||||
logger.error(f"订阅主播live_id:{live_id} 发生了错误 {type(e)}:{e}")
|
||||
logger.error(f"订阅主播live_id: {live_id} 错误", e=e)
|
||||
return "添加订阅失败..."
|
||||
|
||||
|
||||
@@ -80,7 +85,14 @@ async def add_up_sub(uid: str, sub_user: str) -> str:
|
||||
:param uid: UP uid
|
||||
:param sub_user: 订阅用户
|
||||
"""
|
||||
uname = uid
|
||||
dynamic_upload_time = 0
|
||||
latest_video_created = 0
|
||||
try:
|
||||
if await BilibiliSub.exists(
|
||||
sub_type="up", sub_id=uid, sub_users__contains=sub_user + ","
|
||||
):
|
||||
return "该订阅Id已存在..."
|
||||
try:
|
||||
"""bilibili_api.user库中User类的get_user_info改为bilireq.user库的get_user_info方法"""
|
||||
user_info = await get_user_card(uid)
|
||||
@@ -89,29 +101,26 @@ async def add_up_sub(uid: str, sub_user: str) -> str:
|
||||
uname = user_info["name"]
|
||||
"""bilibili_api.user库中User类的get_dynamics改为bilireq.dynamic库的get_user_dynamics方法"""
|
||||
dynamic_info = await dynamic.get_user_dynamics(int(uid))
|
||||
dynamic_upload_time = 0
|
||||
if dynamic_info.get("cards"):
|
||||
dynamic_upload_time = dynamic_info["cards"][0]["desc"]["timestamp"]
|
||||
"""bilibili_api.user库中User类的get_videos改为bilireq.user库的get_videos方法"""
|
||||
video_info = await get_videos(int(uid))
|
||||
latest_video_created = 0
|
||||
if video_info["list"].get("vlist"):
|
||||
latest_video_created = video_info["list"]["vlist"][0]["created"]
|
||||
if await BilibiliSub.sub_handle(
|
||||
uid,
|
||||
"up",
|
||||
sub_user,
|
||||
uid=int(uid),
|
||||
uname=uname,
|
||||
dynamic_upload_time=dynamic_upload_time,
|
||||
latest_video_created=latest_video_created,
|
||||
):
|
||||
return "已成功订阅UP:\n" f"\tname: {uname}\n" f"\tuid:{uid}"
|
||||
else:
|
||||
return "添加订阅失败..."
|
||||
except Exception as e:
|
||||
logger.error(f"订阅Up uid:{uid} 发生了错误 {type(e)}:{e}")
|
||||
return "添加订阅失败..."
|
||||
logger.error(f"订阅Up uid: {uid} 错误", e=e)
|
||||
if await BilibiliSub.sub_handle(
|
||||
uid,
|
||||
"up",
|
||||
sub_user,
|
||||
uid=uid,
|
||||
uname=uname,
|
||||
dynamic_upload_time=dynamic_upload_time,
|
||||
latest_video_created=latest_video_created,
|
||||
):
|
||||
return "已成功订阅UP:\n" f"\tname: {uname}\n" f"\tuid:{uid}"
|
||||
else:
|
||||
return "添加订阅失败..."
|
||||
|
||||
|
||||
async def add_season_sub(media_id: str, sub_user: str) -> str:
|
||||
@@ -121,6 +130,10 @@ async def add_season_sub(media_id: str, sub_user: str) -> str:
|
||||
:param sub_user: 订阅用户
|
||||
"""
|
||||
try:
|
||||
if await BilibiliSub.exists(
|
||||
sub_type="season", sub_id=media_id, sub_users__contains=sub_user + ","
|
||||
):
|
||||
return "该订阅Id已存在..."
|
||||
try:
|
||||
"""bilibili_api.bangumi库中get_meta改为bilireq.bangumi库的get_meta方法"""
|
||||
season_info = await get_meta(media_id)
|
||||
@@ -145,7 +158,7 @@ async def add_season_sub(media_id: str, sub_user: str) -> str:
|
||||
else:
|
||||
return "添加订阅失败..."
|
||||
except Exception as e:
|
||||
logger.error(f"订阅番剧 media_id:{media_id} 发生了错误 {type(e)}:{e}")
|
||||
logger.error(f"订阅番剧 media_id: {media_id} 错误", e=e)
|
||||
return "添加订阅失败..."
|
||||
|
||||
|
||||
@@ -155,7 +168,7 @@ async def delete_sub(sub_id: str, sub_user: str) -> str:
|
||||
:param sub_id: 订阅 id
|
||||
:param sub_user: 订阅用户 id # 7384933:private or 7384933:2342344(group)
|
||||
"""
|
||||
if await BilibiliSub.delete_bilibili_sub(int(sub_id), sub_user):
|
||||
if await BilibiliSub.delete_bilibili_sub(sub_id, sub_user):
|
||||
return f"已成功取消订阅:{sub_id}"
|
||||
else:
|
||||
return f"取消订阅:{sub_id} 失败,请检查是否订阅过该Id...."
|
||||
@@ -204,12 +217,11 @@ async def get_sub_status(id_: str, sub_type: str) -> Optional[str]:
|
||||
return await _get_up_status(id_)
|
||||
elif sub_type == "season":
|
||||
return await _get_season_status(id_)
|
||||
except ResponseCodeError as msg:
|
||||
logger.info(f"Id:{id_} 获取信息失败...{msg}")
|
||||
return None
|
||||
except ResponseCodeError as e:
|
||||
logger.error(f"Id:{id_} 获取信息失败...", e=e)
|
||||
# return f"Id:{id_} 获取信息失败...请检查订阅Id是否存在或稍后再试..."
|
||||
# except Exception as e:
|
||||
# logger.error(f"获取订阅状态发生预料之外的错误 id_:{id_} {type(e)}:{e}")
|
||||
except Exception as e:
|
||||
logger.error(f"获取订阅状态发生预料之外的错误 Id_:{id_}", e=e)
|
||||
# return "发生了预料之外的错误..请稍后再试或联系管理员....."
|
||||
|
||||
|
||||
@@ -250,7 +262,7 @@ async def _get_up_status(id_: str) -> Optional[str]:
|
||||
user_info = await get_user_card(_user.uid)
|
||||
uname = user_info["name"]
|
||||
"""bilibili_api.user库中User类的get_videos改为bilireq.user库的get_videos方法"""
|
||||
video_info = await get_videos(_user.uid)
|
||||
video_info = await get_videos(int(_user.uid))
|
||||
latest_video_created = 0
|
||||
video = None
|
||||
dividing_line = "\n-------------\n"
|
||||
@@ -308,7 +320,7 @@ async def _get_season_status(id_: str) -> Optional[str]:
|
||||
|
||||
|
||||
async def get_user_dynamic(
|
||||
uid: int, local_user: BilibiliSub
|
||||
uid: str, local_user: BilibiliSub
|
||||
) -> Tuple[Optional[MessageSegment], int, str]:
|
||||
"""
|
||||
获取用户动态
|
||||
@@ -317,7 +329,7 @@ async def get_user_dynamic(
|
||||
:return: 最新动态截图与时间
|
||||
"""
|
||||
"""bilibili_api.user库中User类的get_dynamics改为bilireq.dynamic库的get_user_dynamics方法"""
|
||||
dynamic_info = await dynamic.get_user_dynamics(uid)
|
||||
dynamic_info = await dynamic.get_user_dynamics(int(uid))
|
||||
if dynamic_info.get("cards"):
|
||||
dynamic_upload_time = dynamic_info["cards"][0]["desc"]["timestamp"]
|
||||
dynamic_id = dynamic_info["cards"][0]["desc"]["dynamic_id"]
|
||||
|
||||
@@ -21,7 +21,7 @@ class BilibiliSub(Model):
|
||||
"""直播短id"""
|
||||
live_status = fields.IntField(null=True)
|
||||
"""直播状态 0: 停播 1: 直播"""
|
||||
uid = fields.BigIntField(null=True)
|
||||
uid = fields.CharField(255, null=True)
|
||||
"""主播/UP UID"""
|
||||
uname = fields.CharField(255, null=True)
|
||||
"""主播/UP 名称"""
|
||||
@@ -53,7 +53,7 @@ class BilibiliSub(Model):
|
||||
live_short_id: Optional[str] = None,
|
||||
live_status: Optional[int] = None,
|
||||
dynamic_upload_time: int = 0,
|
||||
uid: Optional[int] = None,
|
||||
uid: Optional[str] = None,
|
||||
uname: Optional[str] = None,
|
||||
latest_video_created: Optional[int] = None,
|
||||
season_name: Optional[str] = None,
|
||||
@@ -80,59 +80,63 @@ class BilibiliSub(Model):
|
||||
:param season_update_time: 番剧更新时间
|
||||
"""
|
||||
sub_id = str(sub_id)
|
||||
# try:
|
||||
data = {
|
||||
"sub_type": sub_type,
|
||||
"sub_user": sub_user,
|
||||
"live_short_id": live_short_id,
|
||||
"live_status": live_status,
|
||||
"dynamic_upload_time": dynamic_upload_time,
|
||||
"uid": uid,
|
||||
"uname": uname,
|
||||
"latest_video_created": latest_video_created,
|
||||
"season_name": season_name,
|
||||
"season_id": season_id,
|
||||
"season_current_episode": season_current_episode,
|
||||
"season_update_time": season_update_time,
|
||||
}
|
||||
if sub_user:
|
||||
sub_user = sub_user if sub_user[-1] == "," else f"{sub_user},"
|
||||
sub = None
|
||||
if sub_type:
|
||||
sub = await cls.get_or_none(sub_id=sub_id, sub_type=sub_type)
|
||||
else:
|
||||
sub = await cls.get_or_none(sub_id=sub_id)
|
||||
if sub:
|
||||
sub_users = sub.sub_users + sub_user
|
||||
data["sub_type"] = sub_type or sub.sub_type
|
||||
data["sub_users"] = sub_users
|
||||
data["live_short_id"] = live_short_id or sub.live_short_id
|
||||
data["live_status"] = (
|
||||
live_status if live_status is not None else sub.live_status
|
||||
)
|
||||
data["dynamic_upload_time"] = dynamic_upload_time or sub.dynamic_upload_time
|
||||
data["uid"] = uid or sub.uid
|
||||
data["uname"] = uname or sub.uname
|
||||
data["latest_video_created"] = (
|
||||
latest_video_created or sub.latest_video_created
|
||||
)
|
||||
data["season_name"] = season_name or sub.season_name
|
||||
data["season_id"] = season_id or sub.season_id
|
||||
data["season_current_episode"] = (
|
||||
season_current_episode or sub.season_current_episode
|
||||
)
|
||||
data["season_update_time"] = season_update_time or sub.season_update_time
|
||||
else:
|
||||
await cls.create(sub_id=sub_id, sub_type=sub_type, sub_users=sub_user)
|
||||
await cls.update_or_create(sub_id=sub_id, defaults=data)
|
||||
return True
|
||||
# except Exception as e:
|
||||
# logger.info(f"bilibili_sub 添加订阅错误 {type(e)}: {e}")
|
||||
# return False
|
||||
try:
|
||||
data = {
|
||||
"sub_type": sub_type,
|
||||
"sub_user": sub_user,
|
||||
"live_short_id": live_short_id,
|
||||
"live_status": live_status,
|
||||
"dynamic_upload_time": dynamic_upload_time,
|
||||
"uid": uid,
|
||||
"uname": uname,
|
||||
"latest_video_created": latest_video_created,
|
||||
"season_name": season_name,
|
||||
"season_id": season_id,
|
||||
"season_current_episode": season_current_episode,
|
||||
"season_update_time": season_update_time,
|
||||
}
|
||||
if sub_user:
|
||||
sub_user = sub_user if sub_user[-1] == "," else f"{sub_user},"
|
||||
sub = None
|
||||
if sub_type:
|
||||
sub = await cls.get_or_none(sub_id=sub_id, sub_type=sub_type)
|
||||
else:
|
||||
sub = await cls.get_or_none(sub_id=sub_id)
|
||||
if sub:
|
||||
sub_users = sub.sub_users + sub_user
|
||||
data["sub_type"] = sub_type or sub.sub_type
|
||||
data["sub_users"] = sub_users
|
||||
data["live_short_id"] = live_short_id or sub.live_short_id
|
||||
data["live_status"] = (
|
||||
live_status if live_status is not None else sub.live_status
|
||||
)
|
||||
data["dynamic_upload_time"] = (
|
||||
dynamic_upload_time or sub.dynamic_upload_time
|
||||
)
|
||||
data["uid"] = uid or sub.uid
|
||||
data["uname"] = uname or sub.uname
|
||||
data["latest_video_created"] = (
|
||||
latest_video_created or sub.latest_video_created
|
||||
)
|
||||
data["season_name"] = season_name or sub.season_name
|
||||
data["season_id"] = season_id or sub.season_id
|
||||
data["season_current_episode"] = (
|
||||
season_current_episode or sub.season_current_episode
|
||||
)
|
||||
data["season_update_time"] = (
|
||||
season_update_time or sub.season_update_time
|
||||
)
|
||||
else:
|
||||
await cls.create(sub_id=sub_id, sub_type=sub_type, sub_users=sub_user)
|
||||
await cls.update_or_create(sub_id=sub_id, defaults=data)
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.error(f"添加订阅 Id: {sub_id} 错误", e=e)
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
async def delete_bilibili_sub(
|
||||
cls, sub_id: int, sub_user: str, sub_type: Optional[str] = None
|
||||
cls, sub_id: str, sub_user: str, sub_type: Optional[str] = None
|
||||
) -> bool:
|
||||
"""
|
||||
说明:
|
||||
@@ -142,24 +146,34 @@ class BilibiliSub(Model):
|
||||
:param sub_user: 删除此条目的用户
|
||||
"""
|
||||
try:
|
||||
group_id = None
|
||||
contains_str = sub_user
|
||||
if ":" in sub_user:
|
||||
group_id = sub_user.split(":")[1]
|
||||
contains_str = f":{group_id}"
|
||||
if sub_type:
|
||||
sub = await cls.filter(
|
||||
sub_id=sub_id, sub_type=sub_type, sub_users__contains=sub_user
|
||||
).first()
|
||||
sub = await cls.get_or_none(
|
||||
sub_id=sub_id, sub_type=sub_type, sub_users__contains=contains_str
|
||||
)
|
||||
else:
|
||||
sub = await cls.filter(
|
||||
sub_id=sub_id, sub_users__contains=sub_user
|
||||
).first()
|
||||
sub = await cls.get_or_none(
|
||||
sub_id=sub_id, sub_users__contains=contains_str
|
||||
)
|
||||
if not sub:
|
||||
return False
|
||||
sub.sub_users = sub.sub_users.replace(f"{sub_user},", "")
|
||||
if group_id:
|
||||
sub.sub_users = ",".join(
|
||||
[s for s in sub.sub_users.split(",") if f":{group_id}" not in s]
|
||||
)
|
||||
else:
|
||||
sub.sub_users = sub.sub_users.replace(f"{sub_user},", "")
|
||||
if sub.sub_users.strip():
|
||||
await sub.save(update_fields=["sub_users"])
|
||||
else:
|
||||
await sub.delete()
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.info(f"bilibili_sub 删除订阅错误 {type(e)}: {e}")
|
||||
logger.error(f"bilibili_sub 删除订阅错误", target=sub_id, e=e)
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
@@ -189,4 +203,5 @@ class BilibiliSub(Model):
|
||||
"ALTER TABLE bilibili_sub ALTER COLUMN season_update_time TYPE timestamp with time zone USING season_update_time::timestamp with time zone;",
|
||||
"alter table bilibili_sub alter COLUMN sub_id type varchar(255);", # 将sub_id字段改为字符串
|
||||
"alter table bilibili_sub alter COLUMN live_short_id type varchar(255);", # 将live_short_id字段改为字符串
|
||||
"alter table bilibili_sub alter COLUMN uid type varchar(255);", # 将live_short_id字段改为字符串
|
||||
]
|
||||
|
||||
@@ -96,7 +96,7 @@ Config.add_plugin_config(
|
||||
"BAN_3_DURATION",
|
||||
7,
|
||||
help_="Union[int, List[int, int]]Ban时长(天),三级惩罚,可以为指定数字或指定列表区间(随机),例如 [7, 30]",
|
||||
default_value=360,
|
||||
default_value=7,
|
||||
type=int,
|
||||
)
|
||||
|
||||
@@ -171,8 +171,8 @@ async def _(
|
||||
and event.is_tome()
|
||||
and not msg.startswith("原神绑定")
|
||||
):
|
||||
# if str(event.user_id) not in bot.config.superusers:
|
||||
# return logger.debug(f"超级用户跳过黑名单词汇检查 Message: {msg}", target=event.user_id)
|
||||
if str(event.user_id) in bot.config.superusers:
|
||||
return logger.debug(f"超级用户跳过黑名单词汇检查 Message: {msg}", target=event.user_id)
|
||||
if (
|
||||
event.is_tome()
|
||||
and matcher.plugin_name == "black_word"
|
||||
@@ -184,8 +184,8 @@ async def _(
|
||||
and group_manager.get_group_level(event.group_id) < 0
|
||||
):
|
||||
return
|
||||
user_id = event.user_id
|
||||
group_id = event.group_id if isinstance(event, GroupMessageEvent) else None
|
||||
user_id = str(event.user_id)
|
||||
group_id = str(event.group_id) if isinstance(event, GroupMessageEvent) else None
|
||||
msg = get_message_text(event.json())
|
||||
if await black_word_manager.check(
|
||||
user_id, group_id, msg
|
||||
@@ -206,8 +206,8 @@ async def _(bot: Bot, reg_group: Tuple[Any, ...] = RegexGroup()):
|
||||
await show_black.finish("日期格式错误,需要:年-月-日")
|
||||
pic = await show_black_text_image(
|
||||
bot,
|
||||
int(user_id.split(":")[1]) if user_id else None,
|
||||
int(group_id.split(":")[1]) if group_id else None,
|
||||
user_id.split(":")[1] if user_id else None,
|
||||
group_id.split(":")[1] if group_id else None,
|
||||
date,
|
||||
date_type,
|
||||
)
|
||||
@@ -266,11 +266,13 @@ async def _(event: MessageEvent, arg: Message = CommandArg()):
|
||||
or not is_number(msg[2])
|
||||
):
|
||||
await set_punish.finish("参数错误,请查看帮助...", at_sender=True)
|
||||
uid = int(msg[0])
|
||||
uid = msg[0]
|
||||
id_ = int(msg[1])
|
||||
punish_level = int(msg[2])
|
||||
rst = await set_user_punish(uid, id_, punish_level)
|
||||
await set_punish.send(rst)
|
||||
logger.info(
|
||||
f"USER {event.user_id} 设置惩罚 uid:{uid} id_:{id_} punish_level:{punish_level} --> {rst}"
|
||||
f"设置惩罚 uid:{uid} id_:{id_} punish_level:{punish_level} --> {rst}",
|
||||
"设置惩罚",
|
||||
event.user_id,
|
||||
)
|
||||
|
||||
@@ -1,16 +1,19 @@
|
||||
from nonebot.adapters.onebot.v11 import Bot
|
||||
from utils.image_utils import BuildImage, text2image
|
||||
from services.log import logger
|
||||
from typing import Optional
|
||||
from datetime import datetime
|
||||
from typing import Optional
|
||||
|
||||
from nonebot.adapters.onebot.v11 import Bot
|
||||
|
||||
from services.log import logger
|
||||
from utils.image_utils import BuildImage, text2image
|
||||
|
||||
from .model import BlackWord
|
||||
from .utils import _get_punish, Config
|
||||
from .utils import Config, _get_punish
|
||||
|
||||
|
||||
async def show_black_text_image(
|
||||
bot: Bot,
|
||||
user: Optional[int],
|
||||
group_id: Optional[int],
|
||||
user_id: Optional[str],
|
||||
group_id: Optional[str],
|
||||
date: Optional[datetime],
|
||||
data_type: str = "=",
|
||||
) -> BuildImage:
|
||||
@@ -23,7 +26,7 @@ async def show_black_text_image(
|
||||
:param data_type: 日期搜索类型
|
||||
:return:
|
||||
"""
|
||||
data = await BlackWord.get_black_data(user, group_id, date, data_type)
|
||||
data = await BlackWord.get_black_data(user_id, group_id, date, data_type)
|
||||
A = BuildImage(0, 0, color="#f9f6f2", font_size=20)
|
||||
image_list = []
|
||||
friend_str = await bot.get_friend_list()
|
||||
@@ -41,21 +44,21 @@ async def show_black_text_image(
|
||||
if x.group_id:
|
||||
user_name = (
|
||||
await bot.get_group_member_info(
|
||||
group_id=x.group_id, user_id=x.user_qq
|
||||
group_id=int(x.group_id), user_id=int(x.user_id)
|
||||
)
|
||||
)["card"]
|
||||
else:
|
||||
user_name = [
|
||||
u["nickname"] for u in friend_str if u["user_id"] == x.user_qq
|
||||
u["nickname"] for u in friend_str if u["user_id"] == int(x.user_id)
|
||||
][0]
|
||||
except Exception as e:
|
||||
logger.warning(
|
||||
f"show_black_text_image 获取 USER {x.user_qq} user_name 失败 {type(e)}:{e}"
|
||||
f"show_black_text_image 获取 USER {x.user_id} user_name 失败", e=e
|
||||
)
|
||||
user_name = x.user_qq
|
||||
user_name = x.user_id
|
||||
id_str += f"{i}\n"
|
||||
uname_str += f"{user_name}\n"
|
||||
uid_str += f"{x.user_qq}\n"
|
||||
uid_str += f"{x.user_id}\n"
|
||||
gid_str += f"{x.group_id}\n"
|
||||
plant_text = " ".join(x.plant_text.split("\n"))
|
||||
if A.getsize(plant_text)[0] > 200:
|
||||
@@ -97,7 +100,7 @@ async def show_black_text_image(
|
||||
return A
|
||||
|
||||
|
||||
async def set_user_punish(user_id: int, id_: int, punish_level: int) -> str:
|
||||
async def set_user_punish(user_id: str, id_: int, punish_level: int) -> str:
|
||||
"""
|
||||
设置惩罚
|
||||
:param user_id: 用户id
|
||||
|
||||
+28
-21
@@ -7,13 +7,12 @@ from services.db_context import Model
|
||||
|
||||
|
||||
class BlackWord(Model):
|
||||
# __tablename__ = "black_word"
|
||||
|
||||
id = fields.IntField(pk=True, generated=True, auto_increment=True)
|
||||
"""自增id"""
|
||||
user_qq = fields.BigIntField()
|
||||
user_id = fields.CharField(255)
|
||||
"""用户id"""
|
||||
group_id = fields.BigIntField(null=True)
|
||||
group_id = fields.CharField(255, null=True)
|
||||
"""群聊id"""
|
||||
plant_text = fields.TextField()
|
||||
"""检测文本"""
|
||||
@@ -33,7 +32,7 @@ class BlackWord(Model):
|
||||
@classmethod
|
||||
async def set_user_punish(
|
||||
cls,
|
||||
user_qq: int,
|
||||
user_id: str,
|
||||
punish: str,
|
||||
black_word: Optional[str] = None,
|
||||
id_: Optional[int] = None,
|
||||
@@ -42,22 +41,22 @@ class BlackWord(Model):
|
||||
说明:
|
||||
设置处罚
|
||||
参数:
|
||||
:param user_qq: 用户id
|
||||
:param user_id: 用户id
|
||||
:param punish: 处罚
|
||||
:param black_word: 黑名单词汇
|
||||
:param id_: 记录下标
|
||||
"""
|
||||
user = None
|
||||
if (not black_word and not id_) or not punish:
|
||||
if (not black_word and id_ is None) or not punish:
|
||||
return False
|
||||
if black_word:
|
||||
user = (
|
||||
await cls.filter(user_qq=user_qq, black_word=black_word)
|
||||
await cls.filter(user_id=user_id, black_word=black_word, punish="")
|
||||
.order_by("id")
|
||||
.first()
|
||||
)
|
||||
elif id_:
|
||||
user_list = await cls.filter(user_qq=user_qq).order_by("id").all()
|
||||
elif id_ is not None:
|
||||
user_list = await cls.filter(user_id=user_id).order_by("id").all()
|
||||
if len(user_list) == 0 or (id_ < 0 or id_ > len(user_list)):
|
||||
return False
|
||||
user = user_list[id_]
|
||||
@@ -69,18 +68,18 @@ class BlackWord(Model):
|
||||
|
||||
@classmethod
|
||||
async def get_user_count(
|
||||
cls, user_qq: int, days: int = 7, punish_level: Optional[int] = None
|
||||
cls, user_id: str, days: int = 7, punish_level: Optional[int] = None
|
||||
) -> int:
|
||||
"""
|
||||
说明:
|
||||
获取用户规定周期内的犯事次数
|
||||
参数:
|
||||
:param user_qq: 用户qq
|
||||
:param user_id: 用户id
|
||||
:param days: 周期天数
|
||||
:param punish_level: 惩罚等级
|
||||
"""
|
||||
query = cls.filter(
|
||||
user_qq=user_qq,
|
||||
user_id=user_id,
|
||||
create_time__gte=datetime.now() - timedelta(days=days),
|
||||
punish_level__not_in=[-1],
|
||||
)
|
||||
@@ -89,17 +88,17 @@ class BlackWord(Model):
|
||||
return await query.count()
|
||||
|
||||
@classmethod
|
||||
async def get_user_punish_level(cls, user_qq: int, days: int = 7) -> Optional[int]:
|
||||
async def get_user_punish_level(cls, user_id: str, days: int = 7) -> Optional[int]:
|
||||
"""
|
||||
说明:
|
||||
获取用户最近一次的惩罚记录等级
|
||||
参数:
|
||||
:param user_qq: 用户qq
|
||||
:param user_id: 用户id
|
||||
:param days: 周期天数
|
||||
"""
|
||||
if (
|
||||
user := await cls.filter(
|
||||
user_qq=user_qq,
|
||||
user_id=user_id,
|
||||
create_time__gte=datetime.now() - timedelta(days=days),
|
||||
)
|
||||
.order_by("id")
|
||||
@@ -111,8 +110,8 @@ class BlackWord(Model):
|
||||
@classmethod
|
||||
async def get_black_data(
|
||||
cls,
|
||||
user_qq: Optional[int],
|
||||
group_id: Optional[int],
|
||||
user_id: Optional[str],
|
||||
group_id: Optional[str],
|
||||
date: Optional[datetime],
|
||||
date_type: str = "=",
|
||||
) -> List["BlackWord"]:
|
||||
@@ -120,14 +119,14 @@ class BlackWord(Model):
|
||||
说明:
|
||||
通过指定条件查询数据
|
||||
参数:
|
||||
:param user_qq: 用户qq
|
||||
:param user_id: 用户id
|
||||
:param group_id: 群号
|
||||
:param date: 日期
|
||||
:param date_type: 日期查询类型
|
||||
"""
|
||||
query = cls
|
||||
if user_qq:
|
||||
query = query.filter(user_qq=user_qq)
|
||||
if user_id:
|
||||
query = query.filter(user_id=user_id)
|
||||
if group_id:
|
||||
query = query.filter(group_id=group_id)
|
||||
if date:
|
||||
@@ -139,4 +138,12 @@ class BlackWord(Model):
|
||||
query = query.filter(create_time__gte=date)
|
||||
elif date_type == "<":
|
||||
query = query.filter(create_time__lte=date)
|
||||
return await query.order_by("id").all()
|
||||
return await query.all().order_by("id") # type: ignore
|
||||
|
||||
@classmethod
|
||||
async def _run_script(cls):
|
||||
return [
|
||||
"ALTER TABLE black_word RENAME COLUMN user_qq TO user_id;", # 将user_qq改为user_id
|
||||
"ALTER TABLE black_word ALTER COLUMN user_id TYPE character varying(255);",
|
||||
"ALTER TABLE black_word ALTER COLUMN group_id TYPE character varying(255);",
|
||||
]
|
||||
|
||||
+30
-23
@@ -83,7 +83,7 @@ class BlackWordManager:
|
||||
)
|
||||
|
||||
async def check(
|
||||
self, user_id: int, group_id: Optional[int], message: str
|
||||
self, user_id: str, group_id: Optional[str], message: str
|
||||
) -> Optional[Union[str, bool]]:
|
||||
"""
|
||||
检查是否包含黑名单词汇
|
||||
@@ -91,6 +91,7 @@ class BlackWordManager:
|
||||
:param group_id: 群号
|
||||
:param message: 消息
|
||||
"""
|
||||
logger.debug(f"检查文本是否含有黑名单词汇: {message}", "敏感词检测", user_id, group_id)
|
||||
if data := self._check(message):
|
||||
if data[0]:
|
||||
await _add_user_black_word(
|
||||
@@ -117,7 +118,7 @@ class BlackWordManager:
|
||||
for x in [self._word_list, self._py_list]:
|
||||
for level in x:
|
||||
if message in x[level] or py_msg in x[level]:
|
||||
return message if message in x[level] else py_msg, level
|
||||
return message if message in x[level] else py_msg, int(level)
|
||||
# 模糊匹配
|
||||
for x in [self._word_list, self._py_list]:
|
||||
for level in x:
|
||||
@@ -128,8 +129,8 @@ class BlackWordManager:
|
||||
|
||||
|
||||
async def _add_user_black_word(
|
||||
user_id: int,
|
||||
group_id: Optional[int],
|
||||
user_id: str,
|
||||
group_id: Optional[str],
|
||||
black_word: str,
|
||||
message: str,
|
||||
punish_level: int,
|
||||
@@ -144,13 +145,17 @@ async def _add_user_black_word(
|
||||
"""
|
||||
cycle_days = Config.get_config("black_word", "CYCLE_DAYS") or 7
|
||||
user_count = await BlackWord.get_user_count(user_id, cycle_days, punish_level)
|
||||
add_punish_level_to_count = Config.get_config(
|
||||
"black_word", "ADD_PUNISH_LEVEL_TO_COUNT"
|
||||
)
|
||||
# 周期内超过次数直接提升惩罚
|
||||
if Config.get_config(
|
||||
"black_word", "AUTO_ADD_PUNISH_LEVEL"
|
||||
) and user_count > Config.get_config("black_word", "ADD_PUNISH_LEVEL_TO_COUNT"):
|
||||
if (
|
||||
Config.get_config("black_word", "AUTO_ADD_PUNISH_LEVEL")
|
||||
and add_punish_level_to_count
|
||||
):
|
||||
punish_level -= 1
|
||||
await BlackWord.create(
|
||||
user_qq=user_id,
|
||||
user_id=user_id,
|
||||
group_id=group_id,
|
||||
plant_text=message,
|
||||
black_word=black_word,
|
||||
@@ -165,7 +170,7 @@ async def _add_user_black_word(
|
||||
|
||||
|
||||
async def _punish_handle(
|
||||
user_id: int, group_id: Optional[int], punish_level: int, black_word: str
|
||||
user_id: str, group_id: Optional[str], punish_level: int, black_word: str
|
||||
):
|
||||
"""
|
||||
惩罚措施,级别越低惩罚越严
|
||||
@@ -218,7 +223,7 @@ async def _punish_handle(
|
||||
|
||||
|
||||
async def _get_punish(
|
||||
id_: int, user_id: int, group_id: Optional[int] = None
|
||||
id_: int, user_id: str, group_id: Optional[str] = None
|
||||
) -> Optional[Union[int, str]]:
|
||||
"""
|
||||
通过id_获取惩罚
|
||||
@@ -230,12 +235,12 @@ async def _get_punish(
|
||||
# 忽略的群聊
|
||||
# _ignore_group = Config.get_config("black_word", "IGNORE_GROUP")
|
||||
# 处罚 id 4 ban 时间:int,List[int]
|
||||
ban_3_duration = Config.get_config("black_word", "BAN_3_DURATION")
|
||||
ban_3_duration = Config.get_config("black_word", "BAN_3_DURATION") or 7
|
||||
# 处罚 id 4 ban 时间:int,List[int]
|
||||
ban_4_duration = Config.get_config("black_word", "BAN_4_DURATION")
|
||||
ban_4_duration = Config.get_config("black_word", "BAN_4_DURATION") or 360
|
||||
# 口头警告内容
|
||||
warning_result = Config.get_config("black_word", "WARNING_RESULT")
|
||||
if user := await GroupInfoUser.get_or_none(user_id=str(user_id), group_id=str(group_id)):
|
||||
if user := await GroupInfoUser.get_or_none(user_id=user_id, group_id=group_id):
|
||||
uname = user.user_name
|
||||
else:
|
||||
uname = user_id
|
||||
@@ -285,28 +290,30 @@ async def _get_punish(
|
||||
# 口头警告
|
||||
elif id_ == 5:
|
||||
if group_id:
|
||||
await bot.send_group_msg(group_id=group_id, message=warning_result)
|
||||
await bot.send_group_msg(group_id=int(group_id), message=warning_result)
|
||||
else:
|
||||
await bot.send_private_msg(user_id=user_id, message=warning_result)
|
||||
await bot.send_private_msg(user_id=int(user_id), message=warning_result)
|
||||
logger.info(f"BlackWord 口头警告 USER {user_id}")
|
||||
return warning_result
|
||||
return None
|
||||
|
||||
|
||||
async def send_msg(user_id: int, group_id: Optional[int], message: str):
|
||||
async def send_msg(
|
||||
user_id: Union[str, int], group_id: Optional[Union[str, int]], message: str
|
||||
):
|
||||
"""
|
||||
发送消息
|
||||
:param user_id: user_id
|
||||
:param group_id: group_id
|
||||
:param message: message
|
||||
"""
|
||||
bot = get_bot()
|
||||
if not user_id:
|
||||
user_id = int(list(bot.config.superusers)[0])
|
||||
if group_id:
|
||||
await bot.send_group_msg(group_id=group_id, message=message)
|
||||
else:
|
||||
await bot.send_private_msg(user_id=user_id, message=message)
|
||||
if bot := get_bot():
|
||||
if not user_id:
|
||||
user_id = list(bot.config.superusers)[0]
|
||||
if group_id:
|
||||
await bot.send_group_msg(group_id=int(group_id), message=message)
|
||||
else:
|
||||
await bot.send_private_msg(user_id=int(user_id), message=message)
|
||||
|
||||
|
||||
async def check_text(text: str) -> bool:
|
||||
|
||||
@@ -3,7 +3,7 @@ from bs4 import BeautifulSoup
|
||||
from configs.config import Config
|
||||
from utils.http_utils import AsyncHttpx
|
||||
|
||||
url = "http://www.eclzz.love"
|
||||
url = "http://www.eclzz.ink"
|
||||
|
||||
|
||||
async def get_bt_info(keyword: str, page: int):
|
||||
@@ -17,7 +17,7 @@ async def get_bt_info(keyword: str, page: int):
|
||||
return
|
||||
soup = BeautifulSoup(text, "lxml")
|
||||
item_lst = soup.find_all("div", {"class": "search-item"})
|
||||
bt_max_num = Config.get_config("bt", "BT_MAX_NUM")
|
||||
bt_max_num = Config.get_config("bt", "BT_MAX_NUM") or 10
|
||||
bt_max_num = bt_max_num if bt_max_num < len(item_lst) else len(item_lst)
|
||||
for item in item_lst[:bt_max_num]:
|
||||
divs = item.find_all("div")
|
||||
|
||||
@@ -13,7 +13,7 @@ class Genshin(Model):
|
||||
|
||||
id = fields.IntField(pk=True, generated=True, auto_increment=True)
|
||||
"""自增id"""
|
||||
user_qq = fields.BigIntField()
|
||||
user_id = fields.CharField(255)
|
||||
"""用户id"""
|
||||
uid = fields.BigIntField()
|
||||
"""uid"""
|
||||
@@ -43,7 +43,7 @@ class Genshin(Model):
|
||||
class Meta:
|
||||
table = "genshin"
|
||||
table_description = "原神数据表"
|
||||
unique_together = ("user_qq", "uid")
|
||||
unique_together = ("user_id", "uid")
|
||||
|
||||
@classmethod
|
||||
async def random_sign_time(cls, uid: int) -> Optional[datetime]:
|
||||
@@ -103,4 +103,6 @@ class Genshin(Model):
|
||||
"ALTER TABLE genshin ADD login_ticket VARCHAR(255) DEFAULT '';",
|
||||
"ALTER TABLE genshin ADD stuid VARCHAR(255) DEFAULT '';",
|
||||
"ALTER TABLE genshin ADD stoken VARCHAR(255) DEFAULT '';",
|
||||
"ALTER TABLE genshin RENAME COLUMN user_qq TO user_id;", # 将user_qq改为user_id
|
||||
"ALTER TABLE genshin ALTER COLUMN user_id TYPE character varying(255);",
|
||||
]
|
||||
|
||||
@@ -55,7 +55,7 @@ bbs_Cookie_url2 = (
|
||||
@bind.handle()
|
||||
async def _(event: MessageEvent, cmd: str = OneCommand(), arg: Message = CommandArg()):
|
||||
msg = arg.extract_plain_text().strip()
|
||||
user = await Genshin.get_or_none(user_qq=event.user_id)
|
||||
user = await Genshin.get_or_none(user_id=str(event.user_id))
|
||||
if cmd in ["原神绑定uid", "原神绑定米游社id"]:
|
||||
if not is_number(msg):
|
||||
await bind.finish("uid/id必须为纯数字!", at_senders=True)
|
||||
@@ -63,9 +63,9 @@ async def _(event: MessageEvent, cmd: str = OneCommand(), arg: Message = Command
|
||||
if cmd == "原神绑定uid":
|
||||
if user:
|
||||
await bind.finish(f"您已绑定过uid:{user.uid},如果希望更换uid,请先发送原神解绑")
|
||||
if await Genshin.get_or_none(user_qq=event.user_id, uid=msg):
|
||||
if await Genshin.get_or_none(user_id=str(event.user_id), uid=msg):
|
||||
await bind.finish("添加失败,该uid可能已存在...")
|
||||
user = await Genshin.create(user_qq=event.user_id, uid=msg)
|
||||
user = await Genshin.create(user_id=str(event.user_id), uid=msg)
|
||||
_x = f"已成功添加原神uid:{msg}"
|
||||
elif cmd == "原神绑定米游社id":
|
||||
if not user:
|
||||
@@ -144,7 +144,7 @@ async def _(event: MessageEvent, cmd: str = OneCommand(), arg: Message = Command
|
||||
|
||||
@unbind.handle()
|
||||
async def _(event: MessageEvent):
|
||||
await Genshin.filter(user_qq=event.user_id).delete()
|
||||
await Genshin.filter(user_id=str(event.user_id)).delete()
|
||||
await unbind.send("用户数据删除成功...")
|
||||
logger.info(
|
||||
f"(USER {event.user_id}, GROUP "
|
||||
|
||||
@@ -43,7 +43,7 @@ genshin_matcher = on_command(
|
||||
|
||||
@genshin_matcher.handle()
|
||||
async def _(event: MessageEvent, cmd: str = OneCommand()):
|
||||
user = await Genshin.get_or_none(user_qq=event.user_id)
|
||||
user = await Genshin.get_or_none(user_id=str(event.user_id))
|
||||
if not user:
|
||||
await genshin_matcher.finish("请先绑定user.uid...")
|
||||
if cmd == "查看我的cookie":
|
||||
|
||||
@@ -31,11 +31,11 @@ async def _():
|
||||
_sign,
|
||||
"date",
|
||||
run_date=date.replace(microsecond=0),
|
||||
id=f"genshin_auto_sign_{u.uid}_{u.user_qq}_0",
|
||||
args=[u.user_qq, u.uid, 0],
|
||||
id=f"genshin_auto_sign_{u.uid}_{u.user_id}_0",
|
||||
args=[u.user_id, u.uid, 0],
|
||||
)
|
||||
logger.info(
|
||||
f"genshin_sign add_job:USER:{u.user_qq} UID:{u.uid} "
|
||||
f"genshin_sign add_job:USER:{u.user_id} UID:{u.uid} "
|
||||
f"{date} 原神自动签到"
|
||||
)
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ async def _(event: MessageEvent, cmd: Tuple[str, ...] = Command()):
|
||||
|
||||
|
||||
async def mihoyobbs_sign(user_id):
|
||||
user = await Genshin.get_or_none(user_qq=user_id)
|
||||
user = await Genshin.get_or_none(user_id=str(user_id))
|
||||
if not user or not user.uid or not user.cookie:
|
||||
await mihoyobbs_matcher.finish("请先绑定uid和cookie!", at_sender=True)
|
||||
bbs = mihoyobbs.Mihoyobbs(stuid=user.stuid, stoken=user.stoken, cookie=user.cookie)
|
||||
|
||||
@@ -35,7 +35,7 @@ query_memo_matcher = on_command(
|
||||
|
||||
@query_memo_matcher.handle()
|
||||
async def _(event: MessageEvent):
|
||||
user = await Genshin.get_or_none(user_qq=event.user_id)
|
||||
user = await Genshin.get_or_none(user_id=str(event.user_id))
|
||||
if not user or not user.uid or not user.cookie:
|
||||
await query_memo_matcher.finish("请先绑定uid和cookie!")
|
||||
if isinstance(event, GroupMessageEvent):
|
||||
|
||||
@@ -44,7 +44,7 @@ async def _(event: MessageEvent, arg: Message = CommandArg()):
|
||||
await query_role_info_matcher.finish("查询uid必须为数字!")
|
||||
msg = int(msg)
|
||||
uid = None
|
||||
user = await Genshin.get_or_none(user_qq=event.user_id)
|
||||
user = await Genshin.get_or_none(user_id=str(event.user_id))
|
||||
if not msg and user:
|
||||
uid = user.uid
|
||||
else:
|
||||
|
||||
@@ -52,7 +52,7 @@ resin_remind = on_command("开原神树脂提醒", aliases={"关原神树脂提
|
||||
|
||||
@resin_remind.handle()
|
||||
async def _(event: MessageEvent, cmd: str = OneCommand()):
|
||||
user = await Genshin.get_or_none(user_qq=event.user_id)
|
||||
user = await Genshin.get_or_none(user_id=str(event.user_id))
|
||||
if not user or not user.uid or not user.cookie:
|
||||
await resin_remind.finish("请先绑定uid和cookie!")
|
||||
try:
|
||||
|
||||
@@ -88,35 +88,27 @@ async def _():
|
||||
if u.resin_recovery_time and u.resin_recovery_time > datetime.now(
|
||||
pytz.timezone("Asia/Shanghai")
|
||||
):
|
||||
# date = await Genshin.get_user_resin_recovery_time(u.uid) # 不能要,因为可能在这期间用户使用了树脂
|
||||
add_job(u.user_qq, u.uid)
|
||||
# scheduler.add_job(
|
||||
# _remind,
|
||||
# "date",
|
||||
# run_date=date.replace(microsecond=0),
|
||||
# id=f"genshin_resin_remind_{u.uid}_{u.user_qq}",
|
||||
# args=[u.user_qq, u.uid],
|
||||
# )
|
||||
add_job(u.user_id, u.uid)
|
||||
logger.info(
|
||||
f"genshin_resin_remind add_job:USER:{u.user_qq} UID:{u.uid}启动原神树脂提醒 "
|
||||
f"genshin_resin_remind add_job:USER:{u.user_id} UID:{u.uid}启动原神树脂提醒 "
|
||||
)
|
||||
else:
|
||||
u.resin_recovery_time = None # type: ignore
|
||||
update_list.append(u)
|
||||
add_job(u.user_qq, u.uid)
|
||||
add_job(u.user_id, u.uid)
|
||||
logger.info(
|
||||
f"genshin_resin_remind add_job CHECK:USER:{u.user_qq} UID:{u.uid}启动原神树脂提醒 "
|
||||
f"genshin_resin_remind add_job CHECK:USER:{u.user_id} UID:{u.uid}启动原神树脂提醒 "
|
||||
)
|
||||
else:
|
||||
add_job(u.user_qq, u.uid)
|
||||
add_job(u.user_id, u.uid)
|
||||
logger.info(
|
||||
f"genshin_resin_remind add_job CHECK:USER:{u.user_qq} UID:{u.uid}启动原神树脂提醒 "
|
||||
f"genshin_resin_remind add_job CHECK:USER:{u.user_id} UID:{u.uid}启动原神树脂提醒 "
|
||||
)
|
||||
if update_list:
|
||||
await Genshin.bulk_update(update_list, ["resin_recovery_time"])
|
||||
|
||||
|
||||
def add_job(user_id: int, uid: int):
|
||||
def add_job(user_id: str, uid: int):
|
||||
# 移除
|
||||
try:
|
||||
scheduler.remove_job(f"genshin_resin_remind_{uid}_{user_id}")
|
||||
@@ -136,7 +128,7 @@ def add_job(user_id: int, uid: int):
|
||||
|
||||
|
||||
async def _remind(user_id: int, uid: str):
|
||||
user = await Genshin.get_or_none(user_qq=user_id, uid=int(uid))
|
||||
user = await Genshin.get_or_none(user_id=str(user_id), uid=int(uid))
|
||||
uid = str(uid)
|
||||
if uid[0] in ["1", "2"]:
|
||||
server_id = "cn_gf01"
|
||||
|
||||
@@ -1,33 +1,36 @@
|
||||
from nonebot import on_command, on_notice
|
||||
from nonebot.adapters.onebot.v11 import (
|
||||
Bot,
|
||||
ActionFailed,
|
||||
GroupMessageEvent,
|
||||
PokeNotifyEvent,
|
||||
Message
|
||||
)
|
||||
from .data_source import (
|
||||
check_gold,
|
||||
generate_send_redbag_pic,
|
||||
open_redbag,
|
||||
generate_open_redbag_pic,
|
||||
return_gold,
|
||||
)
|
||||
from nonebot.adapters.onebot.v11.permission import GROUP
|
||||
from nonebot.message import run_preprocessor, IgnoredException
|
||||
from nonebot.matcher import Matcher
|
||||
from utils.utils import is_number, scheduler
|
||||
from utils.message_builder import image
|
||||
from services.log import logger
|
||||
from configs.path_config import IMAGE_PATH
|
||||
from nonebot.permission import SUPERUSER
|
||||
from nonebot.rule import to_me
|
||||
from datetime import datetime, timedelta
|
||||
from configs.config import NICKNAME
|
||||
from apscheduler.jobstores.base import JobLookupError
|
||||
from nonebot.params import CommandArg
|
||||
import random
|
||||
import time
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from apscheduler.jobstores.base import JobLookupError
|
||||
from nonebot import on_command, on_notice
|
||||
from nonebot.adapters.onebot.v11 import (
|
||||
ActionFailed,
|
||||
Bot,
|
||||
GroupMessageEvent,
|
||||
Message,
|
||||
PokeNotifyEvent,
|
||||
)
|
||||
from nonebot.adapters.onebot.v11.permission import GROUP
|
||||
from nonebot.matcher import Matcher
|
||||
from nonebot.message import IgnoredException, run_preprocessor
|
||||
from nonebot.params import CommandArg
|
||||
from nonebot.permission import SUPERUSER
|
||||
from nonebot.rule import to_me
|
||||
|
||||
from configs.config import NICKNAME
|
||||
from configs.path_config import IMAGE_PATH
|
||||
from services.log import logger
|
||||
from utils.message_builder import image
|
||||
from utils.utils import is_number, scheduler
|
||||
|
||||
from .data_source import (
|
||||
check_gold,
|
||||
generate_open_redbag_pic,
|
||||
generate_send_redbag_pic,
|
||||
open_redbag,
|
||||
return_gold,
|
||||
)
|
||||
|
||||
__zx_plugin_name__ = "金币红包"
|
||||
__plugin_usage__ = """
|
||||
@@ -72,7 +75,9 @@ gold_redbag = on_command(
|
||||
"塞红包", aliases={"金币红包"}, priority=5, block=True, permission=GROUP
|
||||
)
|
||||
|
||||
open_ = on_command("开", aliases={"抢"}, priority=5, block=True, permission=GROUP, rule=rule)
|
||||
open_ = on_command(
|
||||
"开", aliases={"抢"}, priority=5, block=True, permission=GROUP, rule=rule
|
||||
)
|
||||
|
||||
poke_ = on_notice(priority=6, block=False)
|
||||
|
||||
@@ -89,7 +94,10 @@ festive_redbag_data = {}
|
||||
|
||||
# 阻断其他poke
|
||||
@run_preprocessor
|
||||
async def _(matcher: Matcher, event: PokeNotifyEvent, ):
|
||||
async def _(
|
||||
matcher: Matcher,
|
||||
event: PokeNotifyEvent,
|
||||
):
|
||||
try:
|
||||
if matcher.type == "notice" and event.self_id == event.target_id:
|
||||
flag = check_on_gold_red(event)
|
||||
@@ -109,10 +117,12 @@ async def _(bot: Bot, event: GroupMessageEvent, arg: Message = CommandArg()):
|
||||
try:
|
||||
if time.time() - redbag_data[event.group_id]["time"] > 60:
|
||||
amount = (
|
||||
redbag_data[event.group_id]["amount"]
|
||||
- redbag_data[event.group_id]["open_amount"]
|
||||
redbag_data[event.group_id]["amount"]
|
||||
- redbag_data[event.group_id]["open_amount"]
|
||||
)
|
||||
await return_gold(
|
||||
redbag_data[event.group_id]["user_id"], str(event.group_id), amount
|
||||
)
|
||||
await return_gold(redbag_data[event.group_id]["user_id"], event.group_id, amount)
|
||||
await gold_redbag.send(
|
||||
f'{redbag_data[event.group_id]["nickname"]}的红包过时未开完,退还{amount}金币...'
|
||||
)
|
||||
@@ -128,18 +138,18 @@ async def _(bot: Bot, event: GroupMessageEvent, arg: Message = CommandArg()):
|
||||
msg = arg.extract_plain_text().strip()
|
||||
msg = msg.split()
|
||||
if len(msg) == 1:
|
||||
flag, amount = await check_gold(event.user_id, event.group_id, msg[0])
|
||||
flag, amount = await check_gold(str(event.user_id), str(event.group_id), msg[0])
|
||||
if not flag:
|
||||
await gold_redbag.finish(amount)
|
||||
await gold_redbag.finish(str(amount))
|
||||
num = 5
|
||||
else:
|
||||
amount = msg[0]
|
||||
num = msg[1]
|
||||
if not is_number(num) or int(num) < 1:
|
||||
await gold_redbag.finish("红包个数给我输正确啊!", at_sender=True)
|
||||
flag, amount = await check_gold(event.user_id, event.group_id, amount)
|
||||
flag, amount = await check_gold(str(event.user_id), str(event.group_id), amount)
|
||||
if not flag:
|
||||
await gold_redbag.finish(amount, at_sender=True)
|
||||
await gold_redbag.finish(str(amount), at_sender=True)
|
||||
group_member_num = (await bot.get_group_info(group_id=event.group_id))[
|
||||
"member_count"
|
||||
]
|
||||
@@ -149,7 +159,12 @@ async def _(bot: Bot, event: GroupMessageEvent, arg: Message = CommandArg()):
|
||||
num = group_member_num
|
||||
nickname = event.sender.card or event.sender.nickname
|
||||
flag, result = init_redbag(
|
||||
event.user_id, event.group_id, nickname, amount, num, int(bot.self_id)
|
||||
str(event.user_id),
|
||||
str(event.group_id),
|
||||
nickname or str(event.user_id),
|
||||
amount,
|
||||
num,
|
||||
int(bot.self_id),
|
||||
)
|
||||
if not flag:
|
||||
await gold_redbag.finish(result, at_sender=True)
|
||||
@@ -158,13 +173,11 @@ async def _(bot: Bot, event: GroupMessageEvent, arg: Message = CommandArg()):
|
||||
f"{nickname}发起了金币红包\n金额:{amount}\n数量:{num}\n"
|
||||
+ image(
|
||||
b64=await generate_send_redbag_pic(
|
||||
redbag_data[event.group_id]["user_id"]
|
||||
redbag_data[str(event.group_id)]["user_id"]
|
||||
)
|
||||
)
|
||||
)
|
||||
logger.info(
|
||||
f"USER {event.user_id} GROUP {event.group_id} 塞入 {num} 个红包,共 {amount} 金币"
|
||||
)
|
||||
logger.info(f"塞入 {num} 个红包,共 {amount} 金币", "金币红包", event.user_id, event.group_id)
|
||||
|
||||
|
||||
@open_.handle()
|
||||
@@ -173,20 +186,20 @@ async def _(event: GroupMessageEvent, arg: Message = CommandArg()):
|
||||
msg = arg.extract_plain_text().strip()
|
||||
msg = (
|
||||
msg.replace("!", "")
|
||||
.replace("!", "")
|
||||
.replace(",", "")
|
||||
.replace(",", "")
|
||||
.replace(".", "")
|
||||
.replace("。", "")
|
||||
.replace("!", "")
|
||||
.replace(",", "")
|
||||
.replace(",", "")
|
||||
.replace(".", "")
|
||||
.replace("。", "")
|
||||
)
|
||||
if msg:
|
||||
if "红包" not in msg:
|
||||
return
|
||||
try:
|
||||
await open_.send(
|
||||
image(b64=await get_redbag_img(event.user_id, event.group_id)),
|
||||
image(b64=await get_redbag_img(str(event.user_id), str(event.group_id))),
|
||||
at_sender=True,
|
||||
)
|
||||
)
|
||||
except KeyError:
|
||||
await open_.finish("真贪心,明明已经开过这个红包了的说...", at_sender=True)
|
||||
|
||||
@@ -199,7 +212,7 @@ async def _poke_(event: PokeNotifyEvent):
|
||||
if not flag:
|
||||
return
|
||||
await poke_.send(
|
||||
image(b64=await get_redbag_img(event.user_id, event.group_id)),
|
||||
image(b64=await get_redbag_img(str(event.user_id), str(event.group_id))),
|
||||
at_sender=True,
|
||||
)
|
||||
|
||||
@@ -217,8 +230,8 @@ async def _(event: GroupMessageEvent):
|
||||
at_sender=True,
|
||||
)
|
||||
await return_gold(
|
||||
event.user_id,
|
||||
event.group_id,
|
||||
str(event.user_id),
|
||||
str(event.group_id),
|
||||
redbag_data[event.group_id]["amount"]
|
||||
- redbag_data[event.group_id]["open_amount"],
|
||||
)
|
||||
@@ -272,9 +285,7 @@ async def _(bot: Bot, arg: Message = CommandArg()):
|
||||
await end_festive_redbag(bot, g)
|
||||
except JobLookupError:
|
||||
pass
|
||||
init_redbag(
|
||||
int(bot.self_id), g, f"{NICKNAME}", amount, num, int(bot.self_id), 1
|
||||
)
|
||||
init_redbag(bot.self_id, g, f"{NICKNAME}", amount, num, int(bot.self_id), 1)
|
||||
scheduler.add_job(
|
||||
end_festive_redbag,
|
||||
"date",
|
||||
@@ -286,7 +297,7 @@ async def _(bot: Bot, arg: Message = CommandArg()):
|
||||
await bot.send_group_msg(
|
||||
group_id=g,
|
||||
message=f"{NICKNAME}发起了金币红包\n金额:{amount}\n数量:{num}\n"
|
||||
+ image(
|
||||
+ image(
|
||||
b64=await generate_send_redbag_pic(int(bot.self_id), greetings)
|
||||
),
|
||||
)
|
||||
@@ -297,13 +308,13 @@ async def _(bot: Bot, arg: Message = CommandArg()):
|
||||
|
||||
# 红包数据初始化
|
||||
def init_redbag(
|
||||
user_id: int,
|
||||
group_id: int,
|
||||
nickname: str,
|
||||
amount: int,
|
||||
num: int,
|
||||
bot_self_id: int,
|
||||
mode: int = 0,
|
||||
user_id: str,
|
||||
group_id: str,
|
||||
nickname: str,
|
||||
amount: int,
|
||||
num: int,
|
||||
bot_self_id: int,
|
||||
mode: int = 0,
|
||||
):
|
||||
global redbag_data, festive_redbag_data
|
||||
data = redbag_data if mode == 0 else festive_redbag_data
|
||||
@@ -341,7 +352,7 @@ def random_redbag(amount: int, num: int) -> list:
|
||||
|
||||
|
||||
# 返回开红包图片
|
||||
async def get_redbag_img(user_id: int, group_id: int):
|
||||
async def get_redbag_img(user_id: str, group_id: str):
|
||||
global redbag_data, festive_redbag_data
|
||||
data = redbag_data
|
||||
mode = 0
|
||||
@@ -389,17 +400,14 @@ def check_on_gold_red(event) -> bool:
|
||||
flag1 = True
|
||||
flag2 = True
|
||||
try:
|
||||
if festive_redbag_data[event.group_id]["user_id"]:
|
||||
if (
|
||||
event.user_id
|
||||
in festive_redbag_data[event.group_id]["open_user"]
|
||||
):
|
||||
if festive_redbag_data[str(event.group_id)]["user_id"]:
|
||||
if event.user_id in festive_redbag_data[str(event.group_id)]["open_user"]:
|
||||
flag1 = False
|
||||
except KeyError:
|
||||
flag1 = False
|
||||
try:
|
||||
if redbag_data[event.group_id]["user_id"]:
|
||||
if event.user_id in redbag_data[event.group_id]["open_user"]:
|
||||
if redbag_data[str(event.group_id)]["user_id"]:
|
||||
if event.user_id in redbag_data[str(event.group_id)]["open_user"]:
|
||||
flag2 = False
|
||||
except KeyError:
|
||||
flag2 = False
|
||||
|
||||
@@ -1,87 +1,108 @@
|
||||
from models.bag_user import BagUser
|
||||
from utils.utils import is_number, get_user_avatar
|
||||
from utils.image_utils import BuildImage
|
||||
from configs.path_config import IMAGE_PATH
|
||||
from .model import RedbagUser
|
||||
import random
|
||||
import os
|
||||
from io import BytesIO
|
||||
import asyncio
|
||||
import os
|
||||
import random
|
||||
from io import BytesIO
|
||||
from typing import Union
|
||||
|
||||
from configs.path_config import IMAGE_PATH
|
||||
from models.bag_user import BagUser
|
||||
from utils.image_utils import BuildImage
|
||||
from utils.utils import get_user_avatar, is_number
|
||||
|
||||
from .model import RedbagUser
|
||||
|
||||
|
||||
# 检查金币数量合法性,并添加记录数据
|
||||
async def check_gold(user_id: int, group_id: int, amount: str):
|
||||
async def check_gold(user_id: str, group_id: str, amount: Union[str, int]):
|
||||
if is_number(amount):
|
||||
amount = int(amount)
|
||||
user_gold = await BagUser.get_gold(user_id, group_id)
|
||||
if amount < 1:
|
||||
return False, '小气鬼,要别人倒贴金币给你嘛!'
|
||||
return False, "小气鬼,要别人倒贴金币给你嘛!"
|
||||
if user_gold < amount:
|
||||
return False, '没有金币的话请不要发红包...'
|
||||
return False, "没有金币的话请不要发红包..."
|
||||
await BagUser.spend_gold(user_id, group_id, amount)
|
||||
await RedbagUser.add_redbag_data(user_id, group_id, 'send', amount)
|
||||
await RedbagUser.add_redbag_data(user_id, group_id, "send", amount)
|
||||
return True, amount
|
||||
else:
|
||||
return False, '给我好好的输入红包里金币的数量啊喂!'
|
||||
return False, "给我好好的输入红包里金币的数量啊喂!"
|
||||
|
||||
|
||||
# 金币退回
|
||||
async def return_gold(user_id: int, group_id: int, amount: int):
|
||||
async def return_gold(user_id: str, group_id: str, amount: int):
|
||||
await BagUser.add_gold(user_id, group_id, amount)
|
||||
|
||||
|
||||
# 开红包
|
||||
async def open_redbag(user_id: int, group_id: int, redbag_data: dict):
|
||||
amount = random.choice(redbag_data[group_id]['redbag'])
|
||||
redbag_data[group_id]['redbag'].remove(amount)
|
||||
redbag_data[group_id]['open_user'].append(user_id)
|
||||
redbag_data[group_id]['open_amount'] += amount
|
||||
await RedbagUser.add_redbag_data(user_id, group_id, 'get', amount)
|
||||
async def open_redbag(user_id: str, group_id: str, redbag_data: dict):
|
||||
amount = random.choice(redbag_data[group_id]["redbag"])
|
||||
redbag_data[group_id]["redbag"].remove(amount)
|
||||
redbag_data[group_id]["open_user"].append(user_id)
|
||||
redbag_data[group_id]["open_amount"] += amount
|
||||
await RedbagUser.add_redbag_data(user_id, group_id, "get", amount)
|
||||
await BagUser.add_gold(user_id, group_id, amount)
|
||||
return amount, redbag_data
|
||||
|
||||
|
||||
# 随机红包图片
|
||||
async def generate_send_redbag_pic(user_id: int, msg: str = '恭喜发财 大吉大利'):
|
||||
async def generate_send_redbag_pic(user_id: int, msg: str = "恭喜发财 大吉大利"):
|
||||
random_redbag = random.choice(os.listdir(f"{IMAGE_PATH}/prts/redbag_2"))
|
||||
redbag = BuildImage(0, 0, font_size=38, background=f'{IMAGE_PATH}/prts/redbag_2/{random_redbag}')
|
||||
redbag = BuildImage(
|
||||
0, 0, font_size=38, background=f"{IMAGE_PATH}/prts/redbag_2/{random_redbag}"
|
||||
)
|
||||
ava = BuildImage(65, 65, background=BytesIO(await get_user_avatar(user_id)))
|
||||
await asyncio.get_event_loop().run_in_executor(None, ava.circle)
|
||||
redbag.text((int((redbag.size[0] - redbag.getsize(msg)[0]) / 2), 210), msg, (240, 218, 164))
|
||||
redbag.paste(ava, (int((redbag.size[0] - ava.size[0])/2), 130), True)
|
||||
redbag.text(
|
||||
(int((redbag.size[0] - redbag.getsize(msg)[0]) / 2), 210), msg, (240, 218, 164)
|
||||
)
|
||||
redbag.paste(ava, (int((redbag.size[0] - ava.size[0]) / 2), 130), True)
|
||||
return redbag.pic2bs4()
|
||||
|
||||
|
||||
# 开红包图片
|
||||
async def generate_open_redbag_pic(user_id: int, send_user_nickname: str, amount: int, text: str):
|
||||
return await asyncio.create_task(_generate_open_redbag_pic(user_id, send_user_nickname, amount, text))
|
||||
async def generate_open_redbag_pic(
|
||||
user_id: str, send_user_nickname: str, amount: int, text: str
|
||||
):
|
||||
return await asyncio.create_task(
|
||||
_generate_open_redbag_pic(user_id, send_user_nickname, amount, text)
|
||||
)
|
||||
|
||||
|
||||
# 开红包图片
|
||||
async def _generate_open_redbag_pic(user_id: int, send_user_nickname: str, amount: int, text: str):
|
||||
send_user_nickname += '的红包'
|
||||
amount = str(amount)
|
||||
async def _generate_open_redbag_pic(
|
||||
user_id: str, send_user_nickname: str, amount: int, text: str
|
||||
):
|
||||
send_user_nickname += "的红包"
|
||||
amount_str = str(amount)
|
||||
random_redbag = random.choice(os.listdir(f"{IMAGE_PATH}/prts/redbag_1"))
|
||||
head = BuildImage(1000, 980, font_size=30, background=f'{IMAGE_PATH}/prts/redbag_1/{random_redbag}')
|
||||
head = BuildImage(
|
||||
1000,
|
||||
980,
|
||||
font_size=30,
|
||||
background=f"{IMAGE_PATH}/prts/redbag_1/{random_redbag}",
|
||||
)
|
||||
size = BuildImage(0, 0, font_size=50).getsize(send_user_nickname)
|
||||
# QQ头像
|
||||
ava_bk = BuildImage(100 + size[0], 66, is_alpha=True, font_size=50)
|
||||
ava = BuildImage(66, 66, is_alpha=True, background=BytesIO(await get_user_avatar(user_id)))
|
||||
ava = BuildImage(
|
||||
66, 66, is_alpha=True, background=BytesIO(await get_user_avatar(user_id))
|
||||
)
|
||||
ava_bk.paste(ava)
|
||||
ava_bk.text((100, 7), send_user_nickname)
|
||||
# ava_bk.show()
|
||||
ava_bk_w, ava_bk_h = ava_bk.size
|
||||
head.paste(ava_bk, (int((1000 - ava_bk_w) / 2), 300), alpha=True)
|
||||
# 金额
|
||||
size = BuildImage(0, 0, font_size=150).getsize(amount)
|
||||
size = BuildImage(0, 0, font_size=150).getsize(amount_str)
|
||||
price = BuildImage(size[0], size[1], is_alpha=True, font_size=150)
|
||||
price.text((0, 0), amount, fill=(209, 171, 108))
|
||||
price.text((0, 0), amount_str, fill=(209, 171, 108))
|
||||
# 金币中文
|
||||
head.paste(price, (int((1000 - size[0]) / 2) - 50, 460), alpha=True)
|
||||
head.text((int((1000 - size[0]) / 2 + size[0]) - 50, 500 + size[1] - 70), '金币', fill=(209, 171, 108))
|
||||
head.text(
|
||||
(int((1000 - size[0]) / 2 + size[0]) - 50, 500 + size[1] - 70),
|
||||
"金币",
|
||||
fill=(209, 171, 108),
|
||||
)
|
||||
# 剩余数量和金额
|
||||
head.text((350, 900), text, (198, 198, 198))
|
||||
return head.pic2bs4()
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -9,9 +9,9 @@ class RedbagUser(Model):
|
||||
|
||||
id = fields.IntField(pk=True, generated=True, auto_increment=True)
|
||||
"""自增id"""
|
||||
user_qq = fields.BigIntField()
|
||||
user_id = fields.CharField(255)
|
||||
"""用户id"""
|
||||
group_id = fields.BigIntField()
|
||||
group_id = fields.CharField(255)
|
||||
"""群聊id"""
|
||||
send_redbag_count = fields.IntField(default=0)
|
||||
"""发送红包次数"""
|
||||
@@ -25,23 +25,23 @@ class RedbagUser(Model):
|
||||
class Meta:
|
||||
table = "redbag_users"
|
||||
table_description = "红包统计数据表"
|
||||
unique_together = ("user_qq", "group_id")
|
||||
unique_together = ("user_id", "group_id")
|
||||
|
||||
@classmethod
|
||||
async def add_redbag_data(
|
||||
cls, user_qq: int, group_id: int, i_type: str, money: int
|
||||
cls, user_id: str, group_id: str, i_type: str, money: int
|
||||
):
|
||||
"""
|
||||
说明:
|
||||
添加收发红包数据
|
||||
参数:
|
||||
:param user_qq: qq号
|
||||
:param user_id: 用户id
|
||||
:param group_id: 群号
|
||||
:param i_type: 收或发
|
||||
:param money: 金钱数量
|
||||
"""
|
||||
|
||||
user, _ = await cls.get_or_create(user_qq=user_qq, group_id=group_id)
|
||||
user, _ = await cls.get_or_create(user_id=user_id, group_id=group_id)
|
||||
if i_type == "get":
|
||||
user.get_redbag_count = user.get_redbag_count + 1
|
||||
user.get_gold = user.get_gold + money
|
||||
@@ -56,3 +56,11 @@ class RedbagUser(Model):
|
||||
"spend_gold",
|
||||
]
|
||||
)
|
||||
|
||||
@classmethod
|
||||
async def _run_script(cls):
|
||||
return [
|
||||
"ALTER TABLE redbag_users RENAME COLUMN user_qq TO user_id;", # 将user_qq改为user_id
|
||||
"ALTER TABLE redbag_users ALTER COLUMN user_id TYPE character varying(255);",
|
||||
"ALTER TABLE redbag_users ALTER COLUMN group_id TYPE character varying(255);",
|
||||
]
|
||||
|
||||
@@ -27,12 +27,12 @@ my_level = on_command("我的权限", permission=GROUP, priority=5, block=True)
|
||||
|
||||
@get_my_group_info.handle()
|
||||
async def _(event: GroupMessageEvent):
|
||||
result = await get_member_info(event.user_id, event.group_id)
|
||||
result = await get_member_info(str(event.user_id), str(event.group_id))
|
||||
await get_my_group_info.finish(result)
|
||||
|
||||
|
||||
async def get_member_info(user_qq: int, group_id: int) -> str:
|
||||
if user := await GroupInfoUser.get_or_none(user_id=str(user_qq), group_id=str(group_id)):
|
||||
async def get_member_info(user_id: str, group_id: str) -> str:
|
||||
if user := await GroupInfoUser.get_or_none(user_id=user_id, group_id=group_id):
|
||||
result = ""
|
||||
result += "昵称:" + user.user_name + "\n"
|
||||
result += "加群时间:" + str(user.user_join_time.date())
|
||||
|
||||
@@ -33,6 +33,7 @@ from .utils import (
|
||||
CaseManager,
|
||||
build_case_image,
|
||||
get_skin_case,
|
||||
init_skin_trends,
|
||||
reset_count_daily,
|
||||
update_skin_data,
|
||||
)
|
||||
@@ -135,6 +136,31 @@ update_case = on_command(
|
||||
show_case = on_command("查看武器箱", priority=5, block=True)
|
||||
my_knifes = on_command("我的金色", priority=1, permission=GROUP, block=True)
|
||||
show_skin = on_command("查看皮肤", priority=5, block=True)
|
||||
price_trends = on_command("价格趋势", priority=5, block=True)
|
||||
|
||||
|
||||
@price_trends.handle()
|
||||
async def _(event: MessageEvent, arg: Message = CommandArg()):
|
||||
msg = arg.extract_plain_text().replace("武器箱", "").strip()
|
||||
if not msg:
|
||||
await price_trends.finish("未指定皮肤")
|
||||
msg_split = msg.split()
|
||||
if len(msg_split) < 3:
|
||||
await price_trends.finish("参数不足, [类型名称] [皮肤名称] [磨损程度] ?[天数=7]")
|
||||
abrasion = msg_split[2]
|
||||
day = 7
|
||||
if len(msg_split) > 3:
|
||||
if not is_number(msg_split[3]):
|
||||
await price_trends.finish("天数必须为数字")
|
||||
day = int(msg_split[3])
|
||||
if day <= 0 or day > 180:
|
||||
await price_trends.finish("天数必须大于0且小于180")
|
||||
result = await init_skin_trends(msg_split[0], msg_split[1], msg_split[2], day)
|
||||
if not result:
|
||||
await price_trends.finish("未查询到数据")
|
||||
await price_trends.send(
|
||||
image(await init_skin_trends(msg_split[0], msg_split[1], msg_split[2], day))
|
||||
)
|
||||
|
||||
|
||||
@reload_count.handle()
|
||||
|
||||
@@ -10,9 +10,9 @@ class OpenCasesLog(Model):
|
||||
|
||||
id = fields.IntField(pk=True, generated=True, auto_increment=True)
|
||||
"""自增id"""
|
||||
user_qq = fields.BigIntField()
|
||||
user_id = fields.CharField(255)
|
||||
"""用户id"""
|
||||
group_id = fields.BigIntField()
|
||||
group_id = fields.CharField(255)
|
||||
"""群聊id"""
|
||||
case_name = fields.CharField(255)
|
||||
"""箱子名称"""
|
||||
@@ -36,3 +36,11 @@ class OpenCasesLog(Model):
|
||||
class Meta:
|
||||
table = "open_cases_log"
|
||||
table_description = "开箱日志表"
|
||||
|
||||
@classmethod
|
||||
async def _run_script(cls):
|
||||
return [
|
||||
"ALTER TABLE open_cases_log RENAME COLUMN user_qq TO user_id;", # 将user_qq改为user_id
|
||||
"ALTER TABLE open_cases_log ALTER COLUMN user_id TYPE character varying(255);",
|
||||
"ALTER TABLE open_cases_log ALTER COLUMN group_id TYPE character varying(255);",
|
||||
]
|
||||
|
||||
@@ -7,9 +7,9 @@ class OpenCasesUser(Model):
|
||||
|
||||
id = fields.IntField(pk=True, generated=True, auto_increment=True)
|
||||
"""自增id"""
|
||||
user_qq = fields.BigIntField()
|
||||
user_id = fields.CharField(255)
|
||||
"""用户id"""
|
||||
group_id = fields.BigIntField()
|
||||
group_id = fields.CharField(255)
|
||||
"""群聊id"""
|
||||
total_count: int = fields.IntField(default=0)
|
||||
"""总开启次数"""
|
||||
@@ -47,11 +47,14 @@ class OpenCasesUser(Model):
|
||||
class Meta:
|
||||
table = "open_cases_users"
|
||||
table_description = "开箱统计数据表"
|
||||
unique_together = ("user_qq", "group_id")
|
||||
unique_together = ("user_id", "group_id")
|
||||
|
||||
@classmethod
|
||||
async def _run_script(cls):
|
||||
return [
|
||||
"alter table open_cases_users alter COLUMN make_money type float;", # 将make_money字段改为float
|
||||
"alter table open_cases_users alter COLUMN spend_money type float;", # 将spend_money字段改为float
|
||||
"ALTER TABLE open_cases_users RENAME COLUMN user_qq TO user_id;", # 将user_qq改为user_id
|
||||
"ALTER TABLE open_cases_users ALTER COLUMN user_id TYPE character varying(255);",
|
||||
"ALTER TABLE open_cases_users ALTER COLUMN group_id TYPE character varying(255);",
|
||||
]
|
||||
|
||||
@@ -63,17 +63,19 @@ def add_count(user: OpenCasesUser, skin: BuffSkin, case_price: float):
|
||||
user.spend_money += 17 + case_price
|
||||
|
||||
|
||||
async def get_user_max_count(user_qq: int, group_id: int) -> int:
|
||||
async def get_user_max_count(user_id: str, group_id: int) -> int:
|
||||
"""获取用户每日最大开箱次数
|
||||
|
||||
Args:
|
||||
user_qq (int): 用户id
|
||||
user_id (str): 用户id
|
||||
group_id (int): 群号
|
||||
|
||||
Returns:
|
||||
int: 最大开箱次数
|
||||
"""
|
||||
user, _ = await SignGroupUser.get_or_create(user_id=str(user_qq), group_id=str(group_id))
|
||||
user, _ = await SignGroupUser.get_or_create(
|
||||
user_id=str(user_id), group_id=str(group_id)
|
||||
)
|
||||
impression = int(user.impression)
|
||||
initial_open_case_count = Config.get_config("open_cases", "INITIAL_OPEN_CASE_COUNT")
|
||||
each_impression_add_count = Config.get_config(
|
||||
@@ -82,11 +84,11 @@ async def get_user_max_count(user_qq: int, group_id: int) -> int:
|
||||
return int(initial_open_case_count + impression / each_impression_add_count) # type: ignore
|
||||
|
||||
|
||||
async def open_case(user_qq: int, group_id: int, case_name: str) -> Union[str, Message]:
|
||||
async def open_case(user_id: str, group_id: int, case_name: str) -> Union[str, Message]:
|
||||
"""开箱
|
||||
|
||||
Args:
|
||||
user_qq (int): 用户id
|
||||
user_id (str): 用户id
|
||||
group_id (int): 群号
|
||||
case_name (str, optional): 武器箱名称. Defaults to "狂牙大行动".
|
||||
|
||||
@@ -99,14 +101,14 @@ async def open_case(user_qq: int, group_id: int, case_name: str) -> Union[str, M
|
||||
case_name = random.choice(CaseManager.CURRENT_CASES) # type: ignore
|
||||
if case_name not in CaseManager.CURRENT_CASES:
|
||||
return "武器箱未收录, 当前可用武器箱:\n" + ", ".join(CaseManager.CURRENT_CASES) # type: ignore
|
||||
logger.debug(f"尝试开启武器箱: {case_name}", "开箱", user_qq, group_id)
|
||||
logger.debug(f"尝试开启武器箱: {case_name}", "开箱", user_id, group_id)
|
||||
case = cn2py(case_name)
|
||||
user = await OpenCasesUser.get_or_none(user_qq=user_qq, group_id=group_id)
|
||||
user = await OpenCasesUser.get_or_none(user_id=user_id, group_id=group_id)
|
||||
if not user:
|
||||
user = await OpenCasesUser.create(
|
||||
user_qq=user_qq, group_id=group_id, open_cases_time_last=datetime.now()
|
||||
user_id=user_id, group_id=group_id, open_cases_time_last=datetime.now()
|
||||
)
|
||||
max_count = await get_user_max_count(user_qq, group_id)
|
||||
max_count = await get_user_max_count(user_id, group_id)
|
||||
# 一天次数上限
|
||||
if user.today_open_total >= max_count:
|
||||
return _handle_is_MAX_COUNT()
|
||||
@@ -129,12 +131,12 @@ async def open_case(user_qq: int, group_id: int, case_name: str) -> Union[str, M
|
||||
logger.info(
|
||||
f"开启{case_name}武器箱获得 {skin.name}{'(StatTrak™)' if skin.is_stattrak else ''} | {skin.skin_name} ({skin.abrasion}) 磨损: [{rand}] 价格: {skin.sell_min_price}",
|
||||
"开箱",
|
||||
user_qq,
|
||||
user_id,
|
||||
group_id,
|
||||
)
|
||||
await user.save()
|
||||
await OpenCasesLog.create(
|
||||
user_qq=user_qq,
|
||||
user_id=user_id,
|
||||
group_id=group_id,
|
||||
case_name=case_name,
|
||||
name=skin.name,
|
||||
@@ -146,7 +148,7 @@ async def open_case(user_qq: int, group_id: int, case_name: str) -> Union[str, M
|
||||
abrasion_value=rand,
|
||||
create_time=datetime.now(),
|
||||
)
|
||||
logger.debug(f"添加 1 条开箱日志", "开箱", user_qq, group_id)
|
||||
logger.debug(f"添加 1 条开箱日志", "开箱", user_id, group_id)
|
||||
over_count = max_count - user.today_open_total
|
||||
img = await draw_card(skin, rand)
|
||||
return (
|
||||
@@ -157,12 +159,12 @@ async def open_case(user_qq: int, group_id: int, case_name: str) -> Union[str, M
|
||||
|
||||
|
||||
async def open_multiple_case(
|
||||
user_qq: int, group_id: int, case_name: str, num: int = 10
|
||||
user_id: str, group_id: int, case_name: str, num: int = 10
|
||||
):
|
||||
"""多连开箱
|
||||
|
||||
Args:
|
||||
user_qq (int): 用户id
|
||||
user_id (int): 用户id
|
||||
group_id (int): 群号
|
||||
case_name (str): 箱子名称
|
||||
num (int, optional): 数量. Defaults to 10.
|
||||
@@ -177,11 +179,11 @@ async def open_multiple_case(
|
||||
if case_name not in CaseManager.CURRENT_CASES:
|
||||
return "武器箱未收录, 当前可用武器箱:\n" + ", ".join(CaseManager.CURRENT_CASES) # type: ignore
|
||||
user, _ = await OpenCasesUser.get_or_create(
|
||||
user_qq=user_qq,
|
||||
user_id=user_id,
|
||||
group_id=group_id,
|
||||
defaults={"open_cases_time_last": datetime.now()},
|
||||
)
|
||||
max_count = await get_user_max_count(user_qq, group_id)
|
||||
max_count = await get_user_max_count(user_id, group_id)
|
||||
if user.today_open_total >= max_count:
|
||||
return _handle_is_MAX_COUNT()
|
||||
if max_count - user.today_open_total < num:
|
||||
@@ -189,7 +191,7 @@ async def open_multiple_case(
|
||||
f"今天开箱次数不足{num}次噢,请单抽试试看(也许单抽运气更好?)"
|
||||
f"\n剩余开箱次数:{max_count - user.today_open_total}"
|
||||
)
|
||||
logger.debug(f"尝试开启武器箱: {case_name}", "开箱", user_qq, group_id)
|
||||
logger.debug(f"尝试开启武器箱: {case_name}", "开箱", user_id, group_id)
|
||||
case = cn2py(case_name)
|
||||
skin_count = {}
|
||||
img_list = []
|
||||
@@ -219,12 +221,12 @@ async def open_multiple_case(
|
||||
logger.info(
|
||||
f"开启{case_name}武器箱获得 {skin.name}{'(StatTrak™)' if skin.is_stattrak else ''} | {skin.skin_name} ({skin.abrasion}) 磨损: [{rand:.11f}] 价格: {skin.sell_min_price}",
|
||||
"开箱",
|
||||
user_qq,
|
||||
user_id,
|
||||
group_id,
|
||||
)
|
||||
log_list.append(
|
||||
OpenCasesLog(
|
||||
user_qq=user_qq,
|
||||
user_id=user_id,
|
||||
group_id=group_id,
|
||||
case_name=case_name,
|
||||
name=skin.name,
|
||||
@@ -240,7 +242,7 @@ async def open_multiple_case(
|
||||
await user.save()
|
||||
if log_list:
|
||||
await OpenCasesLog.bulk_create(log_list, 10)
|
||||
logger.debug(f"添加 {len(log_list)} 条开箱日志", "开箱", user_qq, group_id)
|
||||
logger.debug(f"添加 {len(log_list)} 条开箱日志", "开箱", user_id, group_id)
|
||||
img_w += 10
|
||||
img_h += 10
|
||||
w = img_w * 5
|
||||
@@ -273,8 +275,8 @@ def _handle_is_MAX_COUNT() -> str:
|
||||
return f"今天已达开箱上限了喔,明天再来吧\n(提升好感度可以增加每日开箱数 #疯狂暗示)"
|
||||
|
||||
|
||||
async def total_open_statistics(user_qq: int, group: int) -> str:
|
||||
user, _ = await OpenCasesUser.get_or_create(user_qq=user_qq, group_id=group)
|
||||
async def total_open_statistics(user_id: str, group: str) -> str:
|
||||
user, _ = await OpenCasesUser.get_or_create(user_id=user_id, group_id=group)
|
||||
return (
|
||||
f"开箱总数:{user.total_count}\n"
|
||||
f"今日开箱:{user.today_open_total}\n"
|
||||
@@ -294,7 +296,7 @@ async def total_open_statistics(user_qq: int, group: int) -> str:
|
||||
)
|
||||
|
||||
|
||||
async def group_statistics(group: int):
|
||||
async def group_statistics(group: str):
|
||||
user_list = await OpenCasesUser.filter(group_id=group).all()
|
||||
# lan zi fen hong jin pricei
|
||||
uplist = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.0, 0, 0]
|
||||
@@ -330,19 +332,19 @@ async def group_statistics(group: int):
|
||||
)
|
||||
|
||||
|
||||
async def get_my_knifes(user_id: int, group_id: int) -> Union[str, MessageSegment]:
|
||||
async def get_my_knifes(user_id: str, group_id: str) -> Union[str, MessageSegment]:
|
||||
"""获取我的金色
|
||||
|
||||
Args:
|
||||
user_id (int): 用户id
|
||||
group_id (int): 群号
|
||||
user_id (str): 用户id
|
||||
group_id (str): 群号
|
||||
|
||||
Returns:
|
||||
Union[str, MessageSegment]: 回复消息或图片
|
||||
"""
|
||||
data_list = await get_old_knife(user_id, group_id)
|
||||
data_list += await OpenCasesLog.filter(
|
||||
user_qq=user_id, group_id=group_id, color="KNIFE"
|
||||
user_id=user_id, group_id=group_id, color="KNIFE"
|
||||
).all()
|
||||
if not data_list:
|
||||
return "您木有开出金色级别的皮肤喔"
|
||||
@@ -377,17 +379,17 @@ async def get_my_knifes(user_id: int, group_id: int) -> Union[str, MessageSegmen
|
||||
return image(A)
|
||||
|
||||
|
||||
async def get_old_knife(user_id: int, group_id: int) -> List[OpenCasesLog]:
|
||||
async def get_old_knife(user_id: str, group_id: str) -> List[OpenCasesLog]:
|
||||
"""获取旧数据字段
|
||||
|
||||
Args:
|
||||
user_id (int): 用户id
|
||||
group_id (int): 群号
|
||||
user_id (str): 用户id
|
||||
group_id (str): 群号
|
||||
|
||||
Returns:
|
||||
List[OpenCasesLog]: 旧数据兼容
|
||||
"""
|
||||
user, _ = await OpenCasesUser.get_or_create(user_qq=user_id, group_id=group_id)
|
||||
user, _ = await OpenCasesUser.get_or_create(user_id=user_id, group_id=group_id)
|
||||
knifes_name = user.knifes_name
|
||||
data_list = []
|
||||
if knifes_name:
|
||||
@@ -406,7 +408,7 @@ async def get_old_knife(user_id: int, group_id: int) -> List[OpenCasesLog]:
|
||||
name = name.replace("(StatTrak™)", "")
|
||||
data_list.append(
|
||||
OpenCasesLog(
|
||||
user_qq=user_id,
|
||||
user_id=user_id,
|
||||
group_id=group_id,
|
||||
name=name.strip(),
|
||||
case_name=case_name_py.strip(),
|
||||
|
||||
@@ -3,7 +3,7 @@ import os
|
||||
import random
|
||||
import re
|
||||
import time
|
||||
from datetime import datetime
|
||||
from datetime import datetime, timedelta
|
||||
from typing import List, Optional, Tuple, Union
|
||||
|
||||
import nonebot
|
||||
@@ -13,7 +13,7 @@ from configs.config import Config
|
||||
from configs.path_config import IMAGE_PATH
|
||||
from services.log import logger
|
||||
from utils.http_utils import AsyncHttpx
|
||||
from utils.image_utils import BuildImage
|
||||
from utils.image_utils import BuildImage, BuildMat
|
||||
from utils.utils import broadcast_group, cn2py
|
||||
|
||||
from .build_image import generate_skin
|
||||
@@ -547,6 +547,49 @@ async def get_skin_case(id_: str) -> Optional[List[str]]:
|
||||
return None
|
||||
|
||||
|
||||
async def init_skin_trends(
|
||||
name: str, skin: str, abrasion: str, day: int = 7
|
||||
) -> Optional[BuildMat]:
|
||||
date = datetime.now() - timedelta(days=day)
|
||||
log_list = (
|
||||
await BuffSkinLog.filter(
|
||||
name__contains=name.upper(),
|
||||
skin_name=skin,
|
||||
abrasion__contains=abrasion,
|
||||
create_time__gt=date,
|
||||
is_stattrak=False,
|
||||
)
|
||||
.order_by("create_time")
|
||||
.limit(day * 5)
|
||||
.all()
|
||||
)
|
||||
if not log_list:
|
||||
return None
|
||||
date_list = []
|
||||
price_list = []
|
||||
for log in log_list:
|
||||
date = str(log.create_time.date())
|
||||
if date not in date_list:
|
||||
date_list.append(date)
|
||||
price_list.append(log.sell_min_price)
|
||||
bar_graph = BuildMat(
|
||||
y=price_list,
|
||||
mat_type="line",
|
||||
title=f"{name}({skin})价格趋势({day})",
|
||||
x_index=date_list,
|
||||
x_min_spacing=90,
|
||||
display_num=True,
|
||||
x_rotate=30,
|
||||
background=[
|
||||
f"{IMAGE_PATH}/background/create_mat/{x}"
|
||||
for x in os.listdir(f"{IMAGE_PATH}/background/create_mat")
|
||||
],
|
||||
bar_color=["*"],
|
||||
)
|
||||
await asyncio.get_event_loop().run_in_executor(None, bar_graph.gen_graph)
|
||||
return bar_graph
|
||||
|
||||
|
||||
async def reset_count_daily():
|
||||
"""
|
||||
重置每日开箱
|
||||
|
||||
@@ -6,14 +6,12 @@ from services.db_context import Model
|
||||
|
||||
|
||||
class PixivKeywordUser(Model):
|
||||
__tablename__ = "pixiv_keyword_users"
|
||||
__table_args__ = {"extend_existing": True}
|
||||
|
||||
id = fields.IntField(pk=True, generated=True, auto_increment=True)
|
||||
"""自增id"""
|
||||
user_qq = fields.BigIntField()
|
||||
user_id = fields.CharField(255)
|
||||
"""用户id"""
|
||||
group_id = fields.BigIntField()
|
||||
group_id = fields.CharField(255)
|
||||
"""群聊id"""
|
||||
keyword = fields.CharField(255, unique=True)
|
||||
"""关键词"""
|
||||
@@ -46,9 +44,17 @@ class PixivKeywordUser(Model):
|
||||
获取黑名单PID
|
||||
"""
|
||||
black_pid = []
|
||||
keyword_list = await cls.filter(user_qq=114514).values_list(
|
||||
keyword_list = await cls.filter(user_id="114514").values_list(
|
||||
"keyword", flat=True
|
||||
)
|
||||
for image in keyword_list:
|
||||
black_pid.append(image[6:])
|
||||
return black_pid
|
||||
|
||||
@classmethod
|
||||
async def _run_script(cls):
|
||||
return [
|
||||
"ALTER TABLE pixiv_keyword_users RENAME COLUMN user_qq TO user_id;", # 将user_qq改为user_id
|
||||
"ALTER TABLE pixiv_keyword_users ALTER COLUMN user_id TYPE character varying(255);",
|
||||
"ALTER TABLE pixiv_keyword_users ALTER COLUMN group_id TYPE character varying(255);",
|
||||
]
|
||||
|
||||
@@ -54,8 +54,8 @@ async def _(bot: Bot, event: MessageEvent, arg: Message = CommandArg()):
|
||||
# ):
|
||||
if not await PixivKeywordUser.exists(keyword=msg):
|
||||
await PixivKeywordUser.create(
|
||||
user_qq=event.user_id,
|
||||
group_id=group_id,
|
||||
user_id=str(event.user_id),
|
||||
group_id=str(group_id),
|
||||
keyword=msg,
|
||||
is_pass=str(event.user_id) in bot.config.superusers,
|
||||
)
|
||||
@@ -104,8 +104,8 @@ async def _(
|
||||
# ):
|
||||
if not await PixivKeywordUser.exists(keyword=msg):
|
||||
await PixivKeywordUser.create(
|
||||
user_qq=event.user_id,
|
||||
group_id=group_id,
|
||||
user_id=str(event.user_id),
|
||||
group_id=str(group_id),
|
||||
keyword=msg,
|
||||
is_pass=str(event.user_id) in bot.config.superusers,
|
||||
)
|
||||
@@ -138,7 +138,7 @@ async def _(bot: Bot, event: MessageEvent, arg: Message = CommandArg()):
|
||||
keyword=f"black:{pid}{f'_p{img_p}' if img_p else ''}"
|
||||
):
|
||||
await PixivKeywordUser.create(
|
||||
user_qq=114514,
|
||||
user_id=114514,
|
||||
group_id=114514,
|
||||
keyword=f"black:{pid}{f'_p{img_p}' if img_p else ''}",
|
||||
is_pass=str(event.user_id) in bot.config.superusers,
|
||||
|
||||
@@ -110,8 +110,8 @@ async def _(bot: Bot, event: MessageEvent, arg: Message = CommandArg()):
|
||||
keyword=f"black:{pid}{f'_p{img_p}' if img_p else ''}"
|
||||
):
|
||||
await PixivKeywordUser.create(
|
||||
user_qq=114514,
|
||||
group_id=114514,
|
||||
user_id="114514",
|
||||
group_id="114514",
|
||||
keyword=f"black:{pid}{f'_p{img_p}' if img_p else ''}",
|
||||
is_pass=False,
|
||||
)
|
||||
@@ -168,7 +168,7 @@ async def _(
|
||||
if data:
|
||||
data.is_pass = flag
|
||||
await data.save(update_fields=["is_pass"])
|
||||
user_id, group_id = data.user_qq, data.group_id
|
||||
user_id, group_id = data.user_id, data.group_id
|
||||
if not user_id:
|
||||
await pass_keyword.send(f"未找到关键词/UID:{x},请检查关键词/UID是否存在...")
|
||||
continue
|
||||
|
||||
@@ -37,7 +37,7 @@ show_pix = on_command("查看pix图库", priority=1, block=True)
|
||||
|
||||
@my_keyword.handle()
|
||||
async def _(event: MessageEvent):
|
||||
data = await PixivKeywordUser.filter(user_qq=event.user_id).values_list(
|
||||
data = await PixivKeywordUser.filter(user_id=str(event.user_id)).values_list(
|
||||
"keyword", flat=True
|
||||
)
|
||||
if not data:
|
||||
|
||||
@@ -14,6 +14,7 @@ from models.group_member_info import GroupInfoUser
|
||||
from services.log import logger
|
||||
from utils.message_builder import at, image
|
||||
from utils.utils import get_message_at, is_number
|
||||
|
||||
from .data_source import rank
|
||||
from .model import RussianUser
|
||||
|
||||
@@ -445,10 +446,10 @@ async def end_game(bot: Bot, event: GroupMessageEvent):
|
||||
await BagUser.add_gold(win_user_id, event.group_id, money - fee)
|
||||
await BagUser.spend_gold(lose_user_id, event.group_id, money)
|
||||
win_user, _ = await RussianUser.get_or_create(
|
||||
user_qq=win_user_id, group_id=event.group_id
|
||||
user_id=str(win_user_id), group_id=str(event.group_id)
|
||||
)
|
||||
lose_user, _ = await RussianUser.get_or_create(
|
||||
user_qq=lose_user_id, group_id=event.group_id
|
||||
user_id=str(lose_user_id), group_id=str(event.group_id)
|
||||
)
|
||||
bullet_str = ""
|
||||
for x in rs_player[event.group_id]["bullet"]:
|
||||
@@ -476,7 +477,7 @@ async def end_game(bot: Bot, event: GroupMessageEvent):
|
||||
@record.handle()
|
||||
async def _(event: GroupMessageEvent):
|
||||
user, _ = await RussianUser.get_or_create(
|
||||
user_qq=event.user_id, group_id=event.group_id
|
||||
user_id=str(event.user_id), group_id=str(event.group_id)
|
||||
)
|
||||
await record.send(
|
||||
f"俄罗斯轮盘\n"
|
||||
|
||||
@@ -8,7 +8,7 @@ from .model import RussianUser
|
||||
|
||||
async def rank(group_id: int, itype: str, num: int) -> Optional[BuildMat]:
|
||||
all_users = await RussianUser.filter(group_id=group_id).all()
|
||||
all_user_id = [user.user_qq for user in all_users]
|
||||
all_user_id = [user.user_id for user in all_users]
|
||||
if itype == "win_rank":
|
||||
rank_name = "胜场排行榜"
|
||||
all_user_data = [user.win_count for user in all_users]
|
||||
|
||||
+17
-10
@@ -1,4 +1,3 @@
|
||||
|
||||
from tortoise import fields
|
||||
|
||||
from services.db_context import Model
|
||||
@@ -8,9 +7,9 @@ class RussianUser(Model):
|
||||
|
||||
id = fields.IntField(pk=True, generated=True, auto_increment=True)
|
||||
"""自增id"""
|
||||
user_qq = fields.BigIntField()
|
||||
user_id = fields.CharField(255)
|
||||
"""用户id"""
|
||||
group_id = fields.BigIntField()
|
||||
group_id = fields.CharField(255)
|
||||
"""群聊id"""
|
||||
win_count = fields.IntField(default=0)
|
||||
"""胜利次数"""
|
||||
@@ -32,19 +31,19 @@ class RussianUser(Model):
|
||||
class Meta:
|
||||
table = "russian_users"
|
||||
table_description = "俄罗斯轮盘数据表"
|
||||
unique_together = ("user_qq", "group_id")
|
||||
unique_together = ("user_id", "group_id")
|
||||
|
||||
@classmethod
|
||||
async def add_count(cls, user_qq: int, group_id: int, itype: str):
|
||||
async def add_count(cls, user_id: str, group_id: str, itype: str):
|
||||
"""
|
||||
说明:
|
||||
添加用户输赢次数
|
||||
说明:
|
||||
:param user_qq: qq号
|
||||
:param user_id: qq号
|
||||
:param group_id: 群号
|
||||
:param itype: 输或赢 'win' or 'lose'
|
||||
"""
|
||||
user, _ = await cls.get_or_create(user_qq=user_qq, group_id=group_id)
|
||||
user, _ = await cls.get_or_create(user_id=user_id, group_id=group_id)
|
||||
if itype == "win":
|
||||
_max = (
|
||||
user.max_winning_streak
|
||||
@@ -83,19 +82,27 @@ class RussianUser(Model):
|
||||
)
|
||||
|
||||
@classmethod
|
||||
async def money(cls, user_qq: int, group_id: int, itype: str, count: int) -> bool:
|
||||
async def money(cls, user_id: str, group_id: str, itype: str, count: int) -> bool:
|
||||
"""
|
||||
说明:
|
||||
添加用户输赢金钱
|
||||
参数:
|
||||
:param user_qq: qq号
|
||||
:param user_id: qq号
|
||||
:param group_id: 群号
|
||||
:param itype: 输或赢 'win' or 'lose'
|
||||
:param count: 金钱数量
|
||||
"""
|
||||
user, _ = await cls.get_or_create(user_qq=user_qq, group_id=group_id)
|
||||
user, _ = await cls.get_or_create(user_id=str(user_id), group_id=group_id)
|
||||
if itype == "win":
|
||||
user.make_money = user.make_money + count
|
||||
elif itype == "lose":
|
||||
user.lose_money = user.lose_money + count
|
||||
await user.save(update_fields=["make_money", "lose_money"])
|
||||
|
||||
@classmethod
|
||||
async def _run_script(cls):
|
||||
return [
|
||||
"ALTER TABLE russian_users RENAME COLUMN user_qq TO user_id;", # 将user_qq改为user_id
|
||||
"ALTER TABLE russian_users ALTER COLUMN user_id TYPE character varying(255);",
|
||||
"ALTER TABLE russian_users ALTER COLUMN group_id TYPE character varying(255);",
|
||||
]
|
||||
|
||||
@@ -23,46 +23,48 @@ from .utils import SIGN_TODAY_CARD_PATH, get_card
|
||||
|
||||
|
||||
async def group_user_check_in(
|
||||
nickname: str, user_qq: int, group: int
|
||||
nickname: str, user_id: int, group: int
|
||||
) -> MessageSegment:
|
||||
"Returns string describing the result of checking in"
|
||||
present = datetime.now()
|
||||
# 取得相应用户
|
||||
user, is_create = await SignGroupUser.get_or_create(user_id=str(user_qq), group_id=str(group))
|
||||
user, is_create = await SignGroupUser.get_or_create(
|
||||
user_id=str(user_id), group_id=str(group)
|
||||
)
|
||||
# 如果同一天签到过,特殊处理
|
||||
if not is_create and (
|
||||
user.checkin_time_last.date() >= present.date()
|
||||
or f"{user}_{group}_sign_{datetime.now().date()}"
|
||||
in os.listdir(SIGN_TODAY_CARD_PATH)
|
||||
):
|
||||
gold = await BagUser.get_gold(user_qq, group)
|
||||
gold = await BagUser.get_gold(user_id, group)
|
||||
return await get_card(user, nickname, -1, gold, "")
|
||||
return await _handle_check_in(nickname, user_qq, group, present) # ok
|
||||
return await _handle_check_in(nickname, user_id, group, present) # ok
|
||||
|
||||
|
||||
async def check_in_all(nickname: str, user_qq: int):
|
||||
async def check_in_all(nickname: str, user_id: str):
|
||||
"""
|
||||
说明:
|
||||
签到所有群
|
||||
参数:
|
||||
:param nickname: 昵称
|
||||
:param user_qq: 用户qq
|
||||
:param user_id: 用户id
|
||||
"""
|
||||
present = datetime.now()
|
||||
for u in await SignGroupUser.filter(user_id=str(user_qq)).all():
|
||||
for u in await SignGroupUser.filter(user_id=user_id).all():
|
||||
group = u.group_id
|
||||
if not (
|
||||
u.checkin_time_last.date() >= present.date()
|
||||
or f"{u}_{group}_sign_{datetime.now().date()}"
|
||||
in os.listdir(SIGN_TODAY_CARD_PATH)
|
||||
):
|
||||
await _handle_check_in(nickname, user_qq, group, present)
|
||||
await _handle_check_in(nickname, user_id, group, present)
|
||||
|
||||
|
||||
async def _handle_check_in(
|
||||
nickname: str, user_qq: int, group: int, present: datetime
|
||||
nickname: str, user_id: str, group: str, present: datetime
|
||||
) -> MessageSegment:
|
||||
user, _ = await SignGroupUser.get_or_create(user_id=str(user_qq), group_id=str(group))
|
||||
user, _ = await SignGroupUser.get_or_create(user_id=user_id, group_id=group)
|
||||
impression_added = (secrets.randbelow(99) + 1) / 100
|
||||
critx2 = random.random()
|
||||
add_probability = float(user.add_probability)
|
||||
@@ -75,11 +77,11 @@ async def _handle_check_in(
|
||||
gold = random.randint(1, 100)
|
||||
gift, gift_type = random_event(float(user.impression))
|
||||
if gift_type == "gold":
|
||||
await BagUser.add_gold(user_qq, group, gold + gift)
|
||||
await BagUser.add_gold(user_id, group, gold + gift)
|
||||
gift = f"额外金币 + {gift}"
|
||||
else:
|
||||
await BagUser.add_gold(user_qq, group, gold)
|
||||
await BagUser.add_property(user_qq, group, gift)
|
||||
await BagUser.add_gold(user_id, group, gold)
|
||||
await BagUser.add_property(user_id, group, gift)
|
||||
gift += " + 1"
|
||||
|
||||
logger.info(
|
||||
@@ -93,10 +95,12 @@ async def _handle_check_in(
|
||||
return await get_card(user, nickname, impression_added, gold, gift)
|
||||
|
||||
|
||||
async def group_user_check(nickname: str, user_qq: int, group: int) -> MessageSegment:
|
||||
async def group_user_check(nickname: str, user_id: str, group: str) -> MessageSegment:
|
||||
# heuristic: if users find they have never checked in they are probable to check in
|
||||
user, _ = await SignGroupUser.get_or_create(user_id=str(user_qq), group_id=str(group))
|
||||
gold = await BagUser.get_gold(user_qq, group)
|
||||
user, _ = await SignGroupUser.get_or_create(
|
||||
user_id=str(user_id), group_id=str(group)
|
||||
)
|
||||
gold = await BagUser.get_gold(user_id, group)
|
||||
return await get_card(user, nickname, None, gold, "", is_card_view=True)
|
||||
|
||||
|
||||
@@ -171,7 +175,9 @@ async def _pst(users: list, impressions: list, groups: list):
|
||||
impressions.pop(index)
|
||||
users.pop(index)
|
||||
groups.pop(index)
|
||||
if user_ := await GroupInfoUser.get_or_none(user_id=str(user), group_id=str(group)):
|
||||
if user_ := await GroupInfoUser.get_or_none(
|
||||
user_id=str(user), group_id=str(group)
|
||||
):
|
||||
user_name = user_.user_name
|
||||
else:
|
||||
user_name = f"我名字呢?"
|
||||
|
||||
@@ -9,9 +9,9 @@ class Statistics(Model):
|
||||
|
||||
id = fields.IntField(pk=True, generated=True, auto_increment=True)
|
||||
"""自增id"""
|
||||
user_qq = fields.BigIntField()
|
||||
user_id = fields.CharField(255)
|
||||
"""用户id"""
|
||||
group_id = fields.BigIntField(null=True)
|
||||
group_id = fields.CharField(255, null=True)
|
||||
"""群聊id"""
|
||||
plugin_name = fields.CharField(255)
|
||||
"""插件名称"""
|
||||
@@ -21,3 +21,11 @@ class Statistics(Model):
|
||||
class Meta:
|
||||
table = "statistics"
|
||||
table_description = "用户权限数据库"
|
||||
|
||||
@classmethod
|
||||
async def _run_script(cls):
|
||||
return [
|
||||
"ALTER TABLE statistics RENAME COLUMN user_qq TO user_id;", # 将user_qq改为user_id
|
||||
"ALTER TABLE statistics ALTER COLUMN user_id TYPE character varying(255);",
|
||||
"ALTER TABLE statistics ALTER COLUMN group_id TYPE character varying(255);",
|
||||
]
|
||||
@@ -102,7 +102,7 @@ async def _(
|
||||
and matcher.plugin_name not in ["update_info", "statistics_handle"]
|
||||
):
|
||||
await Statistics.create(
|
||||
user_qq=event.user_id,
|
||||
user_id=str(event.user_id),
|
||||
group_id=getattr(event, "group_id", None),
|
||||
plugin_name=matcher.plugin_name,
|
||||
create_time=datetime.now(),
|
||||
|
||||
@@ -1,15 +1,21 @@
|
||||
import asyncio
|
||||
|
||||
import nonebot
|
||||
from fastapi import APIRouter, FastAPI
|
||||
from nonebot.adapters.onebot.v11 import Bot, MessageEvent
|
||||
from nonebot.log import default_filter, default_format
|
||||
from nonebot.matcher import Matcher
|
||||
from nonebot.message import run_preprocessor
|
||||
from nonebot.typing import T_State
|
||||
|
||||
from configs.config import Config as gConfig
|
||||
from services.log import logger
|
||||
from services.log import logger, logger_
|
||||
from utils.manager import plugins2settings_manager
|
||||
|
||||
from .api.base_info import router as base_info_routes
|
||||
from .api.group import router as group_routes
|
||||
from .api.logs import router as ws_routes
|
||||
from .api.logs.log_manager import LOG_STORAGE
|
||||
from .api.plugins import router as plugin_routes
|
||||
from .api.request import router as request_routes
|
||||
from .api.system import router as system_routes
|
||||
@@ -31,10 +37,20 @@ BaseApiRouter.include_router(plugin_routes)
|
||||
BaseApiRouter.include_router(group_routes)
|
||||
BaseApiRouter.include_router(request_routes)
|
||||
BaseApiRouter.include_router(system_routes)
|
||||
BaseApiRouter.include_router(base_info_routes)
|
||||
|
||||
|
||||
@driver.on_startup
|
||||
def _():
|
||||
|
||||
loop = asyncio.get_running_loop()
|
||||
|
||||
def log_sink(message: str):
|
||||
loop.create_task(LOG_STORAGE.add(message.rstrip("\n")))
|
||||
|
||||
logger_.add(log_sink, colorize=True, filter=default_filter, format=default_format)
|
||||
|
||||
app: FastAPI = nonebot.get_app()
|
||||
app.include_router(BaseApiRouter)
|
||||
app.include_router(ws_routes)
|
||||
logger.info("<g>API启动成功</g>", "Web UI")
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
from datetime import datetime, timedelta
|
||||
from typing import List, Optional
|
||||
|
||||
import nonebot
|
||||
from fastapi import APIRouter
|
||||
|
||||
from configs.config import Config
|
||||
from models.chat_history import ChatHistory
|
||||
from services.log import logger
|
||||
from utils.manager import plugin_data_manager, plugins2settings_manager, plugins_manager
|
||||
from utils.manager.models import PluginData, PluginType
|
||||
|
||||
from ..models.model import BotInfo, Result
|
||||
from ..models.params import UpdateConfig, UpdatePlugin
|
||||
from ..utils import authentication
|
||||
|
||||
AVA_URL = "http://q1.qlogo.cn/g?b=qq&nk={}&s=160"
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
@router.get("/get_bot_info", dependencies=[authentication()])
|
||||
async def _(self_id: Optional[str] = None) -> Result:
|
||||
"""
|
||||
获取Bot基础信息
|
||||
|
||||
Args:
|
||||
qq (Optional[str], optional): qq号. Defaults to None.
|
||||
|
||||
Returns:
|
||||
Result: 获取指定bot信息与bot列表
|
||||
"""
|
||||
bot_list: List[BotInfo] = []
|
||||
if bots := nonebot.get_bots():
|
||||
select_bot: BotInfo
|
||||
for key, bot in bots.items():
|
||||
bot_list.append(
|
||||
BotInfo(
|
||||
bot=bot, # type: ignore
|
||||
self_id=bot.self_id,
|
||||
nickname="可爱的小真寻",
|
||||
ava_url=AVA_URL.format(bot.self_id),
|
||||
)
|
||||
)
|
||||
if _bl := [b for b in bot_list if b.self_id == self_id]:
|
||||
select_bot = _bl[0]
|
||||
else:
|
||||
select_bot = bot_list[0]
|
||||
select_bot.is_select = True
|
||||
now = datetime.now()
|
||||
select_bot.received_messages = await ChatHistory.filter(
|
||||
bot_id=int(select_bot.self_id)
|
||||
).count()
|
||||
select_bot.received_messages_day = await ChatHistory.filter(
|
||||
bot_id=int(select_bot.self_id),
|
||||
create_time__gte=now - timedelta(hours=now.hour),
|
||||
).count()
|
||||
select_bot.received_messages_week = await ChatHistory.filter(
|
||||
bot_id=int(select_bot.self_id),
|
||||
create_time__gte=now - timedelta(days=7),
|
||||
).count()
|
||||
select_bot.group_count = len(await select_bot.bot.get_group_list())
|
||||
select_bot.friend_count = len(await select_bot.bot.get_friend_list())
|
||||
for bot in bot_list:
|
||||
bot.bot = None # type: ignore
|
||||
# 插件加载数量
|
||||
select_bot.plugin_count = len(plugins2settings_manager)
|
||||
pm_data = plugins_manager.get_data()
|
||||
select_bot.fail_plugin_count = len([pd for pd in pm_data if pm_data[pd].error])
|
||||
select_bot.success_plugin_count = (
|
||||
select_bot.plugin_count - select_bot.fail_plugin_count
|
||||
)
|
||||
|
||||
return Result.ok(bot_list, "已获取操作列表")
|
||||
return Result.fail("无Bot连接")
|
||||
@@ -0,0 +1 @@
|
||||
from .logs import *
|
||||
@@ -0,0 +1,45 @@
|
||||
import asyncio
|
||||
import re
|
||||
from typing import Awaitable, Callable, ClassVar, Dict, Generic, List, Set, TypeVar
|
||||
from urllib.parse import urlparse
|
||||
|
||||
PATTERN = r"\x1b(\[.*?[@-~]|\].*?(\x07|\x1b\\))"
|
||||
|
||||
_T = TypeVar("_T")
|
||||
LogListener = Callable[[_T], Awaitable[None]]
|
||||
|
||||
|
||||
class LogStorage(Generic[_T]):
|
||||
def __init__(self, rotation: float = 5 * 60):
|
||||
self.count, self.rotation = 0, rotation
|
||||
self.logs: Dict[int, str] = {}
|
||||
self.listeners: Set[LogListener[str]] = set()
|
||||
|
||||
async def add(self, log: str):
|
||||
log = re.sub(PATTERN, "", log)
|
||||
log_split = log.split()
|
||||
time = log_split[0] + " " + log_split[1]
|
||||
level = log_split[2]
|
||||
main = log_split[3]
|
||||
type_ = None
|
||||
log_ = " ".join(log_split[3:])
|
||||
if "Calling API" in log_:
|
||||
sp = log_.split("|")
|
||||
type_ = sp[1]
|
||||
log_ = "|".join(log_[1:])
|
||||
data = {"time": time, "level": level, "main": main, "type": type_, "log": log_}
|
||||
seq = self.count = self.count + 1
|
||||
self.logs[seq] = log
|
||||
asyncio.get_running_loop().call_later(self.rotation, self.remove, seq)
|
||||
await asyncio.gather(
|
||||
*map(lambda listener: listener(log), self.listeners),
|
||||
return_exceptions=True,
|
||||
)
|
||||
return seq
|
||||
|
||||
def remove(self, seq: int):
|
||||
del self.logs[seq]
|
||||
return
|
||||
|
||||
|
||||
LOG_STORAGE = LogStorage[str]()
|
||||
@@ -0,0 +1,37 @@
|
||||
from typing import List
|
||||
|
||||
from fastapi import APIRouter, WebSocket
|
||||
from loguru import logger
|
||||
from nonebot.utils import escape_tag, run_sync
|
||||
from starlette.websockets import WebSocket, WebSocketDisconnect, WebSocketState
|
||||
|
||||
from .log_manager import LOG_STORAGE
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
@router.get("/logs", response_model=List[str])
|
||||
async def system_logs_history(reverse: bool = False):
|
||||
return LOG_STORAGE.list(reverse=reverse)
|
||||
|
||||
|
||||
@router.websocket("/logs")
|
||||
async def system_logs_realtime(websocket: WebSocket):
|
||||
await websocket.accept()
|
||||
|
||||
async def log_listener(log: str):
|
||||
await websocket.send_text(log)
|
||||
|
||||
LOG_STORAGE.listeners.add(log_listener)
|
||||
try:
|
||||
while websocket.client_state == WebSocketState.CONNECTED:
|
||||
recv = await websocket.receive()
|
||||
logger.trace(
|
||||
f"{system_logs_realtime.__name__!r} received "
|
||||
f"<e>{escape_tag(repr(recv))}</e>"
|
||||
)
|
||||
except WebSocketDisconnect:
|
||||
pass
|
||||
finally:
|
||||
LOG_STORAGE.listeners.remove(log_listener)
|
||||
return
|
||||
@@ -1,6 +1,7 @@
|
||||
from datetime import datetime
|
||||
from typing import Any, Dict, List, Optional, TypeVar, Union
|
||||
|
||||
from nonebot.adapters.onebot.v11 import Bot
|
||||
from pydantic import BaseModel
|
||||
|
||||
from configs.utils import Config
|
||||
@@ -180,3 +181,43 @@ class SystemResult(BaseModel):
|
||||
network: SystemNetwork
|
||||
disk: SystemFolderSize
|
||||
check_time: datetime
|
||||
|
||||
|
||||
class BotInfo(BaseModel):
|
||||
"""
|
||||
Bot基础信息
|
||||
"""
|
||||
|
||||
bot: Bot
|
||||
"""Bot"""
|
||||
self_id: str
|
||||
"""SELF ID"""
|
||||
nickname: str
|
||||
"""昵称"""
|
||||
ava_url: str
|
||||
"""头像url"""
|
||||
friend_count: int = 0
|
||||
"""好友数量"""
|
||||
group_count: int = 0
|
||||
"""群聊数量"""
|
||||
received_messages: int = 0
|
||||
"""累计接收消息"""
|
||||
received_messages_day: int = 0
|
||||
"""今日累计接收消息"""
|
||||
received_messages_week: int = 0
|
||||
"""一周内累计接收消息"""
|
||||
received_messages_month: int = 0
|
||||
"""一月内累计接收消息"""
|
||||
|
||||
plugin_count: int = 0
|
||||
"""加载插件数量"""
|
||||
success_plugin_count: int = 0
|
||||
"""加载成功插件数量"""
|
||||
fail_plugin_count: int = 0
|
||||
"""加载失败插件数量"""
|
||||
|
||||
is_select: bool = False
|
||||
"""当前选择"""
|
||||
|
||||
class Config:
|
||||
arbitrary_types_allowed = True
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
import random
|
||||
import time
|
||||
from pathlib import Path
|
||||
from typing import Any, List, Optional, Tuple, Union
|
||||
|
||||
import nonebot
|
||||
from nonebot.adapters.onebot.v11 import Message, MessageSegment
|
||||
|
||||
from services import logger
|
||||
from utils.image_utils import text2image
|
||||
from utils.message_builder import image
|
||||
from ._model import WordBank
|
||||
from typing import Optional, Tuple, Union, List, Any
|
||||
from utils.utils import is_number
|
||||
import nonebot
|
||||
|
||||
from ._model import WordBank
|
||||
|
||||
driver = nonebot.get_driver()
|
||||
|
||||
@@ -197,7 +198,7 @@ async def _():
|
||||
new_answer_path.mkdir(exist_ok=True, parents=True)
|
||||
for word in word_list:
|
||||
problem: str = word.problem
|
||||
user_id = word.user_qq
|
||||
user_id = word.user_id
|
||||
group_id = word.group_id
|
||||
format_ = word.format
|
||||
answer = word.answer
|
||||
|
||||
+20
-17
@@ -31,9 +31,9 @@ class WordBank(Model):
|
||||
|
||||
id = fields.IntField(pk=True, generated=True, auto_increment=True)
|
||||
"""自增id"""
|
||||
user_qq = fields.BigIntField()
|
||||
user_id = fields.CharField(255)
|
||||
"""用户id"""
|
||||
group_id = fields.BigIntField(null=True)
|
||||
group_id = fields.CharField(255, null=True)
|
||||
"""群聊id"""
|
||||
word_scope = fields.IntField(default=0)
|
||||
"""生效范围 0: 全局 1: 群聊 2: 私聊"""
|
||||
@@ -63,8 +63,8 @@ class WordBank(Model):
|
||||
@classmethod
|
||||
async def exists(
|
||||
cls,
|
||||
user_id: Optional[int],
|
||||
group_id: Optional[int],
|
||||
user_id: Optional[str],
|
||||
group_id: Optional[str],
|
||||
problem: str,
|
||||
answer: Optional[str],
|
||||
word_scope: Optional[int] = None,
|
||||
@@ -83,7 +83,7 @@ class WordBank(Model):
|
||||
"""
|
||||
query = cls.filter(problem=problem)
|
||||
if user_id:
|
||||
query = query.filter(user_qq=user_id)
|
||||
query = query.filter(user_id=user_id)
|
||||
if group_id:
|
||||
query = query.filter(group_id=group_id)
|
||||
if answer:
|
||||
@@ -97,8 +97,8 @@ class WordBank(Model):
|
||||
@classmethod
|
||||
async def add_problem_answer(
|
||||
cls,
|
||||
user_id: int,
|
||||
group_id: Optional[int],
|
||||
user_id: str,
|
||||
group_id: Optional[str],
|
||||
word_scope: int,
|
||||
word_type: int,
|
||||
problem: Union[str, Message],
|
||||
@@ -133,7 +133,7 @@ class WordBank(Model):
|
||||
user_id, group_id, str(problem), answer, word_scope, word_type
|
||||
):
|
||||
await cls.create(
|
||||
user_qq=user_id,
|
||||
user_id=user_id,
|
||||
group_id=group_id,
|
||||
word_scope=word_scope,
|
||||
word_type=word_type,
|
||||
@@ -149,7 +149,7 @@ class WordBank(Model):
|
||||
|
||||
@classmethod
|
||||
async def _answer2format(
|
||||
cls, answer: Union[str, Message], user_id: int, group_id: Optional[int]
|
||||
cls, answer: Union[str, Message], user_id: str, group_id: Optional[str]
|
||||
) -> Tuple[str, List[Any]]:
|
||||
"""
|
||||
说明:
|
||||
@@ -213,7 +213,7 @@ class WordBank(Model):
|
||||
if not query:
|
||||
query = await cls.get_or_none(
|
||||
problem=problem,
|
||||
user_qq=user_id,
|
||||
user_id=user_id,
|
||||
group_id=group_id,
|
||||
answer=answer,
|
||||
)
|
||||
@@ -311,7 +311,7 @@ class WordBank(Model):
|
||||
await cls._format2answer(
|
||||
random_answer.problem,
|
||||
random_answer.answer,
|
||||
random_answer.user_qq,
|
||||
random_answer.user_id,
|
||||
random_answer.group_id,
|
||||
random_answer,
|
||||
)
|
||||
@@ -351,7 +351,7 @@ class WordBank(Model):
|
||||
async def delete_group_problem(
|
||||
cls,
|
||||
problem: str,
|
||||
group_id: int,
|
||||
group_id: str,
|
||||
index: Optional[int] = None,
|
||||
word_scope: int = 1,
|
||||
):
|
||||
@@ -386,7 +386,7 @@ class WordBank(Model):
|
||||
cls,
|
||||
problem: str,
|
||||
replace_str: str,
|
||||
group_id: int,
|
||||
group_id: str,
|
||||
index: Optional[int] = None,
|
||||
word_scope: int = 1,
|
||||
):
|
||||
@@ -419,7 +419,7 @@ class WordBank(Model):
|
||||
|
||||
@classmethod
|
||||
async def get_group_all_problem(
|
||||
cls, group_id: int
|
||||
cls, group_id: str
|
||||
) -> List[Tuple[Any, Union[MessageSegment, str]]]:
|
||||
"""
|
||||
说明:
|
||||
@@ -480,8 +480,8 @@ class WordBank(Model):
|
||||
@classmethod
|
||||
async def _move(
|
||||
cls,
|
||||
user_id: int,
|
||||
group_id: Optional[int],
|
||||
user_id: str,
|
||||
group_id: Optional[str],
|
||||
problem: Union[str, Message],
|
||||
answer: Union[str, Message],
|
||||
placeholder: str,
|
||||
@@ -503,7 +503,7 @@ class WordBank(Model):
|
||||
user_id, group_id, problem, answer, word_scope, word_type
|
||||
):
|
||||
await cls.create(
|
||||
user_qq=user_id,
|
||||
user_id=user_id,
|
||||
group_id=group_id,
|
||||
word_scope=word_scope,
|
||||
word_type=word_type,
|
||||
@@ -522,4 +522,7 @@ class WordBank(Model):
|
||||
"ALTER TABLE word_bank2 ADD to_me varchar(255);", # 添加 to_me 字段
|
||||
"ALTER TABLE word_bank2 ALTER COLUMN create_time TYPE timestamp with time zone USING create_time::timestamp with time zone;",
|
||||
"ALTER TABLE word_bank2 ALTER COLUMN update_time TYPE timestamp with time zone USING update_time::timestamp with time zone;",
|
||||
"ALTER TABLE word_bank2 RENAME COLUMN user_qq TO user_id;", # 将user_qq改为user_id
|
||||
"ALTER TABLE word_bank2 ALTER COLUMN user_id TYPE character varying(255);",
|
||||
"ALTER TABLE word_bank2 ALTER COLUMN group_id TYPE character varying(255);",
|
||||
]
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
from services import logger
|
||||
from ._rule import check
|
||||
from ._model import WordBank
|
||||
from configs.path_config import DATA_PATH
|
||||
from nonebot.adapters.onebot.v11 import GroupMessageEvent, MessageEvent
|
||||
from nonebot import on_message
|
||||
from nonebot.adapters.onebot.v11 import GroupMessageEvent, MessageEvent
|
||||
from nonebot.typing import T_State
|
||||
|
||||
from configs.path_config import DATA_PATH
|
||||
from services import logger
|
||||
|
||||
from ._model import WordBank
|
||||
from ._rule import check
|
||||
|
||||
__zx_plugin_name__ = "词库问答回复操作 [Hidden]"
|
||||
|
||||
data_dir = DATA_PATH / "word_bank"
|
||||
@@ -20,7 +22,8 @@ async def _(event: MessageEvent, state: T_State):
|
||||
if msg := await WordBank.get_answer(event, problem):
|
||||
await message_handle.send(msg)
|
||||
logger.info(
|
||||
f"(USER {event.user_id}, GROUP "
|
||||
f"{event.group_id if isinstance(event, GroupMessageEvent) else 'private'})"
|
||||
f" 触发词条 {problem}"
|
||||
f" 触发词条 {problem}",
|
||||
"词条检测",
|
||||
event.user_id,
|
||||
getattr(event, "group_id", None),
|
||||
)
|
||||
|
||||
@@ -196,11 +196,11 @@ async def _(
|
||||
if problem and bot.config.nickname:
|
||||
nickname = [nk for nk in bot.config.nickname if problem.startswith(nk)]
|
||||
await WordBank.add_problem_answer(
|
||||
event.user_id,
|
||||
event.group_id
|
||||
str(event.user_id),
|
||||
str(event.group_id)
|
||||
if isinstance(event, GroupMessageEvent)
|
||||
and (not word_scope or word_scope == "私聊")
|
||||
else 0,
|
||||
else "0",
|
||||
scope2int[word_scope] if word_scope else 1,
|
||||
type2int[word_type] if word_type else 0,
|
||||
problem or problem_image,
|
||||
@@ -211,16 +211,16 @@ async def _(
|
||||
if isinstance(e, FinishedException):
|
||||
await add_word.finish()
|
||||
logger.error(
|
||||
f"(USER {event.user_id}, GROUP "
|
||||
f"{event.group_id if isinstance(event, GroupMessageEvent) else 'private'})"
|
||||
f" 添加词条 {problem} 发生错误 {type(e)}: {e} "
|
||||
f"添加词条 {problem} 错误...",
|
||||
"添加词条",
|
||||
event.user_id,
|
||||
getattr(event, "group_id", None),
|
||||
e=e,
|
||||
)
|
||||
await add_word.finish(f"添加词条 {problem} 发生错误!")
|
||||
await add_word.send("添加词条 " + (problem or problem_image) + " 成功!")
|
||||
logger.info(
|
||||
f"(USER {event.user_id}, GROUP "
|
||||
f"{event.group_id if isinstance(event, GroupMessageEvent) else 'private'})"
|
||||
f" 添加词条 {problem} 成功!"
|
||||
f"添加词条 {problem} 成功!", "添加词条", event.user_id, getattr(event, "group_id", None)
|
||||
)
|
||||
|
||||
|
||||
@@ -230,7 +230,7 @@ async def _(event: GroupMessageEvent, arg: Message = CommandArg()):
|
||||
await delete_word_matcher.finish("此命令之后需要跟随指定词条,通过“显示词条“查看")
|
||||
result = await delete_word(msg, event.group_id)
|
||||
await delete_word_matcher.send(result)
|
||||
logger.info(f"(USER {event.user_id}, GROUP " f"{event.group_id})" f" 删除词条:" + msg)
|
||||
logger.info(f"删除词条:" + msg, "删除词条", event.user_id, event.group_id)
|
||||
|
||||
|
||||
@delete_word_matcher.handle()
|
||||
@@ -246,7 +246,7 @@ async def _(
|
||||
await delete_word_matcher.finish("此命令之后需要跟随指定词条,通过“显示词条“查看")
|
||||
result = await delete_word(msg, word_scope=2 if cmd[0] == "删除词条" else 0)
|
||||
await delete_word_matcher.send(result)
|
||||
logger.info(f"(USER {event.user_id})" f" 删除词条:" + msg)
|
||||
logger.info(f"删除词条:" + msg, "删除词条", event.user_id)
|
||||
|
||||
|
||||
@update_word_matcher.handle()
|
||||
@@ -257,7 +257,7 @@ async def _(event: GroupMessageEvent, arg: Message = CommandArg()):
|
||||
await update_word_matcher.finish("此命令需要两个参数,请查看帮助")
|
||||
result = await update_word(msg, event.group_id)
|
||||
await update_word_matcher.send(result)
|
||||
logger.info(f"(USER {event.user_id}, GROUP " f"{event.group_id})" f" 更新词条词条:" + msg)
|
||||
logger.info(f"更新词条词条:" + msg, "更新词条", event.user_id, event.group_id)
|
||||
|
||||
|
||||
@update_word_matcher.handle()
|
||||
@@ -275,7 +275,7 @@ async def _(
|
||||
await update_word_matcher.finish("此命令需要两个参数,请查看帮助")
|
||||
result = await update_word(msg, word_scope=2 if cmd[0] == "修改词条" else 0)
|
||||
await update_word_matcher.send(result)
|
||||
logger.info(f"(USER {event.user_id})" f" 更新词条词条:" + msg)
|
||||
logger.info(f"更新词条词条:" + msg, "更新词条", event.user_id)
|
||||
|
||||
|
||||
@show_word_matcher.handle()
|
||||
@@ -288,7 +288,8 @@ async def _(bot: Bot, event: GroupMessageEvent, arg: Message = CommandArg()):
|
||||
if (
|
||||
not is_number(id_)
|
||||
or int(id_) < 0
|
||||
or int(id_) >= len(await WordBank.get_group_all_problem(event.group_id))
|
||||
or int(id_)
|
||||
>= len(await WordBank.get_group_all_problem(str(event.group_id)))
|
||||
):
|
||||
await show_word_matcher.finish("id必须为数字且在范围内")
|
||||
id_ = int(id_)
|
||||
@@ -311,9 +312,7 @@ async def _(bot: Bot, event: GroupMessageEvent, arg: Message = CommandArg()):
|
||||
group_id=event.group_id, messages=custom_forward_msg(msg_list, bot.self_id)
|
||||
)
|
||||
logger.info(
|
||||
f"(USER {event.user_id}, GROUP "
|
||||
f"{event.group_id if isinstance(event, GroupMessageEvent) else 'private'})"
|
||||
f" 发送查看词条回答:" + problem
|
||||
f"查看词条回答:" + problem, "显示词条", event.user_id, getattr(event, "group_id", None)
|
||||
)
|
||||
|
||||
|
||||
@@ -352,4 +351,6 @@ async def _(event: PrivateMessageEvent, arg: Message = CommandArg()):
|
||||
for msg in msg_list:
|
||||
t += msg + "\n"
|
||||
await show_word_matcher.send(t[:-1])
|
||||
logger.info(f"(USER {event.user_id}, GROUP " f"private)" f" 发送查看词条回答:" + problem)
|
||||
logger.info(
|
||||
f"查看词条回答:" + problem, "显示词条", event.user_id, getattr(event, "group_id", None)
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user