重构webui主页与好友/群组api

This commit is contained in:
HibiKier
2023-12-30 05:27:45 +08:00
parent 081c86aba0
commit 25af1802af
27 changed files with 1530 additions and 897 deletions
+5 -4
View File
@@ -1,4 +1,5 @@
from .group import *
from .plugins import *
from .request import *
from .system import *
# from .group import *
# from .plugins import *
# from .request import *
# from .system import *
from .tabs import *
+65 -65
View File
@@ -1,75 +1,75 @@
from datetime import datetime, timedelta
from typing import List, Optional
# from datetime import datetime, timedelta
# from typing import List, Optional
import nonebot
from fastapi import APIRouter
# 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 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
# from ..base_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"
# AVA_URL = "http://q1.qlogo.cn/g?b=qq&nk={}&s=160"
router = APIRouter()
# router = APIRouter()
@router.get("/get_bot_info", dependencies=[authentication()])
async def _(self_id: Optional[str] = None) -> Result:
"""
获取Bot基础信息
# @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.
# 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
)
# 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连接")
# return Result.ok(bot_list, "已获取操作列表")
# return Result.fail("无Bot连接")
+62 -62
View File
@@ -1,69 +1,69 @@
from fastapi import APIRouter
from pydantic.error_wrappers import ValidationError
# from fastapi import APIRouter
# from pydantic.error_wrappers import ValidationError
from services.log import logger
from utils.manager import group_manager
from utils.utils import get_bot
# from services.log import logger
# from utils.manager import group_manager
# from utils.utils import get_bot
from ..models.model import Group, GroupResult, Result, Task
from ..models.params import UpdateGroup
from ..utils import authentication
# from ..base_model import Group, GroupResult, Result, Task
# from ..models.params import UpdateGroup
# from ..utils import authentication
router = APIRouter()
# router = APIRouter()
@router.get("/get_group", dependencies=[authentication()])
async def _() -> Result:
"""
获取群信息
"""
group_list_result = []
try:
group_info = {}
if bot := get_bot():
group_list = await bot.get_group_list()
for g in group_list:
group_info[g["group_id"]] = Group(**g)
group_data = group_manager.get_data()
for group_id in group_data.group_manager:
task_list = []
data = group_manager[group_id].dict()
for tn, status in data["group_task_status"].items():
task_list.append(
Task(
**{
"name": tn,
"nameZh": group_manager.get_task_data().get(tn) or tn,
"status": status,
}
)
)
data["task"] = task_list
if x := group_info.get(int(group_id)):
data["group"] = x
else:
continue
group_list_result.append(GroupResult(**data))
except Exception as e:
logger.error("调用API错误", "/get_group", e=e)
return Result.fail(f"{type(e)}: {e}")
return Result.ok(group_list_result, "拿到了新鲜出炉的数据!")
# @router.get("/get_group", dependencies=[authentication()])
# async def _() -> Result:
# """
# 获取群信息
# """
# group_list_result = []
# try:
# group_info = {}
# if bot := get_bot():
# group_list = await bot.get_group_list()
# for g in group_list:
# group_info[g["group_id"]] = Group(**g)
# group_data = group_manager.get_data()
# for group_id in group_data.group_manager:
# task_list = []
# data = group_manager[group_id].dict()
# for tn, status in data["group_task_status"].items():
# task_list.append(
# Task(
# **{
# "name": tn,
# "nameZh": group_manager.get_task_data().get(tn) or tn,
# "status": status,
# }
# )
# )
# data["task"] = task_list
# if x := group_info.get(int(group_id)):
# data["group"] = x
# else:
# continue
# group_list_result.append(GroupResult(**data))
# except Exception as e:
# logger.error("调用API错误", "/get_group", e=e)
# return Result.fail(f"{type(e)}: {e}")
# return Result.ok(group_list_result, "拿到了新鲜出炉的数据!")
@router.post("/update_group", dependencies=[authentication()])
async def _(group: UpdateGroup) -> Result:
"""
修改群信息
"""
try:
group_id = group.group_id
group_manager.set_group_level(group_id, group.level)
if group.status:
group_manager.turn_on_group_bot_status(group_id)
else:
group_manager.shutdown_group_bot_status(group_id)
group_manager.save()
except Exception as e:
logger.error("调用API错误", "/get_group", e=e)
return Result.fail(f"{type(e)}: {e}")
return Result.ok(info="已完成记录!")
# @router.post("/update_group", dependencies=[authentication()])
# async def _(group: UpdateGroup) -> Result:
# """
# 修改群信息
# """
# try:
# group_id = group.group_id
# group_manager.set_group_level(group_id, group.level)
# if group.status:
# group_manager.turn_on_group_bot_status(group_id)
# else:
# group_manager.shutdown_group_bot_status(group_id)
# group_manager.save()
# except Exception as e:
# logger.error("调用API错误", "/get_group", e=e)
# return Result.fail(f"{type(e)}: {e}")
# return Result.ok(info="已完成记录!")
+7 -2
View File
@@ -1,6 +1,6 @@
import asyncio
import re
from typing import Awaitable, Callable, ClassVar, Dict, Generic, List, Set, TypeVar
from typing import Awaitable, Callable, Dict, Generic, List, Set, TypeVar
from urllib.parse import urlparse
PATTERN = r"\x1b(\[.*?[@-~]|\].*?(\x07|\x1b\\))"
@@ -10,6 +10,11 @@ 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] = {}
@@ -42,4 +47,4 @@ class LogStorage(Generic[_T]):
return
LOG_STORAGE = LogStorage[str]()
LOG_STORAGE: LogStorage[str] = LogStorage[str]()
+7 -2
View File
@@ -2,7 +2,7 @@ from typing import List
from fastapi import APIRouter, WebSocket
from loguru import logger
from nonebot.utils import escape_tag, run_sync
from nonebot.utils import escape_tag
from starlette.websockets import WebSocket, WebSocketDisconnect, WebSocketState
from .log_manager import LOG_STORAGE
@@ -12,7 +12,12 @@ router = APIRouter()
@router.get("/logs", response_model=List[str])
async def system_logs_history(reverse: bool = False):
return LOG_STORAGE.list(reverse=reverse)
"""历史日志
参数:
reverse: 反转顺序.
"""
return LOG_STORAGE.list(reverse=reverse) # type: ignore
@router.websocket("/logs")
+105 -105
View File
@@ -1,115 +1,115 @@
from typing import Optional
# from typing import Optional
import cattrs
from fastapi import APIRouter
# import cattrs
# from fastapi import APIRouter
from configs.config import Config
from services.log import logger
from utils.manager import plugin_data_manager, plugins2settings_manager, plugins_manager
from utils.manager.models import PluginData, PluginType
# from configs.config import Config
# from services.log import logger
# from utils.manager import plugin_data_manager, plugins2settings_manager, plugins_manager
# from utils.manager.models import PluginData, PluginType
from ..config import *
from ..models.model import Plugin, PluginConfig, Result
from ..models.params import UpdateConfig, UpdatePlugin
from ..utils import authentication
# from ..config import *
# from ..base_model import Plugin, PluginConfig, Result
# from ..models.params import UpdateConfig, UpdatePlugin
# from ..utils import authentication
router = APIRouter()
# router = APIRouter()
@router.get("/get_plugins", dependencies=[authentication()])
def _(
plugin_type: PluginType,
) -> Result:
"""
获取插件列表
:param plugin_type: 类型 normal, superuser, hidden, admin
"""
try:
plugin_list = []
for module in plugin_data_manager.keys():
plugin_data: Optional[PluginData] = plugin_data_manager[module]
if plugin_data and plugin_data.plugin_type == plugin_type:
plugin_config = None
if plugin_data.plugin_configs:
plugin_config = {}
for key in plugin_data.plugin_configs:
plugin_config[key] = PluginConfig(
key=key,
module=module,
has_type=bool(plugin_data.plugin_configs[key].type),
**plugin_data.plugin_configs[key].dict(),
)
plugin_list.append(
Plugin(
model=module,
plugin_settings=plugin_data.plugin_setting,
plugin_manager=plugin_data.plugin_status,
plugin_config=plugin_config,
cd_limit=plugin_data.plugin_cd,
block_limit=plugin_data.plugin_block,
count_limit=plugin_data.plugin_count,
)
)
except Exception as e:
logger.error("调用API错误", "/get_plugins", e=e)
return Result.fail(f"{type(e)}: {e}")
return Result.ok(plugin_list, "拿到了新鲜出炉的数据!")
# @router.get("/get_plugins", dependencies=[authentication()])
# def _(
# plugin_type: PluginType,
# ) -> Result:
# """
# 获取插件列表
# :param plugin_type: 类型 normal, superuser, hidden, admin
# """
# try:
# plugin_list = []
# for module in plugin_data_manager.keys():
# plugin_data: Optional[PluginData] = plugin_data_manager[module]
# if plugin_data and plugin_data.plugin_type == plugin_type:
# plugin_config = None
# if plugin_data.plugin_configs:
# plugin_config = {}
# for key in plugin_data.plugin_configs:
# plugin_config[key] = PluginConfig(
# key=key,
# module=module,
# has_type=bool(plugin_data.plugin_configs[key].type),
# **plugin_data.plugin_configs[key].dict(),
# )
# plugin_list.append(
# Plugin(
# model=module,
# plugin_settings=plugin_data.plugin_setting,
# plugin_manager=plugin_data.plugin_status,
# plugin_config=plugin_config,
# cd_limit=plugin_data.plugin_cd,
# block_limit=plugin_data.plugin_block,
# count_limit=plugin_data.plugin_count,
# )
# )
# except Exception as e:
# logger.error("调用API错误", "/get_plugins", e=e)
# return Result.fail(f"{type(e)}: {e}")
# return Result.ok(plugin_list, "拿到了新鲜出炉的数据!")
@router.post("/update_plugins", dependencies=[authentication()])
def _(plugin: UpdatePlugin) -> Result:
"""
修改插件信息
:param plugin: 插件内容
"""
try:
module = plugin.module
if p2s := plugins2settings_manager.get(module):
p2s.default_status = plugin.default_status
p2s.limit_superuser = plugin.limit_superuser
p2s.cost_gold = plugin.cost_gold
p2s.cmd = plugin.cmd
p2s.level = plugin.group_level
if pd := plugin_data_manager.get(module):
menu_lin = None
if len(pd.menu_type) > 1:
menu_lin = pd.menu_type[1]
if menu_lin is not None:
pd.menu_type = (plugin.menu_type, menu_lin)
else:
pd.menu_type = (plugin.menu_type,)
if pm := plugins_manager.get(module):
if plugin.block_type:
pm.block_type = plugin.block_type
pm.status = False
else:
pm.block_type = None
pm.status = True
plugins2settings_manager.save()
plugins_manager.save()
except Exception as e:
logger.error("调用API错误", "/update_plugins", e=e)
return Result.fail(f"{type(e)}: {e}")
return Result.ok(info="已经帮你写好啦!")
# @router.post("/update_plugins", dependencies=[authentication()])
# def _(plugin: UpdatePlugin) -> Result:
# """
# 修改插件信息
# :param plugin: 插件内容
# """
# try:
# module = plugin.module
# if p2s := plugins2settings_manager.get(module):
# p2s.default_status = plugin.default_status
# p2s.limit_superuser = plugin.limit_superuser
# p2s.cost_gold = plugin.cost_gold
# p2s.cmd = plugin.cmd
# p2s.level = plugin.group_level
# if pd := plugin_data_manager.get(module):
# menu_lin = None
# if len(pd.menu_type) > 1:
# menu_lin = pd.menu_type[1]
# if menu_lin is not None:
# pd.menu_type = (plugin.menu_type, menu_lin)
# else:
# pd.menu_type = (plugin.menu_type,)
# if pm := plugins_manager.get(module):
# if plugin.block_type:
# pm.block_type = plugin.block_type
# pm.status = False
# else:
# pm.block_type = None
# pm.status = True
# plugins2settings_manager.save()
# plugins_manager.save()
# except Exception as e:
# logger.error("调用API错误", "/update_plugins", e=e)
# return Result.fail(f"{type(e)}: {e}")
# return Result.ok(info="已经帮你写好啦!")
@router.post("/update_config", dependencies=[authentication()])
def _(config_list: List[UpdateConfig]) -> Result:
try:
for config in config_list:
if cg := Config.get(config.module):
if c := cg.configs.get(config.key):
if isinstance(c.value, (list, tuple)) or isinstance(
c.default_value, (list, tuple)
):
value = config.value.split(",")
else:
value = config.value
if c.type and value is not None:
value = cattrs.structure(value, c.type)
Config.set_config(config.module, config.key, value)
except Exception as e:
logger.error("调用API错误", "/update_config", e=e)
return Result.fail(f"{type(e)}: {e}")
Config.save(save_simple_data=True)
return Result.ok(info="写入配置项了哦!")
# @router.post("/update_config", dependencies=[authentication()])
# def _(config_list: List[UpdateConfig]) -> Result:
# try:
# for config in config_list:
# if cg := Config.get(config.module):
# if c := cg.configs.get(config.key):
# if isinstance(c.value, (list, tuple)) or isinstance(
# c.default_value, (list, tuple)
# ):
# value = config.value.split(",")
# else:
# value = config.value
# if c.type and value is not None:
# value = cattrs.structure(value, c.type)
# Config.set_config(config.module, config.key, value)
# except Exception as e:
# logger.error("调用API错误", "/update_config", e=e)
# return Result.fail(f"{type(e)}: {e}")
# Config.save(save_simple_data=True)
# return Result.ok(info="写入配置项了哦!")
+44 -44
View File
@@ -8,7 +8,7 @@ from services.log import logger
from utils.manager import requests_manager
from utils.utils import get_bot
from ..models.model import RequestResult, Result
from ..base_model import RequestResult, Result
from ..models.params import HandleRequest
from ..utils import authentication
@@ -42,46 +42,46 @@ def _(request_type: Optional[str]) -> Result:
return Result.ok(info="成功清除了数据")
@router.post("/handle_request", dependencies=[authentication()])
async def _(parma: HandleRequest) -> Result:
"""
操作请求
:param parma: 参数
"""
try:
result = "操作成功!"
flag = 3
if bot := get_bot():
if parma.handle == "approve":
if parma.type == "group":
if rid := requests_manager.get_group_id(parma.id):
# await GroupInfo.update_or_create(defaults={"group_flag": 1}, )
if group := await GroupInfo.get_or_none(group_id=str(rid)):
await group.update_or_create(group_flag=1)
else:
group_info = await bot.get_group_info(group_id=rid)
await GroupInfo.update_or_create(
group_id=str(group_info["group_id"]),
defaults={
"group_name": group_info["group_name"],
"max_member_count": group_info["max_member_count"],
"member_count": group_info["member_count"],
"group_flag": 1,
},
)
flag = await requests_manager.approve(bot, parma.id, parma.type)
elif parma.handle == "refuse":
flag = await requests_manager.refused(bot, parma.id, parma.type)
elif parma.handle == "delete":
requests_manager.delete_request(parma.id, parma.type)
if parma.handle != "delete":
if flag == 1:
result = "该请求已失效"
requests_manager.delete_request(parma.id, parma.type)
elif flag == 2:
result = "未找到此Id"
return Result.ok(result, "成功处理了请求!")
return Result.fail("Bot未连接")
except Exception as e:
logger.error("调用API错误", "/get_group", e=e)
return Result.fail(f"{type(e)}: {e}")
# @router.post("/handle_request", dependencies=[authentication()])
# async def _(parma: HandleRequest) -> Result:
# """
# 操作请求
# :param parma: 参数
# """
# try:
# result = "操作成功!"
# flag = 3
# if bot := get_bot():
# if parma.handle == "approve":
# if parma.type == "group":
# if rid := requests_manager.get_group_id(parma.id):
# # await GroupInfo.update_or_create(defaults={"group_flag": 1}, )
# if group := await GroupInfo.get_or_none(group_id=str(rid)):
# await group.update_or_create(group_flag=1)
# else:
# group_info = await bot.get_group_info(group_id=rid)
# await GroupInfo.update_or_create(
# group_id=str(group_info["group_id"]),
# defaults={
# "group_name": group_info["group_name"],
# "max_member_count": group_info["max_member_count"],
# "member_count": group_info["member_count"],
# "group_flag": 1,
# },
# )
# flag = await requests_manager.approve(bot, parma.id, parma.type)
# elif parma.handle == "refuse":
# flag = await requests_manager.refused(bot, parma.id, parma.type)
# elif parma.handle == "delete":
# requests_manager.delete_request(parma.id, parma.type)
# if parma.handle != "delete":
# if flag == 1:
# result = "该请求已失效"
# requests_manager.delete_request(parma.id, parma.type)
# elif flag == 2:
# result = "未找到此Id"
# return Result.ok(result, "成功处理了请求!")
# return Result.fail("Bot未连接")
# except Exception as e:
# logger.error("调用API错误", "/get_group", e=e)
# return Result.fail(f"{type(e)}: {e}")
+205 -205
View File
@@ -1,228 +1,228 @@
import asyncio
import os
from datetime import datetime
from pathlib import Path
from typing import Dict, Optional, Union
# import asyncio
# import os
# from datetime import datetime
# from pathlib import Path
# from typing import Dict, Optional, Union
import psutil
import ujson as json
from fastapi import APIRouter
# import psutil
# import ujson as json
# from fastapi import APIRouter
from configs.path_config import (
DATA_PATH,
FONT_PATH,
IMAGE_PATH,
LOG_PATH,
RECORD_PATH,
TEMP_PATH,
TEXT_PATH,
)
from services.log import logger
from utils.http_utils import AsyncHttpx
# from configs.path_config import (
# DATA_PATH,
# FONT_PATH,
# IMAGE_PATH,
# LOG_PATH,
# RECORD_PATH,
# TEMP_PATH,
# TEXT_PATH,
# )
# from services.log import logger
# from utils.http_utils import AsyncHttpx
from ..models.model import (
Result,
SystemFolderSize,
SystemNetwork,
SystemResult,
SystemStatus,
SystemStatusList,
)
from ..utils import authentication
# from ..base_model import (
# Result,
# SystemFolderSize,
# SystemNetwork,
# SystemResult,
# SystemStatus,
# SystemStatusList,
# )
# from ..utils import authentication
CPU_DATA_PATH = DATA_PATH / "system" / "cpu.json"
MEMORY_DATA_PATH = DATA_PATH / "system" / "memory.json"
DISK_DATA_PATH = DATA_PATH / "system" / "disk.json"
CPU_DATA_PATH.parent.mkdir(exist_ok=True, parents=True)
cpu_data = {"data": []}
memory_data = {"data": []}
disk_data = {"data": []}
# CPU_DATA_PATH = DATA_PATH / "system" / "cpu.json"
# MEMORY_DATA_PATH = DATA_PATH / "system" / "memory.json"
# DISK_DATA_PATH = DATA_PATH / "system" / "disk.json"
# CPU_DATA_PATH.parent.mkdir(exist_ok=True, parents=True)
# cpu_data = {"data": []}
# memory_data = {"data": []}
# disk_data = {"data": []}
router = APIRouter()
# router = APIRouter()
@router.get("/system", dependencies=[authentication()])
async def _() -> Result:
return await get_system_data()
# @router.get("/system", dependencies=[authentication()])
# async def _() -> Result:
# return await get_system_data()
@router.get("/status", dependencies=[authentication()])
async def _() -> Result:
return Result.ok(
await asyncio.get_event_loop().run_in_executor(None, _get_system_status),
)
# @router.get("/status", dependencies=[authentication()])
# async def _() -> Result:
# return Result.ok(
# await asyncio.get_event_loop().run_in_executor(None, _get_system_status),
# )
@router.get("/system/disk", dependencies=[authentication()])
async def _(type_: Optional[str] = None) -> Result:
return Result.ok(
data=await asyncio.get_event_loop().run_in_executor(
None, _get_system_disk, type_
),
)
# @router.get("/system/disk", dependencies=[authentication()])
# async def _(type_: Optional[str] = None) -> Result:
# return Result.ok(
# data=await asyncio.get_event_loop().run_in_executor(
# None, _get_system_disk, type_
# ),
# )
@router.get("/system/statusList", dependencies=[authentication()])
async def _() -> Result:
global cpu_data, memory_data, disk_data
await asyncio.get_event_loop().run_in_executor(None, _get_system_status)
cpu_rst = cpu_data["data"][-10:] if len(cpu_data["data"]) > 10 else cpu_data["data"]
memory_rst = (
memory_data["data"][-10:]
if len(memory_data["data"]) > 10
else memory_data["data"]
)
disk_rst = (
disk_data["data"][-10:] if len(disk_data["data"]) > 10 else disk_data["data"]
)
return Result.ok(
SystemStatusList(
cpu_data=cpu_rst,
memory_data=memory_rst,
disk_data=disk_rst,
),
)
# @router.get("/system/statusList", dependencies=[authentication()])
# async def _() -> Result:
# global cpu_data, memory_data, disk_data
# await asyncio.get_event_loop().run_in_executor(None, _get_system_status)
# cpu_rst = cpu_data["data"][-10:] if len(cpu_data["data"]) > 10 else cpu_data["data"]
# memory_rst = (
# memory_data["data"][-10:]
# if len(memory_data["data"]) > 10
# else memory_data["data"]
# )
# disk_rst = (
# disk_data["data"][-10:] if len(disk_data["data"]) > 10 else disk_data["data"]
# )
# return Result.ok(
# SystemStatusList(
# cpu_data=cpu_rst,
# memory_data=memory_rst,
# disk_data=disk_rst,
# ),
# )
async def get_system_data():
"""
说明:
获取系统信息,资源文件大小,网络状态等
"""
baidu = 200
google = 200
try:
await AsyncHttpx.get("https://www.baidu.com/", timeout=5)
except Exception as e:
logger.warning(f"访问BaiDu失败... {type(e)}: {e}")
baidu = 404
try:
await AsyncHttpx.get("https://www.google.com/", timeout=5)
except Exception as e:
logger.warning(f"访问Google失败... {type(e)}: {e}")
google = 404
network = SystemNetwork(baidu=baidu, google=google)
disk = await asyncio.get_event_loop().run_in_executor(None, _get_system_disk, None)
status = await asyncio.get_event_loop().run_in_executor(None, _get_system_status)
return Result.ok(
SystemResult(
status=status,
network=network,
disk=disk, # type: ignore
check_time=datetime.now().replace(microsecond=0),
),
)
# async def get_system_data():
# """
# 说明:
# 获取系统信息,资源文件大小,网络状态等
# """
# baidu = 200
# google = 200
# try:
# await AsyncHttpx.get("https://www.baidu.com/", timeout=5)
# except Exception as e:
# logger.warning(f"访问BaiDu失败... {type(e)}: {e}")
# baidu = 404
# try:
# await AsyncHttpx.get("https://www.google.com/", timeout=5)
# except Exception as e:
# logger.warning(f"访问Google失败... {type(e)}: {e}")
# google = 404
# network = SystemNetwork(baidu=baidu, google=google)
# disk = await asyncio.get_event_loop().run_in_executor(None, _get_system_disk, None)
# status = await asyncio.get_event_loop().run_in_executor(None, _get_system_status)
# return Result.ok(
# SystemResult(
# status=status,
# network=network,
# disk=disk, # type: ignore
# check_time=datetime.now().replace(microsecond=0),
# ),
# )
def _get_system_status() -> SystemStatus:
"""
说明:
获取系统信息等
"""
cpu = psutil.cpu_percent()
memory = psutil.virtual_memory().percent
disk = psutil.disk_usage("/").percent
save_system_data(cpu, memory, disk)
return SystemStatus(
cpu=cpu,
memory=memory,
disk=disk,
check_time=datetime.now().replace(microsecond=0),
)
# def _get_system_status() -> SystemStatus:
# """
# 说明:
# 获取系统信息等
# """
# cpu = psutil.cpu_percent()
# memory = psutil.virtual_memory().percent
# disk = psutil.disk_usage("/").percent
# save_system_data(cpu, memory, disk)
# return SystemStatus(
# cpu=cpu,
# memory=memory,
# disk=disk,
# check_time=datetime.now().replace(microsecond=0),
# )
def _get_system_disk(
type_: Optional[str],
) -> Union[SystemFolderSize, Dict[str, Union[float, datetime]]]:
"""
说明:
获取资源文件大小等
"""
if not type_:
disk = SystemFolderSize(
font_dir_size=_get_dir_size(FONT_PATH) / 1024 / 1024,
image_dir_size=_get_dir_size(IMAGE_PATH) / 1024 / 1024,
text_dir_size=_get_dir_size(TEXT_PATH) / 1024 / 1024,
record_dir_size=_get_dir_size(RECORD_PATH) / 1024 / 1024,
temp_dir_size=_get_dir_size(TEMP_PATH) / 1024 / 102,
data_dir_size=_get_dir_size(DATA_PATH) / 1024 / 1024,
log_dir_size=_get_dir_size(LOG_PATH) / 1024 / 1024,
check_time=datetime.now().replace(microsecond=0),
)
return disk
else:
if type_ == "image":
dir_path = IMAGE_PATH
elif type_ == "font":
dir_path = FONT_PATH
elif type_ == "text":
dir_path = TEXT_PATH
elif type_ == "record":
dir_path = RECORD_PATH
elif type_ == "data":
dir_path = DATA_PATH
elif type_ == "temp":
dir_path = TEMP_PATH
else:
dir_path = LOG_PATH
dir_map = {}
other_file_size = 0
for file in os.listdir(dir_path):
file = Path(dir_path / file)
if file.is_dir():
dir_map[file.name] = _get_dir_size(file) / 1024 / 1024
else:
other_file_size += os.path.getsize(file) / 1024 / 1024
dir_map["其他文件"] = other_file_size
dir_map["check_time"] = datetime.now().replace(microsecond=0)
return dir_map
# def _get_system_disk(
# type_: Optional[str],
# ) -> Union[SystemFolderSize, Dict[str, Union[float, datetime]]]:
# """
# 说明:
# 获取资源文件大小等
# """
# if not type_:
# disk = SystemFolderSize(
# font_dir_size=_get_dir_size(FONT_PATH) / 1024 / 1024,
# image_dir_size=_get_dir_size(IMAGE_PATH) / 1024 / 1024,
# text_dir_size=_get_dir_size(TEXT_PATH) / 1024 / 1024,
# record_dir_size=_get_dir_size(RECORD_PATH) / 1024 / 1024,
# temp_dir_size=_get_dir_size(TEMP_PATH) / 1024 / 102,
# data_dir_size=_get_dir_size(DATA_PATH) / 1024 / 1024,
# log_dir_size=_get_dir_size(LOG_PATH) / 1024 / 1024,
# check_time=datetime.now().replace(microsecond=0),
# )
# return disk
# else:
# if type_ == "image":
# dir_path = IMAGE_PATH
# elif type_ == "font":
# dir_path = FONT_PATH
# elif type_ == "text":
# dir_path = TEXT_PATH
# elif type_ == "record":
# dir_path = RECORD_PATH
# elif type_ == "data":
# dir_path = DATA_PATH
# elif type_ == "temp":
# dir_path = TEMP_PATH
# else:
# dir_path = LOG_PATH
# dir_map = {}
# other_file_size = 0
# for file in os.listdir(dir_path):
# file = Path(dir_path / file)
# if file.is_dir():
# dir_map[file.name] = _get_dir_size(file) / 1024 / 1024
# else:
# other_file_size += os.path.getsize(file) / 1024 / 1024
# dir_map["其他文件"] = other_file_size
# dir_map["check_time"] = datetime.now().replace(microsecond=0)
# return dir_map
def _get_dir_size(dir_path: Path) -> float:
"""
说明:
获取文件夹大小
参数:
:param dir_path: 文件夹路径
"""
size = 0
for root, dirs, files in os.walk(dir_path):
size += sum([os.path.getsize(os.path.join(root, name)) for name in files])
return size
# def _get_dir_size(dir_path: Path) -> float:
# """
# 说明:
# 获取文件夹大小
# 参数:
# :param dir_path: 文件夹路径
# """
# size = 0
# for root, dirs, files in os.walk(dir_path):
# size += sum([os.path.getsize(os.path.join(root, name)) for name in files])
# return size
def save_system_data(cpu: float, memory: float, disk: float):
"""
说明:
保存一些系统信息
参数:
:param cpu: cpu
:param memory: memory
:param disk: disk
"""
global cpu_data, memory_data, disk_data
if CPU_DATA_PATH.exists() and not cpu_data["data"]:
with open(CPU_DATA_PATH, "r") as f:
cpu_data = json.load(f)
if MEMORY_DATA_PATH.exists() and not memory_data["data"]:
with open(MEMORY_DATA_PATH, "r") as f:
memory_data = json.load(f)
if DISK_DATA_PATH.exists() and not disk_data["data"]:
with open(DISK_DATA_PATH, "r") as f:
disk_data = json.load(f)
now = str(datetime.now().time().replace(microsecond=0))
cpu_data["data"].append({"time": now, "data": cpu})
memory_data["data"].append({"time": now, "data": memory})
disk_data["data"].append({"time": now, "data": disk})
if len(cpu_data["data"]) > 50:
cpu_data["data"] = cpu_data["data"][-50:]
if len(memory_data["data"]) > 50:
memory_data["data"] = memory_data["data"][-50:]
if len(disk_data["data"]) > 50:
disk_data["data"] = disk_data["data"][-50:]
with open(CPU_DATA_PATH, "w") as f:
json.dump(cpu_data, f, indent=4, ensure_ascii=False)
with open(MEMORY_DATA_PATH, "w") as f:
json.dump(memory_data, f, indent=4, ensure_ascii=False)
with open(DISK_DATA_PATH, "w") as f:
json.dump(disk_data, f, indent=4, ensure_ascii=False)
# def save_system_data(cpu: float, memory: float, disk: float):
# """
# 说明:
# 保存一些系统信息
# 参数:
# :param cpu: cpu
# :param memory: memory
# :param disk: disk
# """
# global cpu_data, memory_data, disk_data
# if CPU_DATA_PATH.exists() and not cpu_data["data"]:
# with open(CPU_DATA_PATH, "r") as f:
# cpu_data = json.load(f)
# if MEMORY_DATA_PATH.exists() and not memory_data["data"]:
# with open(MEMORY_DATA_PATH, "r") as f:
# memory_data = json.load(f)
# if DISK_DATA_PATH.exists() and not disk_data["data"]:
# with open(DISK_DATA_PATH, "r") as f:
# disk_data = json.load(f)
# now = str(datetime.now().time().replace(microsecond=0))
# cpu_data["data"].append({"time": now, "data": cpu})
# memory_data["data"].append({"time": now, "data": memory})
# disk_data["data"].append({"time": now, "data": disk})
# if len(cpu_data["data"]) > 50:
# cpu_data["data"] = cpu_data["data"][-50:]
# if len(memory_data["data"]) > 50:
# memory_data["data"] = memory_data["data"][-50:]
# if len(disk_data["data"]) > 50:
# disk_data["data"] = disk_data["data"][-50:]
# with open(CPU_DATA_PATH, "w") as f:
# json.dump(cpu_data, f, indent=4, ensure_ascii=False)
# with open(MEMORY_DATA_PATH, "w") as f:
# json.dump(memory_data, f, indent=4, ensure_ascii=False)
# with open(DISK_DATA_PATH, "w") as f:
# json.dump(disk_data, f, indent=4, ensure_ascii=False)
+2
View File
@@ -0,0 +1,2 @@
from .main import *
from .manage import *
+149
View File
@@ -0,0 +1,149 @@
import asyncio
import time
from datetime import datetime, timedelta
from typing import List, Optional
import nonebot
from fastapi import APIRouter, WebSocket
from nonebot.utils import escape_tag
from starlette.websockets import WebSocket, WebSocketDisconnect, WebSocketState
from configs.config import NICKNAME
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 ....config import QueryDateType
from ....base_model import Result
from ....utils import authentication, get_system_status
from .data_source import bot_live
from .model import BaseInfo
AVA_URL = "http://q1.qlogo.cn/g?b=qq&nk={}&s=160"
run_time = time.time()
ws_router = APIRouter()
router = APIRouter()
@router.get("/get_base_info", dependencies=[authentication()], description="基础信息")
async def _(bot_id: Optional[str] = None) -> Result:
"""
获取Bot基础信息
Args:
qq (Optional[str], optional): qq号. Defaults to None.
Returns:
Result: 获取指定bot信息与bot列表
"""
bot_list: List[BaseInfo] = []
if bots := nonebot.get_bots():
select_bot: BaseInfo
for key, bot in bots.items():
bot_list.append(
BaseInfo(
bot=bot, # type: ignore
self_id=bot.self_id,
nickname=NICKNAME,
ava_url=AVA_URL.format(bot.self_id),
)
)
# 获取指定qq号的bot信息,若无指定则获取第一个
if _bl := [b for b in bot_list if b.self_id == bot_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=select_bot.self_id,
create_time__gte=now - timedelta(hours=now.hour),
).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
)
# 连接时间
select_bot.connect_time = bot_live.get(select_bot.self_id) or 0
return Result.ok(bot_list, "已获取操作列表")
return Result.warning_("无Bot连接...")
@router.get("/get_ch_count", dependencies=[authentication()], description="获取接收消息数量")
async def _(bot_id: str, query_type: Optional[QueryDateType] = None) -> Result:
if bots := nonebot.get_bots():
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连接...")
@router.get("get_fg_count", dependencies=[authentication()], description="好友/群组数量")
async def _(bot_id: str) -> Result:
if bots := nonebot.get_bots():
if bot_id not in bots:
return Result.warning_("指定Bot未连接...")
bot = bots[bot_id]
data = {
"friend_count": len(await bot.get_friend_list()),
"group_count": len(await bot.get_group_list()),
}
return Result.ok(data)
return Result.warning_("无Bot连接...")
@router.get("/get_run_time", dependencies=[authentication()], description="获取nb运行时间")
async def _() -> Result:
return Result.ok(int(time.time() - run_time))
@ws_router.websocket("/system_status")
async def system_logs_realtime(websocket: WebSocket):
await websocket.accept()
logger.debug("ws system_status is connect")
try:
while websocket.client_state == WebSocketState.CONNECTED:
system_status = await get_system_status()
await websocket.send_text(system_status.json())
await asyncio.sleep(5)
except WebSocketDisconnect:
pass
return
@@ -0,0 +1,36 @@
import time
from typing import Optional
import nonebot
from nonebot import Driver
from nonebot.adapters.onebot.v12 import Bot
driver: Driver = nonebot.get_driver()
class BotLive:
def __init__(self):
self._data = {}
def add(self, bot_id: str):
self._data[bot_id] = time.time()
def get(self, bot_id: str) -> Optional[int]:
return self._data.get(bot_id)
def remove(self, bot_id: str):
if bot_id in self._data:
del self._data[bot_id]
bot_live = BotLive()
@driver.on_bot_connect
async def _(bot: Bot):
bot_live.add(bot.self_id)
@driver.on_bot_disconnect
async def _(bot: Bot):
bot_live.remove(bot.self_id)
+56
View File
@@ -0,0 +1,56 @@
from nonebot.adapters.onebot.v11 import Bot
from pydantic import BaseModel
class SystemStatus(BaseModel):
"""
系统状态
"""
cpu: float
memory: float
disk: float
class BaseInfo(BaseModel):
"""
基础信息
"""
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
# """一月内累计接收消息"""
# received_messages_year: int = 0
# """一年内累计接受消息"""
connect_time: 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
+245
View File
@@ -0,0 +1,245 @@
from typing import Literal
import nonebot
from fastapi import APIRouter
from pydantic.error_wrappers import ValidationError
from configs.config import NICKNAME
from models.group_info import GroupInfo
from services.log import logger
from utils.manager import group_manager, requests_manager
from utils.utils import get_bot
from ....base_model import Result
from ....utils import authentication
from .model import (
DeleteFriend,
Friend,
FriendRequestResult,
Group,
GroupRequestResult,
GroupResult,
HandleRequest,
LeaveGroup,
Task,
UpdateGroup,
)
router = APIRouter()
@router.get("/get_group_list", dependencies=[authentication()], description="获取群组列表")
async def _(bot_id: str) -> Result:
"""
获取群信息
"""
if bots := nonebot.get_bots():
if bot_id not in bots:
return Result.warning_("指定Bot未连接...")
group_list_result = []
try:
group_info = {}
group_list = await bots[bot_id].get_group_list()
for g in group_list:
group_info[g["group_id"]] = Group(**g)
group_data = group_manager.get_data()
for group_id in group_data.group_manager:
task_list = []
data = group_manager[group_id].dict()
for tn, status in data["group_task_status"].items():
task_list.append(
Task(
**{
"name": tn,
"nameZh": group_manager.get_task_data().get(tn) or tn,
"status": status,
}
)
)
data["task"] = task_list
if x := group_info.get(int(group_id)):
data["group"] = x
else:
continue
group_list_result.append(GroupResult(**data))
except Exception as e:
logger.error("调用API错误", "/get_group_list", e=e)
return Result.fail(f"{type(e)}: {e}")
return Result.ok(group_list_result, "拿到了新鲜出炉的数据!")
return Result.warning_("无Bot连接...")
@router.post("/update_group", dependencies=[authentication()], description="修改群组信息")
async def _(group: UpdateGroup) -> Result:
try:
group_id = group.group_id
group_manager.set_group_level(group_id, group.level)
if group.status:
group_manager.turn_on_group_bot_status(group_id)
else:
group_manager.shutdown_group_bot_status(group_id)
if group.task_status:
for task in group.task_status:
if group.task_status[task]:
group_manager.open_group_task(group_id, task)
else:
group_manager.close_group_task(group_id, task)
group_manager.save()
except Exception as e:
logger.error("调用API错误", "/get_group", e=e)
return Result.fail(f"{type(e)}: {e}")
return Result.ok(info="已完成记录!")
@router.get("/get_friend_list", dependencies=[authentication()], description="获取好友列表")
async def _(bot_id: str) -> Result:
"""
获取群信息
"""
if bots := nonebot.get_bots():
if bot_id not in bots:
return Result.warning_("指定Bot未连接...")
try:
friend_list = await bots[bot_id].get_friend_list()
return Result.ok([Friend(**f) for f in friend_list], "拿到了新鲜出炉的数据!")
except Exception as e:
logger.error("调用API错误", "/get_group_list", e=e)
return Result.fail(f"{type(e)}: {e}")
return Result.warning_("无Bot连接...")
@router.get("/get_request_count", dependencies=[authentication()], description="获取请求数量")
def _() -> Result:
data = {
"friend_count": len(requests_manager.get_data().get("private") or []),
"group_count": len(requests_manager.get_data().get("group") or []),
}
return Result.ok(data, f"{NICKNAME}带来了最新的数据!")
@router.get("/get_request_list", dependencies=[authentication()], description="获取请求列表")
def _(request_type: Literal["private", "group"]) -> Result:
try:
req_data = requests_manager.get_data().get(request_type) or []
req_list = []
for x in req_data:
req_data[x]["oid"] = x
if request_type == "private":
req_list.append(FriendRequestResult(**req_data[x]))
else:
req_list.append(GroupRequestResult(**req_data[x]))
req_list.reverse()
except Exception as e:
logger.error("调用API错误", "/get_request", e=e)
return Result.fail(f"{type(e)}: {e}")
return Result.ok(req_list, f"{NICKNAME}带来了最新的数据!")
@router.delete("/clear_request", dependencies=[authentication()], description="清空请求列表")
def _(request_type: Literal["private", "group"]) -> Result:
"""
清空请求
:param type_: 类型
"""
requests_manager.clear(request_type)
return Result.ok(info="成功清除了数据!")
@router.post("/refuse_request", dependencies=[authentication()], description="拒绝请求")
async def _(parma: HandleRequest) -> Result:
"""
操作请求
:param parma: 参数
"""
try:
if bots := nonebot.get_bots():
bot_id = parma.bot_id
if bot_id not in nonebot.get_bots():
return Result.warning_("指定Bot未连接...")
flag = await requests_manager.refused(bots[bot_id], parma.id, parma.request_type) # type: ignore
if flag == 1:
requests_manager.delete_request(parma.id, parma.request_type)
return Result.warning_("该请求已失效...")
elif flag == 2:
return Result.warning_("未找到此Id请求...")
return Result.ok(info="成功处理了请求!")
return Result.warning_("Bot未连接...")
except Exception as e:
logger.error("调用API错误", "/refuse_request", e=e)
return Result.fail(f"{type(e)}: {e}")
@router.post("/delete_request", dependencies=[authentication()], description="忽略请求")
async def _(parma: HandleRequest) -> Result:
"""
操作请求
:param parma: 参数
"""
requests_manager.delete_request(parma.id, parma.request_type)
return Result.ok(info="成功处理了请求!")
@router.post("/approve_request", dependencies=[authentication()], description="同意请求")
async def _(parma: HandleRequest) -> Result:
"""
操作请求
:param parma: 参数
"""
try:
if bots := nonebot.get_bots():
bot_id = parma.bot_id
if bot_id not in nonebot.get_bots():
return Result.warning_("指定Bot未连接...")
if parma.request_type == "group":
if rid := requests_manager.get_group_id(parma.id):
if group := await GroupInfo.get_or_none(group_id=str(rid)):
await group.update_or_create(group_flag=1)
else:
group_info = await bots[bot_id].get_group_info(group_id=rid)
await GroupInfo.update_or_create(
group_id=str(group_info["group_id"]),
defaults={
"group_name": group_info["group_name"],
"max_member_count": group_info["max_member_count"],
"member_count": group_info["member_count"],
"group_flag": 1,
},
)
await requests_manager.approve(bots[bot_id], parma.id, parma.request_type) # type: ignore
return Result.ok(info="成功处理了请求!")
return Result.warning_("Bot未连接...")
except Exception as e:
logger.error("调用API错误", "/approve_request", e=e)
return Result.fail(f"{type(e)}: {e}")
@router.post("/leave_group", dependencies=[authentication()], description="退群")
async def _(param: LeaveGroup) -> Result:
try:
if bots := nonebot.get_bots():
bot_id = param.bot_id
group_list = await bots[bot_id].get_group_list()
if param.group_id not in [str(g["group_id"]) for g in group_list]:
return Result.warning_("Bot未在该群聊中...")
await bots[bot_id].set_group_leave(group_id=param.group_id)
return Result.ok(info="成功处理了请求!")
return Result.warning_("Bot未连接...")
except Exception as e:
logger.error("调用API错误", "/leave_group", e=e)
return Result.fail(f"{type(e)}: {e}")
@router.post("/delete_friend", dependencies=[authentication()], description="删除好友")
async def _(param: DeleteFriend) -> Result:
try:
if bots := nonebot.get_bots():
bot_id = param.bot_id
friend_list = await bots[bot_id].get_friend_list()
if param.user_id not in [str(g["user_id"]) for g in friend_list]:
return Result.warning_("Bot未有其好友...")
await bots[bot_id].delete_friend(user_id=param.user_id)
return Result.ok(info="成功处理了请求!")
return Result.warning_("Bot未连接...")
except Exception as e:
logger.error("调用API错误", "/delete_friend", e=e)
return Result.fail(f"{type(e)}: {e}")
+151
View File
@@ -0,0 +1,151 @@
from typing import Dict, List, Literal, Optional, Union
from matplotlib.dates import FR
from nonebot.adapters.onebot.v11 import Bot
from pydantic import BaseModel
class Group(BaseModel):
"""
群组信息
"""
group_id: Union[str, int]
"""群组id"""
group_name: str
"""群组名称"""
member_count: int
"""成员人数"""
max_member_count: int
"""群组最大人数"""
class Task(BaseModel):
"""
被动技能
"""
name: str
"""被动名称"""
nameZh: str
"""被动中文名称"""
status: bool
"""状态"""
class GroupResult(BaseModel):
"""
群组返回数据
"""
group: Group
"""Group"""
level: int
"""群等级"""
status: bool
"""状态"""
close_plugins: List[str]
"""关闭的插件"""
task: List[Task]
"""被动列表"""
class Friend(BaseModel):
"""
好友数据
"""
user_id: Union[str, int]
"""用户id"""
nickname: str = ""
"""昵称"""
remark: str = ""
"""备注"""
class UpdateGroup(BaseModel):
"""
更新群组信息
"""
group_id: str
"""群号"""
status: bool
"""状态"""
level: int
"""群权限"""
task_status: Dict[str, bool]
"""被动状态"""
class FriendRequestResult(BaseModel):
"""
好友/群组请求管理
"""
bot_id: Union[str, int]
"""bot_id"""
oid: str
"""排序"""
id: int
"""id"""
flag: str
"""flag"""
nickname: Optional[str]
"""昵称"""
level: Optional[int]
"""等级"""
sex: Optional[str]
"""性别"""
age: Optional[int]
"""年龄"""
from_: Optional[str]
"""来自"""
comment: Optional[str]
"""备注信息"""
class GroupRequestResult(FriendRequestResult):
"""
群聊邀请请求
"""
invite_group: Union[int, str]
"""邀请群聊"""
group_name: Optional[str]
"""群聊名称"""
class HandleRequest(BaseModel):
"""
操作请求接收数据
"""
bot_id: str
"""bot_id"""
id: int
"""id"""
request_type: Literal["private", "group"]
"""类型"""
class LeaveGroup(BaseModel):
"""
退出群聊
"""
bot_id: str
"""bot_id"""
group_id: str
"""群聊id"""
class DeleteFriend(BaseModel):
"""
删除好友
"""
bot_id: str
"""bot_id"""
user_id: str
"""用户id"""