mirror of
https://github.com/zhenxun-org/zhenxun_bot.git
synced 2026-10-06 04:10:02 +08:00
版本更新
This commit is contained in:
@@ -1,22 +1,201 @@
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
import nonebot
|
||||
from nonebot import require
|
||||
from fastapi import APIRouter
|
||||
from nonebot.config import Config
|
||||
from tortoise.functions import Count
|
||||
from tortoise.expressions import RawSQL
|
||||
from fastapi.responses import JSONResponse
|
||||
|
||||
from zhenxun.models.statistics import Statistics
|
||||
from zhenxun.models.chat_history import ChatHistory
|
||||
from zhenxun.models.bot_connect_log import BotConnectLog
|
||||
|
||||
from ....base_model import Result
|
||||
from .data_source import BotManage
|
||||
from ....utils import authentication
|
||||
from ....base_model import Result, QueryModel, BaseResultModel
|
||||
from .model import BotInfo, ChatCallMonthCount, QueryChatCallCount, AllChatAndCallCount
|
||||
|
||||
require("plugin_store")
|
||||
|
||||
router = APIRouter(prefix="/dashboard")
|
||||
|
||||
driver = nonebot.get_driver()
|
||||
|
||||
|
||||
@router.get(
|
||||
"/get_bot_list",
|
||||
dependencies=[authentication()],
|
||||
response_model=Result[list[BotInfo]],
|
||||
response_class=JSONResponse,
|
||||
deprecated="获取bot列表", # type: ignore
|
||||
)
|
||||
async def _() -> Result:
|
||||
async def _() -> Result[list[BotInfo]]:
|
||||
try:
|
||||
return Result.ok(await BotManage.get_bot_list(), "拿到信息啦!")
|
||||
except Exception as e:
|
||||
return Result.fail(f"发生了一点错误捏 {type(e)}: {e}")
|
||||
|
||||
|
||||
@router.get(
|
||||
"/get_chat_and_call_count",
|
||||
dependencies=[authentication()],
|
||||
response_model=Result[QueryChatCallCount],
|
||||
response_class=JSONResponse,
|
||||
description="获取聊天/调用记录的全部和今日数量",
|
||||
)
|
||||
async def _(bot_id: str | None = None) -> Result[QueryChatCallCount]:
|
||||
now = datetime.now()
|
||||
query = ChatHistory
|
||||
if bot_id:
|
||||
query = query.filter(bot_id=bot_id)
|
||||
chat_all_count = await query.annotate().count()
|
||||
chat_day_count = await query.filter(
|
||||
create_time__gte=now - timedelta(hours=now.hour, minutes=now.minute)
|
||||
).count()
|
||||
query = Statistics
|
||||
if bot_id:
|
||||
query = query.filter(bot_id=bot_id)
|
||||
call_all_count = await query.annotate().count()
|
||||
call_day_count = await query.filter(
|
||||
create_time__gte=now - timedelta(hours=now.hour, minutes=now.minute)
|
||||
).count()
|
||||
return Result.ok(
|
||||
QueryChatCallCount(
|
||||
chat_num=chat_all_count,
|
||||
chat_day=chat_day_count,
|
||||
call_num=call_all_count,
|
||||
call_day=call_day_count,
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@router.get(
|
||||
"/get_all_chat_and_call_count",
|
||||
dependencies=[authentication()],
|
||||
response_model=Result[AllChatAndCallCount],
|
||||
response_class=JSONResponse,
|
||||
description="获取聊天/调用记录的全部数据次数",
|
||||
)
|
||||
async def _(bot_id: str | None = None) -> Result[AllChatAndCallCount]:
|
||||
now = datetime.now()
|
||||
query = ChatHistory
|
||||
if bot_id:
|
||||
query = query.filter(bot_id=bot_id)
|
||||
chat_week_count = await query.filter(
|
||||
create_time__gte=now - timedelta(days=7, hours=now.hour, minutes=now.minute)
|
||||
).count()
|
||||
chat_month_count = await query.filter(
|
||||
create_time__gte=now - timedelta(days=30, hours=now.hour, minutes=now.minute)
|
||||
).count()
|
||||
chat_year_count = await query.filter(
|
||||
create_time__gte=now - timedelta(days=365, hours=now.hour, minutes=now.minute)
|
||||
).count()
|
||||
query = Statistics
|
||||
if bot_id:
|
||||
query = query.filter(bot_id=bot_id)
|
||||
call_week_count = await query.filter(
|
||||
create_time__gte=now - timedelta(days=7, hours=now.hour, minutes=now.minute)
|
||||
).count()
|
||||
call_month_count = await query.filter(
|
||||
create_time__gte=now - timedelta(days=30, hours=now.hour, minutes=now.minute)
|
||||
).count()
|
||||
call_year_count = await query.filter(
|
||||
create_time__gte=now - timedelta(days=365, hours=now.hour, minutes=now.minute)
|
||||
).count()
|
||||
return Result.ok(
|
||||
AllChatAndCallCount(
|
||||
chat_week=chat_week_count,
|
||||
chat_month=chat_month_count,
|
||||
chat_year=chat_year_count,
|
||||
call_week=call_week_count,
|
||||
call_month=call_month_count,
|
||||
call_year=call_year_count,
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@router.get(
|
||||
"/get_chat_and_call_month",
|
||||
dependencies=[authentication()],
|
||||
response_model=Result[ChatCallMonthCount],
|
||||
response_class=JSONResponse,
|
||||
deprecated="获取聊天/调用记录的一个月数量", # type: ignore
|
||||
)
|
||||
async def _(bot_id: str | None = None) -> Result[ChatCallMonthCount]:
|
||||
now = datetime.now()
|
||||
filter_date = now - timedelta(days=30, hours=now.hour, minutes=now.minute)
|
||||
chat_query = ChatHistory
|
||||
call_query = Statistics
|
||||
if bot_id:
|
||||
chat_query = chat_query.filter(bot_id=bot_id)
|
||||
call_query = call_query.filter(bot_id=bot_id)
|
||||
chat_date_list = (
|
||||
await chat_query.filter(create_time__gte=filter_date)
|
||||
.annotate(date=RawSQL("DATE(create_time)"), count=Count("id"))
|
||||
.group_by("date")
|
||||
.values("date", "count")
|
||||
)
|
||||
call_date_list = (
|
||||
await call_query.filter(create_time__gte=filter_date)
|
||||
.annotate(date=RawSQL("DATE(create_time)"), count=Count("id"))
|
||||
.group_by("date")
|
||||
.values("date", "count")
|
||||
)
|
||||
date_list = []
|
||||
chat_count_list = []
|
||||
call_count_list = []
|
||||
chat_date2cnt = {str(date["date"]): date["count"] for date in chat_date_list}
|
||||
call_date2cnt = {str(date["date"]): date["count"] for date in call_date_list}
|
||||
date = now.date()
|
||||
for _ in range(30):
|
||||
if str(date) in chat_date2cnt:
|
||||
chat_count_list.append(chat_date2cnt[str(date)])
|
||||
else:
|
||||
chat_count_list.append(0)
|
||||
if str(date) in call_date2cnt:
|
||||
call_count_list.append(call_date2cnt[str(date)])
|
||||
else:
|
||||
call_count_list.append(0)
|
||||
date_list.append(str(date)[5:])
|
||||
date -= timedelta(days=1)
|
||||
chat_count_list.reverse()
|
||||
call_count_list.reverse()
|
||||
date_list.reverse()
|
||||
return Result.ok(
|
||||
ChatCallMonthCount(chat=chat_count_list, call=call_count_list, date=date_list)
|
||||
)
|
||||
|
||||
|
||||
@router.post(
|
||||
"/get_connect_log",
|
||||
dependencies=[authentication()],
|
||||
response_model=Result[BaseResultModel],
|
||||
response_class=JSONResponse,
|
||||
deprecated="获取Bot连接记录", # type: ignore
|
||||
)
|
||||
async def _(query: QueryModel) -> Result[BaseResultModel]:
|
||||
total = await BotConnectLog.all().count()
|
||||
if total % query.size:
|
||||
total += 1
|
||||
data = (
|
||||
await BotConnectLog.all()
|
||||
.order_by("-id")
|
||||
.offset((query.index - 1) * query.size)
|
||||
.limit(query.size)
|
||||
)
|
||||
for v in data:
|
||||
v.connect_time = v.connect_time.replace(tzinfo=None).replace(microsecond=0)
|
||||
return Result.ok(BaseResultModel(total=total, data=data))
|
||||
|
||||
|
||||
@router.get(
|
||||
"/get_nonebot_config",
|
||||
dependencies=[authentication()],
|
||||
response_model=Result[Config],
|
||||
response_class=JSONResponse,
|
||||
deprecated="获取nb配置", # type: ignore
|
||||
)
|
||||
async def _() -> Result[Config]:
|
||||
return Result.ok(driver.config)
|
||||
|
||||
@@ -49,11 +49,12 @@ class BotManage:
|
||||
)
|
||||
group_list, _ = await PlatformUtils.get_group_list(bot)
|
||||
group_list = [g for g in group_list if g.channel_id is None]
|
||||
friend_list = await PlatformUtils.get_friend_list(bot)
|
||||
friend_list, _ = await PlatformUtils.get_friend_list(bot)
|
||||
bot_info.group_count = len(group_list)
|
||||
bot_info.friend_count = len(friend_list)
|
||||
bot_info.day_call = await Statistics.filter(
|
||||
create_time__gte=now - timedelta(hours=now.hour, minutes=now.minute)
|
||||
create_time__gte=now - timedelta(hours=now.hour, minutes=now.minute),
|
||||
bot_id=bot.self_id,
|
||||
).count()
|
||||
bot_info.received_messages = await ChatHistory.filter(
|
||||
bot_id=bot_info.self_id,
|
||||
@@ -62,10 +63,7 @@ class BotManage:
|
||||
bot_info.connect_time = bot_live.get(bot.self_id) or 0
|
||||
if bot_info.connect_time:
|
||||
connect_date = datetime.fromtimestamp(CONNECT_TIME)
|
||||
connect_date_str = connect_date.strftime("%Y-%m-%d %H:%M:%S")
|
||||
bot_info.connect_date = datetime.strptime(
|
||||
connect_date_str, "%Y-%m-%d %H:%M:%S"
|
||||
)
|
||||
bot_info.connect_date = connect_date.strftime("%Y-%m-%d %H:%M:%S")
|
||||
return bot_info
|
||||
|
||||
@classmethod
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
from datetime import datetime
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
|
||||
@@ -22,5 +20,52 @@ class BotInfo(BaseModel):
|
||||
"""今日调用插件次数"""
|
||||
connect_time: int = 0
|
||||
"""连接时间"""
|
||||
connect_date: datetime | None = None
|
||||
connect_date: str | None = None
|
||||
"""连接日期"""
|
||||
|
||||
|
||||
class QueryChatCallCount(BaseModel):
|
||||
"""
|
||||
查询聊天/调用记录次数
|
||||
"""
|
||||
|
||||
chat_num: int
|
||||
"""聊天记录总数"""
|
||||
chat_day: int
|
||||
"""今日消息"""
|
||||
call_num: int
|
||||
"""调用记录总数"""
|
||||
call_day: int
|
||||
"""今日调用"""
|
||||
|
||||
|
||||
class ChatCallMonthCount(BaseModel):
|
||||
"""
|
||||
查询聊天/调用一个月记录次数
|
||||
"""
|
||||
|
||||
chat: list[int]
|
||||
"""一个月内聊天总数"""
|
||||
call: list[int]
|
||||
"""一个月内调用数据"""
|
||||
date: list[str]
|
||||
"""日期"""
|
||||
|
||||
|
||||
class AllChatAndCallCount(BaseModel):
|
||||
"""
|
||||
查询聊天/调用记录次数
|
||||
"""
|
||||
|
||||
chat_week: int
|
||||
"""一周内聊天次数"""
|
||||
chat_month: int
|
||||
"""一月内聊天次数"""
|
||||
chat_year: int
|
||||
"""一年内聊天次数"""
|
||||
call_week: int
|
||||
"""一周内调用次数"""
|
||||
call_month: int
|
||||
"""一月内调用次数"""
|
||||
call_year: int
|
||||
"""一年内调用次数"""
|
||||
|
||||
@@ -2,6 +2,7 @@ import nonebot
|
||||
from tortoise import Tortoise
|
||||
from nonebot.drivers import Driver
|
||||
from fastapi import Request, APIRouter
|
||||
from fastapi.responses import JSONResponse
|
||||
from tortoise.exceptions import OperationalError
|
||||
|
||||
from zhenxun.models.task_info import TaskInfo
|
||||
@@ -62,26 +63,40 @@ async def _():
|
||||
|
||||
|
||||
@router.get(
|
||||
"/get_table_list", dependencies=[authentication()], description="获取数据库表"
|
||||
"/get_table_list",
|
||||
dependencies=[authentication()],
|
||||
response_model=Result[list[dict]],
|
||||
response_class=JSONResponse,
|
||||
description="获取数据库表",
|
||||
)
|
||||
async def _() -> Result:
|
||||
async def _() -> Result[list[dict]]:
|
||||
db = Tortoise.get_connection("default")
|
||||
query = await db.execute_query_dict(SELECT_TABLE_SQL)
|
||||
return Result.ok(query)
|
||||
|
||||
|
||||
@router.get(
|
||||
"/get_table_column", dependencies=[authentication()], description="获取表字段"
|
||||
"/get_table_column",
|
||||
dependencies=[authentication()],
|
||||
response_model=Result[list[dict]],
|
||||
response_class=JSONResponse,
|
||||
description="获取表字段",
|
||||
)
|
||||
async def _(table_name: str) -> Result:
|
||||
async def _(table_name: str) -> Result[list[dict]]:
|
||||
db = Tortoise.get_connection("default")
|
||||
# print(SELECT_TABLE_COLUMN_SQL.format(table_name))
|
||||
query = await db.execute_query_dict(SELECT_TABLE_COLUMN_SQL.format(table_name))
|
||||
return Result.ok(query)
|
||||
|
||||
|
||||
@router.post("/exec_sql", dependencies=[authentication()], description="执行sql")
|
||||
async def _(sql: SqlText, request: Request) -> Result:
|
||||
@router.post(
|
||||
"/exec_sql",
|
||||
dependencies=[authentication()],
|
||||
response_model=Result[list[dict]],
|
||||
response_class=JSONResponse,
|
||||
description="执行sql",
|
||||
)
|
||||
async def _(sql: SqlText, request: Request) -> Result[list[dict]]:
|
||||
ip = request.client.host if request.client else "unknown"
|
||||
try:
|
||||
if sql.sql.lower().startswith("select"):
|
||||
@@ -98,8 +113,14 @@ async def _(sql: SqlText, request: Request) -> Result:
|
||||
return Result.warning_(f"sql执行错误: {e}")
|
||||
|
||||
|
||||
@router.post("/get_sql_log", dependencies=[authentication()], description="sql日志列表")
|
||||
async def _(query: QueryModel) -> Result:
|
||||
@router.post(
|
||||
"/get_sql_log",
|
||||
dependencies=[authentication()],
|
||||
response_model=Result[BaseResultModel],
|
||||
response_class=JSONResponse,
|
||||
description="sql日志列表",
|
||||
)
|
||||
async def _(query: QueryModel) -> Result[BaseResultModel]:
|
||||
total = await SqlLog.all().count()
|
||||
if total % query.size:
|
||||
total += 1
|
||||
@@ -112,8 +133,14 @@ async def _(query: QueryModel) -> Result:
|
||||
return Result.ok(BaseResultModel(total=total, data=data))
|
||||
|
||||
|
||||
@router.get("/get_common_sql", dependencies=[authentication()], description="常用sql")
|
||||
async def _(plugin_name: str | None = None) -> Result:
|
||||
@router.get(
|
||||
"/get_common_sql",
|
||||
dependencies=[authentication()],
|
||||
response_model=Result[dict],
|
||||
response_class=JSONResponse,
|
||||
description="常用sql",
|
||||
)
|
||||
async def _(plugin_name: str | None = None) -> Result[dict]:
|
||||
if plugin_name:
|
||||
return Result.ok(SQL_DICT.get(plugin_name))
|
||||
return Result.ok(str(SQL_DICT))
|
||||
|
||||
@@ -6,31 +6,48 @@ from datetime import datetime, timedelta
|
||||
|
||||
import nonebot
|
||||
from fastapi import APIRouter
|
||||
from nonebot.config import Config
|
||||
from tortoise.functions import Count
|
||||
from fastapi.responses import JSONResponse
|
||||
from websockets.exceptions import ConnectionClosedOK, ConnectionClosedError
|
||||
from starlette.websockets import WebSocket, WebSocketState, WebSocketDisconnect
|
||||
|
||||
from zhenxun.services.log import logger
|
||||
from zhenxun.models.group_info import GroupInfo
|
||||
from zhenxun.models.statistics import Statistics
|
||||
from zhenxun.utils.platform import PlatformUtils
|
||||
from zhenxun.models.plugin_info import PluginInfo
|
||||
from zhenxun.models.chat_history import ChatHistory
|
||||
from zhenxun.models.group_console import GroupConsole
|
||||
from zhenxun.models.bot_connect_log import BotConnectLog
|
||||
|
||||
from ....base_model import Result
|
||||
from .data_source import bot_live
|
||||
from ....utils import authentication, get_system_status
|
||||
from ....config import AVA_URL, GROUP_AVA_URL, QueryDateType
|
||||
from .model import BaseInfo, HotPlugin, ActiveGroup, ChatHistoryCount
|
||||
from .model import (
|
||||
BaseInfo,
|
||||
HotPlugin,
|
||||
QueryCount,
|
||||
ActiveGroup,
|
||||
NonebotData,
|
||||
TemplateBaseInfo,
|
||||
)
|
||||
|
||||
driver = nonebot.get_driver()
|
||||
run_time = time.time()
|
||||
|
||||
ws_router = APIRouter()
|
||||
router = APIRouter(prefix="/main")
|
||||
|
||||
|
||||
@router.get("/get_base_info", dependencies=[authentication()], description="基础信息")
|
||||
async def _(bot_id: str | None = None) -> Result:
|
||||
@router.get(
|
||||
"/get_base_info",
|
||||
dependencies=[authentication()],
|
||||
response_model=Result[list[BaseInfo]],
|
||||
response_class=JSONResponse,
|
||||
description="基础信息",
|
||||
)
|
||||
async def _(bot_id: str | None = None) -> Result[list[BaseInfo]]:
|
||||
"""获取Bot基础信息
|
||||
|
||||
参数:
|
||||
@@ -39,13 +56,14 @@ async def _(bot_id: str | None = None) -> Result:
|
||||
返回:
|
||||
Result: 获取指定bot信息与bot列表
|
||||
"""
|
||||
bot_list: list[BaseInfo] = []
|
||||
global run_time
|
||||
bot_list: list[TemplateBaseInfo] = []
|
||||
if bots := nonebot.get_bots():
|
||||
select_bot: BaseInfo
|
||||
for key, bot in bots.items():
|
||||
for _, bot in bots.items():
|
||||
login_info = await bot.get_login_info()
|
||||
bot_list.append(
|
||||
BaseInfo(
|
||||
TemplateBaseInfo(
|
||||
bot=bot, # type: ignore
|
||||
self_id=bot.self_id,
|
||||
nickname=login_info["nickname"],
|
||||
@@ -58,7 +76,6 @@ async def _(bot_id: str | None = None) -> Result:
|
||||
else:
|
||||
select_bot = bot_list[0]
|
||||
select_bot.is_select = True
|
||||
select_bot.config = select_bot.bot.config
|
||||
now = datetime.now()
|
||||
# 今日累计接收消息
|
||||
select_bot.received_messages = await ChatHistory.filter(
|
||||
@@ -82,10 +99,7 @@ async def _(bot_id: str | None = None) -> Result:
|
||||
select_bot.connect_time = bot_live.get(select_bot.self_id) or 0
|
||||
if select_bot.connect_time:
|
||||
connect_date = datetime.fromtimestamp(select_bot.connect_time)
|
||||
connect_date_str = connect_date.strftime("%Y-%m-%d %H:%M:%S")
|
||||
select_bot.connect_date = datetime.strptime(
|
||||
connect_date_str, "%Y-%m-%d %H:%M:%S"
|
||||
)
|
||||
select_bot.connect_date = connect_date.strftime("%Y-%m-%d %H:%M:%S")
|
||||
version_file = Path() / "__version__"
|
||||
if version_file.exists():
|
||||
if text := version_file.open().read():
|
||||
@@ -95,30 +109,40 @@ async def _(bot_id: str | None = None) -> Result:
|
||||
create_time__gte=now - timedelta(hours=now.hour)
|
||||
).count()
|
||||
select_bot.day_call = day_call
|
||||
return Result.ok(bot_list, "拿到信息啦!")
|
||||
select_bot.connect_count = await BotConnectLog.filter(
|
||||
bot_id=select_bot.self_id
|
||||
).count()
|
||||
return Result.ok([BaseInfo(**e.dict()) for e in bot_list], "拿到信息啦!")
|
||||
return Result.warning_("无Bot连接...")
|
||||
|
||||
|
||||
@router.get(
|
||||
"/get_all_ch_count", dependencies=[authentication()], description="获取接收消息数量"
|
||||
"/get_all_chat_count",
|
||||
dependencies=[authentication()],
|
||||
response_model=Result[QueryCount],
|
||||
response_class=JSONResponse,
|
||||
description="获取接收消息数量",
|
||||
)
|
||||
async def _(bot_id: str) -> Result:
|
||||
async def _(bot_id: str | None = None) -> Result[QueryCount]:
|
||||
now = datetime.now()
|
||||
all_count = await ChatHistory.filter(bot_id=bot_id).count()
|
||||
day_count = await ChatHistory.filter(
|
||||
bot_id=bot_id, create_time__gte=now - timedelta(hours=now.hour)
|
||||
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 ChatHistory.filter(
|
||||
bot_id=bot_id, create_time__gte=now - timedelta(days=7)
|
||||
week_count = await query.filter(
|
||||
create_time__gte=now - timedelta(days=7, hours=now.hour, minutes=now.minute)
|
||||
).count()
|
||||
month_count = await ChatHistory.filter(
|
||||
bot_id=bot_id, create_time__gte=now - timedelta(days=30)
|
||||
month_count = await query.filter(
|
||||
create_time__gte=now - timedelta(days=30, hours=now.hour, minutes=now.minute)
|
||||
).count()
|
||||
year_count = await ChatHistory.filter(
|
||||
bot_id=bot_id, create_time__gte=now - timedelta(days=365)
|
||||
year_count = await query.filter(
|
||||
create_time__gte=now - timedelta(days=365, hours=now.hour, minutes=now.minute)
|
||||
).count()
|
||||
return Result.ok(
|
||||
ChatHistoryCount(
|
||||
QueryCount(
|
||||
num=all_count,
|
||||
day=day_count,
|
||||
week=week_count,
|
||||
@@ -129,44 +153,49 @@ async def _(bot_id: str) -> Result:
|
||||
|
||||
|
||||
@router.get(
|
||||
"/get_ch_count", dependencies=[authentication()], description="获取接收消息数量"
|
||||
"/get_all_call_count",
|
||||
dependencies=[authentication()],
|
||||
response_model=Result[QueryCount],
|
||||
response_class=JSONResponse,
|
||||
description="获取调用次数",
|
||||
)
|
||||
async def _(bot_id: str, query_type: QueryDateType | None = None) -> Result:
|
||||
if nonebot.get_bot(bot_id):
|
||||
if not query_type:
|
||||
return Result.ok(await ChatHistory.filter(bot_id=bot_id).count())
|
||||
now = datetime.now()
|
||||
if query_type == QueryDateType.DAY:
|
||||
return Result.ok(
|
||||
await ChatHistory.filter(
|
||||
bot_id=bot_id, create_time__gte=now - timedelta(hours=now.hour)
|
||||
).count()
|
||||
)
|
||||
if query_type == QueryDateType.WEEK:
|
||||
return Result.ok(
|
||||
await ChatHistory.filter(
|
||||
bot_id=bot_id, create_time__gte=now - timedelta(days=7)
|
||||
).count()
|
||||
)
|
||||
if query_type == QueryDateType.MONTH:
|
||||
return Result.ok(
|
||||
await ChatHistory.filter(
|
||||
bot_id=bot_id, create_time__gte=now - timedelta(days=30)
|
||||
).count()
|
||||
)
|
||||
if query_type == QueryDateType.YEAR:
|
||||
return Result.ok(
|
||||
await ChatHistory.filter(
|
||||
bot_id=bot_id, create_time__gte=now - timedelta(days=365)
|
||||
).count()
|
||||
)
|
||||
return Result.warning_("无Bot连接...")
|
||||
async def _(bot_id: str | None = None) -> Result[QueryCount]:
|
||||
now = datetime.now()
|
||||
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()
|
||||
return Result.ok(
|
||||
QueryCount(
|
||||
num=all_count,
|
||||
day=day_count,
|
||||
week=week_count,
|
||||
month=month_count,
|
||||
year=year_count,
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@router.get(
|
||||
"get_fg_count", dependencies=[authentication()], description="好友/群组数量"
|
||||
"get_fg_count",
|
||||
dependencies=[authentication()],
|
||||
response_model=Result[dict[str, int]],
|
||||
response_class=JSONResponse,
|
||||
description="好友/群组数量",
|
||||
)
|
||||
async def _(bot_id: str) -> Result:
|
||||
async def _(bot_id: str) -> Result[dict[str, int]]:
|
||||
if bots := nonebot.get_bots():
|
||||
if bot_id not in bots:
|
||||
return Result.warning_("指定Bot未连接...")
|
||||
@@ -183,26 +212,60 @@ async def _(bot_id: str) -> Result:
|
||||
|
||||
|
||||
@router.get(
|
||||
"/get_run_time", dependencies=[authentication()], description="获取nb运行时间"
|
||||
"/get_nb_data",
|
||||
dependencies=[authentication()],
|
||||
response_model=Result[NonebotData],
|
||||
response_class=JSONResponse,
|
||||
description="获取nb数据",
|
||||
)
|
||||
async def _() -> Result:
|
||||
return Result.ok(int(time.time() - run_time))
|
||||
async def _() -> Result[NonebotData]:
|
||||
return Result.ok(NonebotData(config=driver.config, run_time=int(run_time)))
|
||||
|
||||
|
||||
@router.get(
|
||||
"/get_active_group", dependencies=[authentication()], description="获取活跃群聊"
|
||||
"/get_nb_config",
|
||||
dependencies=[authentication()],
|
||||
response_model=Result[Config],
|
||||
response_class=JSONResponse,
|
||||
description="获取nb配置",
|
||||
)
|
||||
async def _(date_type: QueryDateType | None = None) -> Result:
|
||||
async def _() -> Result[Config]:
|
||||
return Result.ok(driver.config)
|
||||
|
||||
|
||||
@router.get(
|
||||
"/get_run_time",
|
||||
dependencies=[authentication()],
|
||||
response_model=Result[int],
|
||||
response_class=JSONResponse,
|
||||
description="获取nb运行时间",
|
||||
)
|
||||
async def _() -> Result[int]:
|
||||
return Result.ok(int(run_time))
|
||||
|
||||
|
||||
@router.get(
|
||||
"/get_active_group",
|
||||
dependencies=[authentication()],
|
||||
response_model=Result[list[ActiveGroup]],
|
||||
response_class=JSONResponse,
|
||||
description="获取活跃群聊",
|
||||
)
|
||||
async def _(
|
||||
date_type: QueryDateType | None = None, bot_id: str | None = None
|
||||
) -> Result[list[ActiveGroup]]:
|
||||
query = ChatHistory
|
||||
now = datetime.now()
|
||||
if bot_id:
|
||||
query = query.filter(bot_id=bot_id)
|
||||
if date_type == QueryDateType.DAY:
|
||||
query = ChatHistory.filter(create_time__gte=now - timedelta(hours=now.hour))
|
||||
query = query.filter(create_time__gte=now - timedelta(hours=now.hour))
|
||||
if date_type == QueryDateType.WEEK:
|
||||
query = ChatHistory.filter(create_time__gte=now - timedelta(days=7))
|
||||
query = query.filter(create_time__gte=now - timedelta(days=7))
|
||||
if date_type == QueryDateType.MONTH:
|
||||
query = ChatHistory.filter(create_time__gte=now - timedelta(days=30))
|
||||
query = query.filter(create_time__gte=now - timedelta(days=30))
|
||||
if date_type == QueryDateType.YEAR:
|
||||
query = ChatHistory.filter(create_time__gte=now - timedelta(days=365))
|
||||
query = query.filter(create_time__gte=now - timedelta(days=365))
|
||||
data_list = (
|
||||
await query.annotate(count=Count("id"))
|
||||
.filter(group_id__not_isnull=True)
|
||||
@@ -213,7 +276,7 @@ async def _(date_type: QueryDateType | None = None) -> Result:
|
||||
)
|
||||
id2name = {}
|
||||
if data_list:
|
||||
if info_list := await GroupInfo.filter(
|
||||
if info_list := await GroupConsole.filter(
|
||||
group_id__in=[x[0] for x in data_list]
|
||||
).all():
|
||||
for group_info in info_list:
|
||||
@@ -236,19 +299,27 @@ async def _(date_type: QueryDateType | None = None) -> Result:
|
||||
|
||||
|
||||
@router.get(
|
||||
"/get_hot_plugin", dependencies=[authentication()], description="获取热门插件"
|
||||
"/get_hot_plugin",
|
||||
dependencies=[authentication()],
|
||||
response_model=Result[list[HotPlugin]],
|
||||
response_class=JSONResponse,
|
||||
description="获取热门插件",
|
||||
)
|
||||
async def _(date_type: QueryDateType | None = None) -> Result:
|
||||
async def _(
|
||||
date_type: QueryDateType | None = None, bot_id: str | None = None
|
||||
) -> Result[list[HotPlugin]]:
|
||||
query = Statistics
|
||||
now = datetime.now()
|
||||
if bot_id:
|
||||
query = query.filter(bot_id=bot_id)
|
||||
if date_type == QueryDateType.DAY:
|
||||
query = Statistics.filter(create_time__gte=now - timedelta(hours=now.hour))
|
||||
query = query.filter(create_time__gte=now - timedelta(hours=now.hour))
|
||||
if date_type == QueryDateType.WEEK:
|
||||
query = Statistics.filter(create_time__gte=now - timedelta(days=7))
|
||||
query = query.filter(create_time__gte=now - timedelta(days=7))
|
||||
if date_type == QueryDateType.MONTH:
|
||||
query = Statistics.filter(create_time__gte=now - timedelta(days=30))
|
||||
query = query.filter(create_time__gte=now - timedelta(days=30))
|
||||
if date_type == QueryDateType.YEAR:
|
||||
query = Statistics.filter(create_time__gte=now - timedelta(days=365))
|
||||
query = query.filter(create_time__gte=now - timedelta(days=365))
|
||||
data_list = (
|
||||
await query.annotate(count=Count("id"))
|
||||
.group_by("plugin_name")
|
||||
@@ -281,4 +352,3 @@ async def system_logs_realtime(websocket: WebSocket, sleep: int = 5):
|
||||
system_status = await get_system_status()
|
||||
await websocket.send_text(system_status.json())
|
||||
await asyncio.sleep(sleep)
|
||||
return
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import time
|
||||
|
||||
import nonebot
|
||||
from nonebot.adapters.onebot.v11 import Bot
|
||||
from nonebot.drivers import Driver
|
||||
from nonebot.adapters.onebot.v11 import Bot
|
||||
|
||||
driver: Driver = nonebot.get_driver()
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
from datetime import datetime
|
||||
|
||||
from pydantic import BaseModel
|
||||
from nonebot.adapters import Bot
|
||||
from nonebot.config import Config
|
||||
from pydantic import BaseModel
|
||||
|
||||
|
||||
class SystemStatus(BaseModel):
|
||||
@@ -20,8 +18,6 @@ class BaseInfo(BaseModel):
|
||||
基础信息
|
||||
"""
|
||||
|
||||
bot: Bot
|
||||
"""Bot"""
|
||||
self_id: str
|
||||
"""SELF ID"""
|
||||
nickname: str
|
||||
@@ -36,8 +32,10 @@ class BaseInfo(BaseModel):
|
||||
"""今日 累计接收消息"""
|
||||
connect_time: int = 0
|
||||
"""连接时间"""
|
||||
connect_date: datetime | None = None
|
||||
connect_date: str | None = None
|
||||
"""连接日期"""
|
||||
connect_count: int = 0
|
||||
"""连接次数"""
|
||||
|
||||
plugin_count: int = 0
|
||||
"""加载插件数量"""
|
||||
@@ -48,9 +46,6 @@ class BaseInfo(BaseModel):
|
||||
|
||||
is_select: bool = False
|
||||
"""当前选择"""
|
||||
|
||||
config: Config | None = None
|
||||
"""nb配置"""
|
||||
day_call: int = 0
|
||||
"""今日调用插件次数"""
|
||||
version: str = "unknown"
|
||||
@@ -60,7 +55,16 @@ class BaseInfo(BaseModel):
|
||||
arbitrary_types_allowed = True
|
||||
|
||||
|
||||
class ChatHistoryCount(BaseModel):
|
||||
class TemplateBaseInfo(BaseInfo):
|
||||
"""
|
||||
基础信息
|
||||
"""
|
||||
|
||||
bot: Bot
|
||||
"""bot"""
|
||||
|
||||
|
||||
class QueryCount(BaseModel):
|
||||
"""
|
||||
聊天记录数量
|
||||
"""
|
||||
@@ -103,3 +107,10 @@ class HotPlugin(BaseModel):
|
||||
"""插件名称"""
|
||||
count: int
|
||||
"""调用次数"""
|
||||
|
||||
|
||||
class NonebotData(BaseModel):
|
||||
config: Config
|
||||
"""nb配置"""
|
||||
run_time: int
|
||||
"""运行时间"""
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import nonebot
|
||||
from fastapi import APIRouter
|
||||
from tortoise.functions import Count
|
||||
from fastapi.responses import JSONResponse
|
||||
from nonebot.adapters.onebot.v11 import ActionFailed
|
||||
|
||||
from zhenxun.services.log import logger
|
||||
@@ -41,7 +42,11 @@ router = APIRouter(prefix="/manage")
|
||||
|
||||
|
||||
@router.get(
|
||||
"/get_group_list", dependencies=[authentication()], description="获取群组列表"
|
||||
"/get_group_list",
|
||||
dependencies=[authentication()],
|
||||
response_model=Result[list[GroupResult]],
|
||||
response_class=JSONResponse,
|
||||
description="获取群组列表",
|
||||
)
|
||||
async def _(bot_id: str) -> Result:
|
||||
"""
|
||||
@@ -65,9 +70,13 @@ async def _(bot_id: str) -> Result:
|
||||
|
||||
|
||||
@router.post(
|
||||
"/update_group", dependencies=[authentication()], description="修改群组信息"
|
||||
"/update_group",
|
||||
dependencies=[authentication()],
|
||||
response_model=Result[str],
|
||||
response_class=JSONResponse,
|
||||
description="修改群组信息",
|
||||
)
|
||||
async def _(group: UpdateGroup) -> Result:
|
||||
async def _(group: UpdateGroup) -> Result[str]:
|
||||
try:
|
||||
group_id = group.group_id
|
||||
if db_group := await GroupConsole.get_group(group_id):
|
||||
@@ -75,9 +84,11 @@ async def _(group: UpdateGroup) -> Result:
|
||||
db_group.level = group.level
|
||||
db_group.status = group.status
|
||||
if group.close_plugins:
|
||||
group.close_plugins = [f"<{module}" for module in group.close_plugins]
|
||||
db_group.block_plugin = ",".join(group.close_plugins) + ","
|
||||
if group.task:
|
||||
if block_task := [t for t in task_list if t not in group.task]:
|
||||
block_task = [f"<{module}" for module in block_task]
|
||||
db_group.block_task = ",".join(block_task) + "," # type: ignore
|
||||
await db_group.save(
|
||||
update_fields=["level", "status", "block_plugin", "block_task"]
|
||||
@@ -89,9 +100,13 @@ async def _(group: UpdateGroup) -> Result:
|
||||
|
||||
|
||||
@router.get(
|
||||
"/get_friend_list", dependencies=[authentication()], description="获取好友列表"
|
||||
"/get_friend_list",
|
||||
dependencies=[authentication()],
|
||||
response_model=Result[list[Friend]],
|
||||
response_class=JSONResponse,
|
||||
description="获取好友列表",
|
||||
)
|
||||
async def _(bot_id: str) -> Result:
|
||||
async def _(bot_id: str) -> Result[list[Friend]]:
|
||||
"""
|
||||
获取群信息
|
||||
"""
|
||||
@@ -116,9 +131,13 @@ async def _(bot_id: str) -> Result:
|
||||
|
||||
|
||||
@router.get(
|
||||
"/get_request_count", dependencies=[authentication()], description="获取请求数量"
|
||||
"/get_request_count",
|
||||
dependencies=[authentication()],
|
||||
response_model=Result[dict[str, int]],
|
||||
response_class=JSONResponse,
|
||||
description="获取请求数量",
|
||||
)
|
||||
async def _() -> Result:
|
||||
async def _() -> Result[dict[str, int]]:
|
||||
f_count = await FgRequest.filter(
|
||||
request_type=RequestType.FRIEND, handle_type__isnull=True
|
||||
).count()
|
||||
@@ -133,9 +152,13 @@ async def _() -> Result:
|
||||
|
||||
|
||||
@router.get(
|
||||
"/get_request_list", dependencies=[authentication()], description="获取请求列表"
|
||||
"/get_request_list",
|
||||
dependencies=[authentication()],
|
||||
response_model=Result[ReqResult],
|
||||
response_class=JSONResponse,
|
||||
description="获取请求列表",
|
||||
)
|
||||
async def _() -> Result:
|
||||
async def _() -> Result[ReqResult]:
|
||||
try:
|
||||
req_result = ReqResult()
|
||||
data_list = await FgRequest.filter(handle_type__isnull=True).all()
|
||||
@@ -177,7 +200,11 @@ async def _() -> Result:
|
||||
|
||||
|
||||
@router.post(
|
||||
"/clear_request", dependencies=[authentication()], description="清空请求列表"
|
||||
"/clear_request",
|
||||
dependencies=[authentication()],
|
||||
response_model=Result,
|
||||
response_class=JSONResponse,
|
||||
description="清空请求列表",
|
||||
)
|
||||
async def _(cr: ClearRequest) -> Result:
|
||||
await FgRequest.filter(
|
||||
@@ -186,7 +213,13 @@ async def _(cr: ClearRequest) -> Result:
|
||||
return Result.ok(info="成功清除了数据!")
|
||||
|
||||
|
||||
@router.post("/refuse_request", dependencies=[authentication()], description="拒绝请求")
|
||||
@router.post(
|
||||
"/refuse_request",
|
||||
dependencies=[authentication()],
|
||||
response_model=Result,
|
||||
response_class=JSONResponse,
|
||||
description="拒绝请求",
|
||||
)
|
||||
async def _(parma: HandleRequest) -> Result:
|
||||
try:
|
||||
if bots := nonebot.get_bots():
|
||||
@@ -207,14 +240,24 @@ async def _(parma: HandleRequest) -> Result:
|
||||
return Result.fail(f"{type(e)}: {e}")
|
||||
|
||||
|
||||
@router.post("/delete_request", dependencies=[authentication()], description="忽略请求")
|
||||
@router.post(
|
||||
"/delete_request",
|
||||
dependencies=[authentication()],
|
||||
response_model=Result,
|
||||
response_class=JSONResponse,
|
||||
description="忽略请求",
|
||||
)
|
||||
async def _(parma: HandleRequest) -> Result:
|
||||
await FgRequest.ignore(parma.id)
|
||||
return Result.ok(info="成功处理了请求!")
|
||||
|
||||
|
||||
@router.post(
|
||||
"/approve_request", dependencies=[authentication()], description="同意请求"
|
||||
"/approve_request",
|
||||
dependencies=[authentication()],
|
||||
response_model=Result,
|
||||
response_class=JSONResponse,
|
||||
description="同意请求",
|
||||
)
|
||||
async def _(parma: HandleRequest) -> Result:
|
||||
try:
|
||||
@@ -245,7 +288,13 @@ async def _(parma: HandleRequest) -> Result:
|
||||
return Result.fail(f"{type(e)}: {e}")
|
||||
|
||||
|
||||
@router.post("/leave_group", dependencies=[authentication()], description="退群")
|
||||
@router.post(
|
||||
"/leave_group",
|
||||
dependencies=[authentication()],
|
||||
response_model=Result,
|
||||
response_class=JSONResponse,
|
||||
description="退群",
|
||||
)
|
||||
async def _(param: LeaveGroup) -> Result:
|
||||
try:
|
||||
if bots := nonebot.get_bots():
|
||||
@@ -264,7 +313,13 @@ async def _(param: LeaveGroup) -> Result:
|
||||
return Result.fail(f"{type(e)}: {e}")
|
||||
|
||||
|
||||
@router.post("/delete_friend", dependencies=[authentication()], description="删除好友")
|
||||
@router.post(
|
||||
"/delete_friend",
|
||||
dependencies=[authentication()],
|
||||
response_model=Result,
|
||||
response_class=JSONResponse,
|
||||
description="删除好友",
|
||||
)
|
||||
async def _(param: DeleteFriend) -> Result:
|
||||
try:
|
||||
if bots := nonebot.get_bots():
|
||||
@@ -284,9 +339,13 @@ async def _(param: DeleteFriend) -> Result:
|
||||
|
||||
|
||||
@router.get(
|
||||
"/get_friend_detail", dependencies=[authentication()], description="获取好友详情"
|
||||
"/get_friend_detail",
|
||||
dependencies=[authentication()],
|
||||
response_model=Result[UserDetail],
|
||||
response_class=JSONResponse,
|
||||
description="获取好友详情",
|
||||
)
|
||||
async def _(bot_id: str, user_id: str) -> Result:
|
||||
async def _(bot_id: str, user_id: str) -> Result[UserDetail]:
|
||||
if bots := nonebot.get_bots():
|
||||
if bot_id in bots:
|
||||
if fd := [
|
||||
@@ -327,9 +386,13 @@ async def _(bot_id: str, user_id: str) -> Result:
|
||||
|
||||
|
||||
@router.get(
|
||||
"/get_group_detail", dependencies=[authentication()], description="获取群组详情"
|
||||
"/get_group_detail",
|
||||
dependencies=[authentication()],
|
||||
response_model=Result[GroupDetail],
|
||||
response_class=JSONResponse,
|
||||
description="获取群组详情",
|
||||
)
|
||||
async def _(bot_id: str, group_id: str) -> Result:
|
||||
async def _(bot_id: str, group_id: str) -> Result[GroupDetail]:
|
||||
if not (bots := nonebot.get_bots()):
|
||||
return Result.warning_("无Bot连接...")
|
||||
if bot_id not in bots:
|
||||
@@ -346,34 +409,46 @@ async def _(bot_id: str, group_id: str) -> Result:
|
||||
.values_list("plugin_name", "count")
|
||||
)
|
||||
like_plugin = {}
|
||||
plugins = await PluginInfo.all()
|
||||
plugins = await PluginInfo.get_plugins()
|
||||
module2name = {p.module: p.name for p in plugins}
|
||||
for data in like_plugin_list:
|
||||
name = module2name.get(data[0]) or data[0]
|
||||
like_plugin[name] = data[1]
|
||||
close_plugins = []
|
||||
close_plugins: list[Plugin] = []
|
||||
if group.block_plugin:
|
||||
for module in group.block_plugin.split(","):
|
||||
module_ = module.replace(":super", "")
|
||||
is_super_block = module.endswith(":super")
|
||||
plugin = Plugin(
|
||||
module=module_,
|
||||
plugin_name=module,
|
||||
is_super_block=is_super_block,
|
||||
)
|
||||
plugin.plugin_name = module2name.get(module) or module
|
||||
close_plugins.append(plugin)
|
||||
for module in group.block_plugin.replace("<", "").split(","):
|
||||
if module:
|
||||
plugin = Plugin(
|
||||
module=module,
|
||||
plugin_name=module,
|
||||
is_super_block=False,
|
||||
)
|
||||
plugin.plugin_name = module2name.get(module) or module
|
||||
close_plugins.append(plugin)
|
||||
exists_modules = [p.module for p in close_plugins]
|
||||
if group.superuser_block_plugin:
|
||||
for module in group.superuser_block_plugin.replace("<", "").split(","):
|
||||
if module and module not in exists_modules:
|
||||
plugin = Plugin(
|
||||
module=module,
|
||||
plugin_name=module,
|
||||
is_super_block=True,
|
||||
)
|
||||
plugin.plugin_name = module2name.get(module) or module
|
||||
close_plugins.append(plugin)
|
||||
all_task = await TaskInfo.annotate().values_list("module", "name")
|
||||
task_module2name = {x[0]: x[1] for x in all_task}
|
||||
task_list = []
|
||||
if group.block_task:
|
||||
split_task = group.block_task.split(",")
|
||||
if group.block_task or group.superuser_block_plugin:
|
||||
sbp = group.superuser_block_plugin.replace("<", "").split(",")
|
||||
split_task = group.block_task.replace("<", "").split(",")
|
||||
for task in all_task:
|
||||
task_list.append(
|
||||
Task(
|
||||
name=task[0],
|
||||
zh_name=task_module2name.get(task[0]) or task[0],
|
||||
status=task[0] not in split_task,
|
||||
status=task[0] not in split_task and task[0] not in sbp,
|
||||
is_super_block=task[0] in sbp,
|
||||
)
|
||||
)
|
||||
else:
|
||||
@@ -383,6 +458,7 @@ async def _(bot_id: str, group_id: str) -> Result:
|
||||
name=task[0],
|
||||
zh_name=task_module2name.get(task[0]) or task[0],
|
||||
status=True,
|
||||
is_super_block=False,
|
||||
)
|
||||
)
|
||||
group_detail = GroupDetail(
|
||||
@@ -403,7 +479,11 @@ async def _(bot_id: str, group_id: str) -> Result:
|
||||
|
||||
|
||||
@router.post(
|
||||
"/send_message", dependencies=[authentication()], description="获取群组详情"
|
||||
"/send_message",
|
||||
dependencies=[authentication()],
|
||||
response_model=Result,
|
||||
response_class=JSONResponse,
|
||||
description="获取群组详情",
|
||||
)
|
||||
async def _(param: SendMessage) -> Result:
|
||||
if not (bots := nonebot.get_bots()):
|
||||
|
||||
@@ -29,6 +29,8 @@ class Task(BaseModel):
|
||||
"""被动中文名称"""
|
||||
status: bool
|
||||
"""状态"""
|
||||
is_super_block: bool
|
||||
"""是否超级用户禁用"""
|
||||
|
||||
|
||||
class Plugin(BaseModel):
|
||||
|
||||
@@ -2,6 +2,7 @@ import re
|
||||
|
||||
import cattrs
|
||||
from fastapi import Query, APIRouter
|
||||
from fastapi.responses import JSONResponse
|
||||
|
||||
from zhenxun.services.log import logger
|
||||
from zhenxun.configs.config import Config
|
||||
@@ -25,11 +26,13 @@ router = APIRouter(prefix="/plugin")
|
||||
@router.get(
|
||||
"/get_plugin_list",
|
||||
dependencies=[authentication()],
|
||||
response_model=Result[list[PluginInfo]],
|
||||
response_class=JSONResponse,
|
||||
deprecated="获取插件列表", # type: ignore
|
||||
)
|
||||
async def _(
|
||||
plugin_type: list[PluginType] = Query(None), menu_type: str | None = None
|
||||
) -> Result:
|
||||
) -> Result[list[PluginInfo]]:
|
||||
try:
|
||||
plugin_list: list[PluginInfo] = []
|
||||
query = DbPluginInfo
|
||||
@@ -61,9 +64,11 @@ async def _(
|
||||
@router.get(
|
||||
"/get_plugin_count",
|
||||
dependencies=[authentication()],
|
||||
response_model=Result[int],
|
||||
response_class=JSONResponse,
|
||||
deprecated="获取插件数量", # type: ignore
|
||||
)
|
||||
async def _() -> Result:
|
||||
async def _() -> Result[int]:
|
||||
plugin_count = PluginCount()
|
||||
plugin_count.normal = await DbPluginInfo.filter(
|
||||
plugin_type=PluginType.NORMAL, load_status=True
|
||||
@@ -82,7 +87,11 @@ async def _() -> Result:
|
||||
|
||||
|
||||
@router.post(
|
||||
"/update_plugin", dependencies=[authentication()], description="更新插件参数"
|
||||
"/update_plugin",
|
||||
dependencies=[authentication()],
|
||||
response_model=Result,
|
||||
response_class=JSONResponse,
|
||||
description="更新插件参数",
|
||||
)
|
||||
async def _(plugin: UpdatePlugin) -> Result:
|
||||
try:
|
||||
@@ -113,7 +122,13 @@ async def _(plugin: UpdatePlugin) -> Result:
|
||||
return Result.ok(info="已经帮你写好啦!")
|
||||
|
||||
|
||||
@router.post("/change_switch", dependencies=[authentication()], description="开关插件")
|
||||
@router.post(
|
||||
"/change_switch",
|
||||
dependencies=[authentication()],
|
||||
response_model=Result,
|
||||
response_class=JSONResponse,
|
||||
description="开关插件",
|
||||
)
|
||||
async def _(param: PluginSwitch) -> Result:
|
||||
db_plugin = await DbPluginInfo.get_or_none(module=param.module, load_status=True)
|
||||
if not db_plugin:
|
||||
@@ -129,9 +144,13 @@ async def _(param: PluginSwitch) -> Result:
|
||||
|
||||
|
||||
@router.get(
|
||||
"/get_plugin_menu_type", dependencies=[authentication()], description="获取插件类型"
|
||||
"/get_plugin_menu_type",
|
||||
dependencies=[authentication()],
|
||||
response_model=Result[list[str]],
|
||||
response_class=JSONResponse,
|
||||
description="获取插件类型",
|
||||
)
|
||||
async def _() -> Result:
|
||||
async def _() -> Result[list[str]]:
|
||||
menu_type_list = []
|
||||
result = await DbPluginInfo.annotate().values_list("menu_type", flat=True)
|
||||
for r in result:
|
||||
@@ -140,8 +159,14 @@ async def _() -> Result:
|
||||
return Result.ok(menu_type_list)
|
||||
|
||||
|
||||
@router.get("/get_plugin", dependencies=[authentication()], description="获取插件详情")
|
||||
async def _(module: str) -> Result:
|
||||
@router.get(
|
||||
"/get_plugin",
|
||||
dependencies=[authentication()],
|
||||
response_model=Result[PluginDetail],
|
||||
response_class=JSONResponse,
|
||||
description="获取插件详情",
|
||||
)
|
||||
async def _(module: str) -> Result[PluginDetail]:
|
||||
db_plugin = await DbPluginInfo.get_or_none(module=module, load_status=True)
|
||||
if not db_plugin:
|
||||
return Result.fail("插件不存在...")
|
||||
|
||||
@@ -1,25 +1,37 @@
|
||||
from nonebot import require
|
||||
from fastapi import APIRouter
|
||||
from fastapi.responses import JSONResponse
|
||||
|
||||
from zhenxun.models.plugin_info import PluginInfo
|
||||
|
||||
from .model import PluginIr
|
||||
from ....base_model import Result
|
||||
from ....utils import authentication
|
||||
|
||||
require("plugin_store")
|
||||
from zhenxun.builtin_plugins.plugin_store import ShopManage
|
||||
|
||||
router = APIRouter(prefix="/store")
|
||||
|
||||
|
||||
@router.get(
|
||||
"/get_plugin_store",
|
||||
dependencies=[authentication()],
|
||||
response_model=Result[dict],
|
||||
response_class=JSONResponse,
|
||||
deprecated="获取插件商店插件信息", # type: ignore
|
||||
)
|
||||
async def _() -> Result:
|
||||
async def _() -> Result[dict]:
|
||||
try:
|
||||
require("plugin_store")
|
||||
from zhenxun.builtin_plugins.plugin_store import ShopManage
|
||||
|
||||
data = await ShopManage.get_data()
|
||||
return Result.ok(data)
|
||||
plugin_list = [
|
||||
{**data[name].dict(), "name": name, "id": idx}
|
||||
for idx, name in enumerate(data)
|
||||
]
|
||||
modules = await PluginInfo.filter(load_status=True).values_list(
|
||||
"module", flat=True
|
||||
)
|
||||
return Result.ok({"install_module": modules, "plugin_list": plugin_list})
|
||||
except Exception as e:
|
||||
return Result.fail(f"获取插件商店插件信息失败: {type(e)}: {e}")
|
||||
|
||||
@@ -27,24 +39,52 @@ async def _() -> Result:
|
||||
@router.post(
|
||||
"/install_plugin",
|
||||
dependencies=[authentication()],
|
||||
response_model=Result,
|
||||
response_class=JSONResponse,
|
||||
deprecated="安装插件", # type: ignore
|
||||
)
|
||||
async def _(param: PluginIr) -> Result:
|
||||
try:
|
||||
require("plugin_store")
|
||||
from zhenxun.builtin_plugins.plugin_store import ShopManage
|
||||
|
||||
result = await ShopManage.add_plugin(param.id) # type: ignore
|
||||
return Result.ok(result)
|
||||
return Result.ok(info=result)
|
||||
except Exception as e:
|
||||
return Result.fail(f"安装插件失败: {type(e)}: {e}")
|
||||
|
||||
|
||||
@router.post(
|
||||
"/update_plugin",
|
||||
dependencies=[authentication()],
|
||||
response_model=Result,
|
||||
response_class=JSONResponse,
|
||||
deprecated="更新插件", # type: ignore
|
||||
)
|
||||
async def _(param: PluginIr) -> Result:
|
||||
try:
|
||||
require("plugin_store")
|
||||
from zhenxun.builtin_plugins.plugin_store import ShopManage
|
||||
|
||||
result = await ShopManage.update_plugin(param.id) # type: ignore
|
||||
return Result.ok(info=result)
|
||||
except Exception as e:
|
||||
return Result.fail(f"更新插件失败: {type(e)}: {e}")
|
||||
|
||||
|
||||
@router.post(
|
||||
"/remove_plugin",
|
||||
dependencies=[authentication()],
|
||||
response_model=Result,
|
||||
response_class=JSONResponse,
|
||||
deprecated="移除插件", # type: ignore
|
||||
)
|
||||
async def _(param: PluginIr) -> Result:
|
||||
try:
|
||||
require("plugin_store")
|
||||
from zhenxun.builtin_plugins.plugin_store import ShopManage
|
||||
|
||||
result = await ShopManage.remove_plugin(param.id) # type: ignore
|
||||
return Result.ok(result)
|
||||
return Result.ok(info=result)
|
||||
except Exception as e:
|
||||
return Result.fail(f"移除插件失败: {type(e)}: {e}")
|
||||
|
||||
@@ -4,10 +4,11 @@ from pathlib import Path
|
||||
|
||||
import aiofiles
|
||||
from fastapi import APIRouter
|
||||
from fastapi.responses import JSONResponse
|
||||
|
||||
from zhenxun.utils._build_image import BuildImage
|
||||
|
||||
from ....base_model import Result
|
||||
from ....base_model import Result, SystemFolderSize
|
||||
from ....utils import authentication, get_system_disk
|
||||
from .model import AddFile, DirFile, SaveFile, DeleteFile, RenameFile
|
||||
|
||||
@@ -17,9 +18,13 @@ IMAGE_TYPE = ["jpg", "jpeg", "png", "gif", "bmp", "webp", "svg"]
|
||||
|
||||
|
||||
@router.get(
|
||||
"/get_dir_list", dependencies=[authentication()], description="获取文件列表"
|
||||
"/get_dir_list",
|
||||
dependencies=[authentication()],
|
||||
response_model=Result[list[DirFile]],
|
||||
response_class=JSONResponse,
|
||||
description="获取文件列表",
|
||||
)
|
||||
async def _(path: str | None = None) -> Result:
|
||||
async def _(path: str | None = None) -> Result[list[DirFile]]:
|
||||
base_path = Path(path) if path else Path()
|
||||
data_list = []
|
||||
for file in os.listdir(base_path):
|
||||
@@ -37,13 +42,23 @@ async def _(path: str | None = None) -> Result:
|
||||
|
||||
|
||||
@router.get(
|
||||
"/get_resources_size", dependencies=[authentication()], description="获取文件列表"
|
||||
"/get_resources_size",
|
||||
dependencies=[authentication()],
|
||||
response_model=Result[SystemFolderSize],
|
||||
response_class=JSONResponse,
|
||||
description="获取文件列表",
|
||||
)
|
||||
async def _(full_path: str | None = None) -> Result:
|
||||
async def _(full_path: str | None = None) -> Result[SystemFolderSize]:
|
||||
return Result.ok(await get_system_disk(full_path))
|
||||
|
||||
|
||||
@router.post("/delete_file", dependencies=[authentication()], description="删除文件")
|
||||
@router.post(
|
||||
"/delete_file",
|
||||
dependencies=[authentication()],
|
||||
response_model=Result,
|
||||
response_class=JSONResponse,
|
||||
description="删除文件",
|
||||
)
|
||||
async def _(param: DeleteFile) -> Result:
|
||||
path = Path(param.full_path)
|
||||
if not path or not path.exists():
|
||||
@@ -56,7 +71,11 @@ async def _(param: DeleteFile) -> Result:
|
||||
|
||||
|
||||
@router.post(
|
||||
"/delete_folder", dependencies=[authentication()], description="删除文件夹"
|
||||
"/delete_folder",
|
||||
dependencies=[authentication()],
|
||||
response_model=Result,
|
||||
response_class=JSONResponse,
|
||||
description="删除文件夹",
|
||||
)
|
||||
async def _(param: DeleteFile) -> Result:
|
||||
path = Path(param.full_path)
|
||||
@@ -69,7 +88,13 @@ async def _(param: DeleteFile) -> Result:
|
||||
return Result.warning_(f"删除失败: {e!s}")
|
||||
|
||||
|
||||
@router.post("/rename_file", dependencies=[authentication()], description="重命名文件")
|
||||
@router.post(
|
||||
"/rename_file",
|
||||
dependencies=[authentication()],
|
||||
response_model=Result,
|
||||
response_class=JSONResponse,
|
||||
description="重命名文件",
|
||||
)
|
||||
async def _(param: RenameFile) -> Result:
|
||||
path = (
|
||||
(Path(param.parent) / param.old_name) if param.parent else Path(param.old_name)
|
||||
@@ -84,7 +109,11 @@ async def _(param: RenameFile) -> Result:
|
||||
|
||||
|
||||
@router.post(
|
||||
"/rename_folder", dependencies=[authentication()], description="重命名文件夹"
|
||||
"/rename_folder",
|
||||
dependencies=[authentication()],
|
||||
response_model=Result,
|
||||
response_class=JSONResponse,
|
||||
description="重命名文件夹",
|
||||
)
|
||||
async def _(param: RenameFile) -> Result:
|
||||
path = (
|
||||
@@ -100,7 +129,13 @@ async def _(param: RenameFile) -> Result:
|
||||
return Result.warning_(f"重命名失败: {e!s}")
|
||||
|
||||
|
||||
@router.post("/add_file", dependencies=[authentication()], description="新建文件")
|
||||
@router.post(
|
||||
"/add_file",
|
||||
dependencies=[authentication()],
|
||||
response_model=Result,
|
||||
response_class=JSONResponse,
|
||||
description="新建文件",
|
||||
)
|
||||
async def _(param: AddFile) -> Result:
|
||||
path = (Path(param.parent) / param.name) if param.parent else Path(param.name)
|
||||
if path.exists():
|
||||
@@ -112,7 +147,13 @@ async def _(param: AddFile) -> Result:
|
||||
return Result.warning_(f"新建文件失败: {e!s}")
|
||||
|
||||
|
||||
@router.post("/add_folder", dependencies=[authentication()], description="新建文件夹")
|
||||
@router.post(
|
||||
"/add_folder",
|
||||
dependencies=[authentication()],
|
||||
response_model=Result,
|
||||
response_class=JSONResponse,
|
||||
description="新建文件夹",
|
||||
)
|
||||
async def _(param: AddFile) -> Result:
|
||||
path = (Path(param.parent) / param.name) if param.parent else Path(param.name)
|
||||
if path.exists():
|
||||
@@ -124,7 +165,13 @@ async def _(param: AddFile) -> Result:
|
||||
return Result.warning_(f"新建文件夹失败: {e!s}")
|
||||
|
||||
|
||||
@router.get("/read_file", dependencies=[authentication()], description="读取文件")
|
||||
@router.get(
|
||||
"/read_file",
|
||||
dependencies=[authentication()],
|
||||
response_model=Result[str],
|
||||
response_class=JSONResponse,
|
||||
description="读取文件",
|
||||
)
|
||||
async def _(full_path: str) -> Result:
|
||||
path = Path(full_path)
|
||||
if not path.exists():
|
||||
@@ -136,8 +183,14 @@ async def _(full_path: str) -> Result:
|
||||
return Result.warning_(f"读取文件失败: {e!s}")
|
||||
|
||||
|
||||
@router.post("/save_file", dependencies=[authentication()], description="读取文件")
|
||||
async def _(param: SaveFile) -> Result:
|
||||
@router.post(
|
||||
"/save_file",
|
||||
dependencies=[authentication()],
|
||||
response_model=Result[str],
|
||||
response_class=JSONResponse,
|
||||
description="读取文件",
|
||||
)
|
||||
async def _(param: SaveFile) -> Result[str]:
|
||||
path = Path(param.full_path)
|
||||
try:
|
||||
async with aiofiles.open(path, "w", encoding="utf-8") as f:
|
||||
@@ -147,8 +200,14 @@ async def _(param: SaveFile) -> Result:
|
||||
return Result.warning_(f"保存文件失败: {e!s}")
|
||||
|
||||
|
||||
@router.get("/get_image", dependencies=[authentication()], description="读取图片base64")
|
||||
async def _(full_path: str) -> Result:
|
||||
@router.get(
|
||||
"/get_image",
|
||||
dependencies=[authentication()],
|
||||
response_model=Result[str],
|
||||
response_class=JSONResponse,
|
||||
description="读取图片base64",
|
||||
)
|
||||
async def _(full_path: str) -> Result[str]:
|
||||
path = Path(full_path)
|
||||
if not path.exists():
|
||||
return Result.warning_("文件不存在...")
|
||||
|
||||
Reference in New Issue
Block a user