🎨 webui优化

This commit is contained in:
HibiKier
2024-08-13 22:37:44 +08:00
parent b37e55648b
commit 2d0cee80c2
4 changed files with 123 additions and 119 deletions
@@ -1,19 +1,13 @@
import re
from typing import Literal
import nonebot
from fastapi import APIRouter
from nonebot.adapters.onebot.v11 import ActionFailed
from starlette.websockets import WebSocket, WebSocketDisconnect, WebSocketState
from tortoise.functions import Count
from zhenxun.configs.config import NICKNAME
from zhenxun.models.ban_console import BanConsole
from zhenxun.models.chat_history import ChatHistory
from zhenxun.models.fg_request import FgRequest
from zhenxun.models.friend_user import FriendUser
from zhenxun.models.group_console import GroupConsole
from zhenxun.models.group_member_info import GroupInfoUser
from zhenxun.models.plugin_info import PluginInfo
from zhenxun.models.statistics import Statistics
from zhenxun.models.task_info import TaskInfo
@@ -25,7 +19,6 @@ from zhenxun.utils.platform import PlatformUtils
from ....base_model import Result
from ....config import AVA_URL, GROUP_AVA_URL
from ....utils import authentication
from ...logs.log_manager import LOG_STORAGE
from .model import (
ClearRequest,
DeleteFriend,
@@ -36,8 +29,6 @@ from .model import (
GroupResult,
HandleRequest,
LeaveGroup,
Message,
MessageItem,
Plugin,
ReqResult,
SendMessage,
@@ -46,19 +37,8 @@ from .model import (
UserDetail,
)
ws_router = APIRouter()
router = APIRouter(prefix="/manage")
SUB_PATTERN = r"\x1b(\[.*?[@-~]|\].*?(\x07|\x1b\\))"
GROUP_PATTERN = r".*?Message (-?\d*) from (\d*)@\[群:(\d*)] '(.*)'"
PRIVATE_PATTERN = r".*?Message (-?\d*) from (\d*) '(.*)'"
AT_PATTERN = r"\[CQ:at,qq=(.*)\]"
IMAGE_PATTERN = r"\[image:file=.*,url=(.*);.*?\]"
@router.get(
"/get_group_list", dependencies=[authentication()], description="获取群组列表"
@@ -72,7 +52,6 @@ async def _(bot_id: str) -> Result:
return Result.warning_("指定Bot未连接...")
group_list_result = []
try:
group_info = {}
group_list = await bots[bot_id].get_group_list()
for g in group_list:
gid = g["group_id"]
@@ -459,93 +438,3 @@ async def _(param: SendMessage) -> Result:
return Result.ok("发送成功!")
return Result.warning_("指定Bot未连接...")
return Result.warning_("无Bot连接...")
MSG_LIST = []
ID2NAME = {}
async def message_handle(
sub_log: str, type: Literal["private", "group"]
) -> Message | None:
global MSG_LIST, ID2NAME
pattern = PRIVATE_PATTERN if type == "private" else GROUP_PATTERN
msg_id = None
uid = None
gid = None
msg = None
img_list = re.findall(IMAGE_PATTERN, sub_log)
if r := re.search(pattern, sub_log):
if type == "private":
msg_id = r.group(1)
uid = r.group(2)
msg = r.group(3)
if uid not in ID2NAME:
if user := await FriendUser.get_or_none(user_id=uid):
ID2NAME[uid] = user.user_name or user.nickname
else:
msg_id = r.group(1)
uid = r.group(2)
gid = r.group(3)
msg = r.group(4)
if gid not in ID2NAME:
if user := await GroupInfoUser.get_or_none(user_id=uid, group_id=gid):
ID2NAME[uid] = user.user_name or user.nickname
if at_list := re.findall(AT_PATTERN, msg):
user_list = await GroupInfoUser.filter(
user_id__in=at_list, group_id=gid
).all()
id2name = {u.user_id: (u.user_name or u.nickname) for u in user_list}
for qq in at_list:
msg = re.sub(rf"\[CQ:at,qq={qq}\]", f"@{id2name[qq] or ''}", msg)
if msg_id in MSG_LIST:
return
MSG_LIST.append(msg_id)
messages = []
if msg and uid:
rep = re.split(r"\[CQ:image.*\]", msg)
if img_list:
for i in range(len(rep)):
messages.append(MessageItem(type="text", msg=rep[i]))
if i < len(img_list):
messages.append(MessageItem(type="img", msg=img_list[i]))
else:
messages = [MessageItem(type="text", msg=x) for x in rep]
return Message(
object_id=uid if type == "private" else gid, # type: ignore
user_id=uid,
group_id=gid,
message=messages,
name=ID2NAME.get(uid) or "",
ava_url=AVA_URL.format(uid),
)
return None
@ws_router.websocket("/chat")
async def _(websocket: WebSocket):
await websocket.accept()
async def log_listener(log: str):
global MSG_LIST, ID2NAME
sub_log = re.sub(SUB_PATTERN, "", log)
if "message.private.friend" in log:
if message := await message_handle(sub_log, "private"):
await websocket.send_json(message.dict())
else:
if r := re.search(GROUP_PATTERN, sub_log):
if message := await message_handle(sub_log, "group"):
await websocket.send_json(message.dict())
if len(MSG_LIST) > 30:
MSG_LIST = MSG_LIST[-1:]
LOG_STORAGE.listeners.add(log_listener)
try:
while websocket.client_state == WebSocketState.CONNECTED:
recv = await websocket.receive()
except WebSocketDisconnect:
pass
finally:
LOG_STORAGE.listeners.remove(log_listener)
return
@@ -0,0 +1,111 @@
import re
from typing import Literal
import nonebot
from fastapi import APIRouter
from nonebot import on_message
from nonebot.adapters.onebot.v11 import MessageEvent
from nonebot_plugin_alconna import At, Emoji, Hyper, Image, Text, UniMessage, UniMsg
from nonebot_plugin_session import EventSession
from starlette.websockets import WebSocket, WebSocketDisconnect, WebSocketState
from zhenxun.models.friend_user import FriendUser
from zhenxun.models.group_console import GroupConsole
from zhenxun.models.group_member_info import GroupInfoUser
from zhenxun.utils.depends import UserName
from ....config import AVA_URL, GROUP_AVA_URL
from .model import Message, MessageItem
driver = nonebot.get_driver()
ws_conn: WebSocket | None = None
ID2NAME = {}
ID_LIST = []
ws_router = APIRouter()
matcher = on_message(block=False, priority=1)
@driver.on_shutdown
async def _():
if ws_conn:
await ws_conn.close()
@ws_router.websocket("/chat")
async def _(websocket: WebSocket):
global ws_conn
await websocket.accept()
if not ws_conn:
ws_conn = websocket
try:
while websocket.client_state == WebSocketState.CONNECTED:
recv = await websocket.receive()
except WebSocketDisconnect:
ws_conn = None
async def message_handle(
message: UniMsg,
group_id: str | None,
):
messages = []
for m in message:
if isinstance(m, (Text, str)):
messages.append(MessageItem(type="text", msg=str(m)))
elif isinstance(m, Image):
if m.url:
messages.append(MessageItem(type="img", msg=m.url))
elif isinstance(m, At):
if group_id:
if m.target == "0":
uname = "全体成员"
else:
uname = m.target
if group_id not in ID2NAME:
ID2NAME[group_id] = {}
if m.target in ID2NAME[group_id]:
uname = ID2NAME[group_id][m.target]
else:
if group_user := await GroupInfoUser.get_or_none(
user_id=m.target, group_id=group_id
):
uname = group_user.user_name
if m.target not in ID2NAME[group_id]:
ID2NAME[group_id][m.target] = uname
messages.append(MessageItem(type="at", msg=f"@{uname}"))
# elif isinstance(m, Emoji):
# messages.append(MessageItem(type="text", msg=f"[emoji]"))
elif isinstance(m, Hyper):
messages.append(MessageItem(type="text", msg=f"[分享消息]"))
return messages
@matcher.handle()
async def _(
message: UniMsg, event: MessageEvent, session: EventSession, uname: str = UserName()
):
global ws_conn, ID2NAME, ID_LIST
uid = session.id1
gid = session.id3 or session.id2
if ws_conn and uid:
msg_id = event.message_id
if msg_id in ID_LIST:
return
ID_LIST.append(msg_id)
if len(ID_LIST) > 50:
ID_LIST = ID_LIST[40:]
messages = await message_handle(message, gid)
data = Message(
object_id=gid or uid,
user_id=uid,
group_id=gid,
message=messages,
name=uname,
ava_url=AVA_URL.format(uid),
)
await ws_conn.send_json(data.dict())