bugfix:修复sqlite部分场景下锁竞争问题;新增插件恶意触发配置文件 (#2144)

* bugfix:修复sqlite部分场景下锁竞争问题;新增插件恶意触发配置文件

* 文件没同步完
This commit is contained in:
Copaan
2026-06-24 09:11:03 +08:00
committed by GitHub
parent 73cbe2a609
commit f4d2342693
39 changed files with 1577 additions and 829 deletions
@@ -16,7 +16,7 @@ from zhenxun.utils.platform import PlatformUtils
from ....base_model import Result
from ....config import QueryDateType
from ....utils import authentication, get_system_status
from ....utils import DB_BUSY_MESSAGE, authentication, get_system_status
from .data_source import ApiDataSource
from .model import (
ActiveGroup,
@@ -82,6 +82,8 @@ async def _(bot_id: str | None = None) -> Result[list[BaseInfo]]:
if not result:
Result.warning_("无Bot连接...")
return Result.ok(result, "拿到信息啦!")
except TimeoutError:
return Result.fail(DB_BUSY_MESSAGE)
except Exception as e:
logger.error(f"{router.prefix}/get_base_info 调用错误", "WebUi", e=e)
return Result.fail(f"发生了一点错误捏 {type(e)}: {e}")
@@ -97,6 +99,8 @@ async def _(bot_id: str | None = None) -> Result[list[BaseInfo]]:
async def _(bot_id: str | None = None) -> Result[QueryCount]:
try:
return Result.ok(await ApiDataSource.get_all_chat_count(bot_id), "拿到信息啦!")
except TimeoutError:
return Result.fail(DB_BUSY_MESSAGE)
except Exception as e:
logger.error(f"{router.prefix}/get_all_chat_count 调用错误", "WebUi", e=e)
return Result.fail(f"发生了一点错误捏 {type(e)}: {e}")
@@ -112,6 +116,8 @@ async def _(bot_id: str | None = None) -> Result[QueryCount]:
async def _(bot_id: str | None = None) -> Result[QueryCount]:
try:
return Result.ok(await ApiDataSource.get_all_call_count(bot_id), "拿到信息啦!")
except TimeoutError:
return Result.fail(DB_BUSY_MESSAGE)
except Exception as e:
logger.error(f"{router.prefix}/get_all_call_count 调用错误", "WebUi", e=e)
return Result.fail(f"发生了一点错误捏 {type(e)}: {e}")
@@ -188,6 +194,8 @@ async def _(
return Result.ok(
await ApiDataSource.get_active_group(date_type, bot_id), "拿到信息啦!"
)
except TimeoutError:
return Result.fail(DB_BUSY_MESSAGE)
except Exception as e:
logger.error(f"{router.prefix}/get_active_group 调用错误", "WebUi", e=e)
return Result.fail(f"发生了一点错误捏 {type(e)}: {e}")
@@ -207,6 +215,8 @@ async def _(
return Result.ok(
await ApiDataSource.get_hot_plugin(date_type, bot_id), "拿到信息啦!"
)
except TimeoutError:
return Result.fail(DB_BUSY_MESSAGE)
except Exception as e:
logger.error(f"{router.prefix}/get_hot_plugin 调用错误", "WebUi", e=e)
return Result.fail(f"发生了一点错误捏 {type(e)}: {e}")
@@ -294,9 +304,14 @@ async def system_logs_realtime(websocket: WebSocket, sleep: int = 5):
await asyncio.wait_for(websocket.send_text(system_status.json()), timeout=5)
try:
await asyncio.wait_for(disconnect_event.wait(), timeout=max(sleep, 1))
except TimeoutError:
except asyncio.TimeoutError:
pass
except (WebSocketDisconnect, ConnectionClosedError, ConnectionClosedOK):
except (
asyncio.CancelledError,
WebSocketDisconnect,
ConnectionClosedError,
ConnectionClosedOK,
):
pass
finally:
_SYSTEM_STATUS_CONNECTIONS.discard(websocket)
@@ -20,6 +20,7 @@ from zhenxun.utils.enum import PluginType
from zhenxun.utils.platform import PlatformUtils
from ....config import AVA_URL, GROUP_AVA_URL, QueryDateType
from ....utils import webui_db_call
from .model import (
ActiveGroup,
BaseInfo,
@@ -105,10 +106,13 @@ class ApiDataSource:
"""
now = datetime.now()
# 今日累计接收消息
select_bot.received_messages = await ChatHistory.filter(
bot_id=select_bot.self_id,
create_time__gte=now - timedelta(hours=now.hour),
).count()
select_bot.received_messages = await webui_db_call(
ChatHistory.filter(
bot_id=select_bot.self_id,
create_time__gte=now - timedelta(hours=now.hour),
).count(),
"Main.received_messages",
)
# 群聊数量
try:
select_bot.group_count = len(
@@ -129,13 +133,15 @@ class ApiDataSource:
connect_date = datetime.fromtimestamp(select_bot.connect_time)
select_bot.connect_date = connect_date.strftime("%Y-%m-%d %H:%M:%S")
select_bot.version = cls.__get_bot_version()
day_call = await Statistics.filter(
create_time__gte=now - timedelta(hours=now.hour)
).count()
day_call = await webui_db_call(
Statistics.filter(create_time__gte=now - timedelta(hours=now.hour)).count(),
"Main.day_call",
)
select_bot.day_call = day_call
select_bot.connect_count = await BotConnectLog.filter(
bot_id=select_bot.self_id
).count()
select_bot.connect_count = await webui_db_call(
BotConnectLog.filter(bot_id=select_bot.self_id).count(),
"Main.connect_count",
)
@classmethod
async def get_base_info(cls, bot_id: str | None) -> list[BaseInfo] | None:
@@ -177,21 +183,37 @@ class ApiDataSource:
query = ChatHistory
if bot_id:
query = query.filter(bot_id=bot_id)
all_count = await query.annotate().count()
day_count = await query.filter(
create_time__gte=now - timedelta(hours=now.hour, minutes=now.minute)
).count()
week_count = await query.filter(
create_time__gte=now - timedelta(days=7, hours=now.hour, minutes=now.minute)
).count()
month_count = await query.filter(
create_time__gte=now
- timedelta(days=30, hours=now.hour, minutes=now.minute)
).count()
year_count = await query.filter(
create_time__gte=now
- timedelta(days=365, hours=now.hour, minutes=now.minute)
).count()
all_count = await webui_db_call(
query.annotate().count(),
"Main.chat_all_count",
)
day_count = await webui_db_call(
query.filter(
create_time__gte=now - timedelta(hours=now.hour, minutes=now.minute)
).count(),
"Main.chat_day_count",
)
week_count = await webui_db_call(
query.filter(
create_time__gte=now
- timedelta(days=7, hours=now.hour, minutes=now.minute)
).count(),
"Main.chat_week_count",
)
month_count = await webui_db_call(
query.filter(
create_time__gte=now
- timedelta(days=30, hours=now.hour, minutes=now.minute)
).count(),
"Main.chat_month_count",
)
year_count = await webui_db_call(
query.filter(
create_time__gte=now
- timedelta(days=365, hours=now.hour, minutes=now.minute)
).count(),
"Main.chat_year_count",
)
return QueryCount(
num=all_count,
day=day_count,
@@ -214,21 +236,37 @@ class ApiDataSource:
query = Statistics
if bot_id:
query = query.filter(bot_id=bot_id)
all_count = await query.annotate().count()
day_count = await query.filter(
create_time__gte=now - timedelta(hours=now.hour, minutes=now.minute)
).count()
week_count = await query.filter(
create_time__gte=now - timedelta(days=7, hours=now.hour, minutes=now.minute)
).count()
month_count = await query.filter(
create_time__gte=now
- timedelta(days=30, hours=now.hour, minutes=now.minute)
).count()
year_count = await query.filter(
create_time__gte=now
- timedelta(days=365, hours=now.hour, minutes=now.minute)
).count()
all_count = await webui_db_call(
query.annotate().count(),
"Main.call_all_count",
)
day_count = await webui_db_call(
query.filter(
create_time__gte=now - timedelta(hours=now.hour, minutes=now.minute)
).count(),
"Main.call_day_count",
)
week_count = await webui_db_call(
query.filter(
create_time__gte=now
- timedelta(days=7, hours=now.hour, minutes=now.minute)
).count(),
"Main.call_week_count",
)
month_count = await webui_db_call(
query.filter(
create_time__gte=now
- timedelta(days=30, hours=now.hour, minutes=now.minute)
).count(),
"Main.call_month_count",
)
year_count = await webui_db_call(
query.filter(
create_time__gte=now
- timedelta(days=365, hours=now.hour, minutes=now.minute)
).count(),
"Main.call_year_count",
)
return QueryCount(
num=all_count,
day=day_count,
@@ -296,19 +334,21 @@ class ApiDataSource:
list[ActiveGroup]: 活跃群组列表
"""
query = cls.__get_query(ChatHistory, date_type, bot_id)
data_list = (
await query.annotate(count=Count("id"))
data_list = await webui_db_call(
query.annotate(count=Count("id"))
.filter(group_id__not_isnull=True)
.group_by("group_id")
.order_by("-count")
.limit(5)
.values_list("group_id", "count")
.values_list("group_id", "count"),
"Main.active_group",
)
id2name = {}
if data_list:
if info_list := await GroupConsole.filter(
group_id__in=[x[0] for x in data_list]
).all():
if info_list := await webui_db_call(
GroupConsole.filter(group_id__in=[x[0] for x in data_list]).all(),
"Main.active_group_names",
):
for group_info in info_list:
id2name[group_info.group_id] = group_info.group_name
active_group_list = [
@@ -341,19 +381,23 @@ class ApiDataSource:
list[HotPlugin]: 热门插件列表
"""
query = cls.__get_query(Statistics, date_type, bot_id)
data_list = (
await query.annotate(count=Count("id"))
data_list = await webui_db_call(
query.annotate(count=Count("id"))
.group_by("plugin_name")
.order_by("-count")
.limit(5)
.values_list("plugin_name", "count")
.values_list("plugin_name", "count"),
"Main.hot_plugin",
)
hot_plugin_list = []
module_list = [x[0] for x in data_list]
plugins = await PluginInfo.get_plugins(
load_status=None,
filter_parent=False,
module__in=module_list,
plugins = await webui_db_call(
PluginInfo.get_plugins(
load_status=None,
filter_parent=False,
module__in=module_list,
),
"Main.hot_plugin_names",
)
module2name = {p.module: p.name for p in plugins}
for data in data_list: