feat: dashboard partially
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
from addons.dashboard.server import AstrBotDashBoard, DashBoardData
|
||||
from pydantic import BaseModel
|
||||
from typing import Union, Optional,
|
||||
|
||||
class DashBoardConfig(BaseModel):
|
||||
type: str["group", "item"]
|
||||
name: str
|
||||
description: str
|
||||
body: Union[dict, list]
|
||||
value: Optional[Union[list, dict, str, int, bool]]
|
||||
val_type: Optional[str["list", "dict", "str", "int", "bool"]]
|
||||
body: Optional['DashBoardConfig']
|
||||
|
||||
|
||||
class DashBoardHelper():
|
||||
def __init__(self, dashboard_data: DashBoardData):
|
||||
self.dashboard_data = dashboard_data
|
||||
self.dashboard = AstrBotDashBoard(self.dashboard_data)
|
||||
|
||||
@self.dashboard.register("post_configs")
|
||||
def on_post_configs(configs: dict):
|
||||
self.dashboard_data.configs = configs
|
||||
|
||||
return True
|
||||
|
||||
# 将 config.yaml、 中的配置解析到 dashboard_data.configs 中
|
||||
def parse_config(self, config: dict):
|
||||
pass
|
||||
|
||||
def run(self):
|
||||
self.dashboard.run()
|
||||
@@ -0,0 +1,68 @@
|
||||
from flask import Flask
|
||||
import datetime
|
||||
from pydantic import BaseModel
|
||||
from util import general_utils as gu
|
||||
|
||||
class DashBoardData(BaseModel):
|
||||
stats: dict
|
||||
configs: dict
|
||||
logs: dict
|
||||
|
||||
class Response(BaseModel):
|
||||
status: str
|
||||
message: str
|
||||
data: dict
|
||||
|
||||
class AstrBotDashBoard():
|
||||
def __init__(self, dashboard_data: DashBoardData):
|
||||
self.dashboard_data = dashboard_data
|
||||
self.dashboard_be = Flask(__name__)
|
||||
self.funcs = {}
|
||||
|
||||
@self.dashboard_be.get("/stats")
|
||||
def get_stats():
|
||||
return Response(
|
||||
status="success",
|
||||
message="",
|
||||
data=self.dashboard_data.stats
|
||||
).dict()
|
||||
|
||||
@self.dashboard_be.get("/configs")
|
||||
def get_configs():
|
||||
return Response(
|
||||
status="success",
|
||||
message="",
|
||||
data=self.dashboard_data.configs
|
||||
).__dict__
|
||||
|
||||
@self.dashboard_be.post("/configs")
|
||||
def post_configs():
|
||||
if self.funcs["post_configs"](self.dashboard_data.configs):
|
||||
return Response(
|
||||
status="success",
|
||||
message="",
|
||||
data=self.dashboard_data.configs
|
||||
).__dict__
|
||||
return Response(
|
||||
status="error",
|
||||
message="",
|
||||
data=self.dashboard_data.configs
|
||||
).__dict__
|
||||
|
||||
@self.dashboard_be.get("/logs")
|
||||
def get_logs():
|
||||
return Response(
|
||||
status="success",
|
||||
message="",
|
||||
data=self.dashboard_data.logs
|
||||
).__dict__
|
||||
|
||||
def register(self, name: str):
|
||||
def decorator(func):
|
||||
self.funcs[name] = func
|
||||
return func
|
||||
return decorator
|
||||
|
||||
def run(self):
|
||||
gu.log(f"\n\n==================\n您可以访问:\n\thttp://localhost:6185/\n来登录可视化面板。\n==================\n\n", tag="可视化面板")
|
||||
self.dashboard_be.run(host="0.0.0.0", port=6185)
|
||||
+15
-33
@@ -39,7 +39,7 @@ import io
|
||||
import traceback
|
||||
from . global_object import GlobalObject
|
||||
from typing import Union, Callable
|
||||
|
||||
from addons.dashboard.helper import DashBoardHelper
|
||||
|
||||
# 缓存的会话
|
||||
session_dict = {}
|
||||
@@ -48,9 +48,6 @@ count = {}
|
||||
# 统计信息
|
||||
stat_file = ''
|
||||
|
||||
# 日志记录
|
||||
# logf = open('log.log', 'a+', encoding='utf-8')
|
||||
|
||||
# 用户发言频率
|
||||
user_frequency = {}
|
||||
# 时间默认值
|
||||
@@ -64,11 +61,8 @@ announcement = ""
|
||||
# 机器人私聊模式
|
||||
direct_message_mode = True
|
||||
|
||||
# 适配pyinstaller
|
||||
abs_path = os.path.dirname(os.path.realpath(sys.argv[0])) + '/'
|
||||
|
||||
# 版本
|
||||
version = '3.0.4'
|
||||
version = '3.1.0'
|
||||
|
||||
# 语言模型
|
||||
REV_CHATGPT = 'rev_chatgpt'
|
||||
@@ -160,27 +154,6 @@ def _runner(func: Callable, args: tuple):
|
||||
loop.run_until_complete(func(*args))
|
||||
loop.close()
|
||||
|
||||
|
||||
# [Deprecated] 写入统计信息
|
||||
def toggle_count(at: bool, message):
|
||||
global stat_file
|
||||
try:
|
||||
if str(message.guild_id) not in count:
|
||||
count[str(message.guild_id)] = {
|
||||
'count': 1,
|
||||
'direct_count': 1,
|
||||
}
|
||||
else:
|
||||
count[str(message.guild_id)]['count'] += 1
|
||||
if not at:
|
||||
count[str(message.guild_id)]['direct_count'] += 1
|
||||
stat_file = open(abs_path+"configs/stat", 'w', encoding='utf-8')
|
||||
stat_file.write(json.dumps(count))
|
||||
stat_file.flush()
|
||||
stat_file.close()
|
||||
except BaseException:
|
||||
pass
|
||||
|
||||
# 上传统计信息并检查更新
|
||||
def upload():
|
||||
global version, gocq_bot, qqchannel_bot
|
||||
@@ -228,6 +201,9 @@ def initBot(cfg, prov):
|
||||
global baidu_judge, chosen_provider
|
||||
global frequency_count, frequency_time, announcement, direct_message_mode, version
|
||||
global keywords, _global_object
|
||||
|
||||
# 迁移旧配置
|
||||
gu.try_migrate_config()
|
||||
|
||||
_event_loop = asyncio.new_event_loop()
|
||||
asyncio.set_event_loop(_event_loop)
|
||||
@@ -410,7 +386,7 @@ def initBot(cfg, prov):
|
||||
# thread.join()
|
||||
|
||||
if thread_inst == None:
|
||||
raise Exception("[System-Error] 没有启用/成功启用任何机器人,程序退出")
|
||||
gu.log("没有启用/成功启用任何机器人平台", gu.LEVEL_CRITICAL)
|
||||
|
||||
default_personality_str = cc.get("default_personality_str", "")
|
||||
if default_personality_str == "":
|
||||
@@ -420,12 +396,18 @@ def initBot(cfg, prov):
|
||||
"name": "default",
|
||||
"prompt": default_personality_str,
|
||||
}
|
||||
|
||||
# 初始化dashboard
|
||||
dashboard_helper = DashBoardHelper(_global_object.dashboard_data)
|
||||
dashboard_helper.parse_config(cfg)
|
||||
dashboard_thread = threading.Thread(target=dashboard_helper.run, daemon=True)
|
||||
dashboard_thread.start()
|
||||
|
||||
gu.log("🎉 项目启动完成。")
|
||||
|
||||
# asyncio.get_event_loop().run_until_complete(cli())
|
||||
|
||||
asyncio.get_event_loop().run_until_complete(cli())
|
||||
|
||||
thread_inst.join()
|
||||
dashboard_thread.join()
|
||||
|
||||
async def cli():
|
||||
time.sleep(1)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
from model.platform.qqchan import QQChan, NakuruGuildMember, NakuruGuildMessage
|
||||
from model.platform.qq import QQ
|
||||
from model.provider.provider import Provider
|
||||
from addons.dashboard.server import DashBoardData
|
||||
from nakuru import (
|
||||
CQHTTP,
|
||||
GroupMessage,
|
||||
@@ -27,6 +28,7 @@ class GlobalObject:
|
||||
platform_qq: QQ
|
||||
platform_qqchan: QQChan
|
||||
default_personality: dict
|
||||
dashboard_data: DashBoardData
|
||||
|
||||
def __init__(self):
|
||||
self.nick = None # gocq 的昵称
|
||||
@@ -41,6 +43,7 @@ class GlobalObject:
|
||||
self.platform_qq = None
|
||||
self.platform_qqchan = None
|
||||
self.default_personality = None
|
||||
self.dashboard_data = None
|
||||
|
||||
class AstrMessageEvent():
|
||||
message_str: str # 纯消息字符串
|
||||
|
||||
@@ -3,12 +3,17 @@ from pip._internal import main as pipmain
|
||||
import warnings
|
||||
import traceback
|
||||
import threading
|
||||
import logging
|
||||
|
||||
warnings.filterwarnings("ignore")
|
||||
abs_path = os.path.dirname(os.path.realpath(sys.argv[0])) + '/'
|
||||
|
||||
def main():
|
||||
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
||||
datefmt='%H:%M:%S',
|
||||
)
|
||||
# config.yaml 配置文件加载和环境确认
|
||||
try:
|
||||
import cores.qqbot.core as qqBot
|
||||
@@ -112,7 +117,6 @@ def get_platform():
|
||||
print("other")
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
args = sys.argv
|
||||
|
||||
if '-cn' in args:
|
||||
@@ -123,7 +127,7 @@ if __name__ == "__main__":
|
||||
if '-replit' in args:
|
||||
print("[System] 启动Replit Web保活服务...")
|
||||
try:
|
||||
from webapp_replit import keep_alive
|
||||
from util.webapp_replit import keep_alive
|
||||
keep_alive()
|
||||
except BaseException as e:
|
||||
print(e)
|
||||
|
||||
+21
-12
@@ -5,6 +5,7 @@ from PIL import Image, ImageDraw, ImageFont
|
||||
import os
|
||||
import re
|
||||
import requests
|
||||
from util.cmd_config import CmdConfig
|
||||
|
||||
PLATFORM_GOCQ = 'gocq'
|
||||
PLATFORM_QQCHAN = 'qqchan'
|
||||
@@ -79,7 +80,14 @@ def log(
|
||||
if len(msg) > max_len:
|
||||
msg = msg[:max_len] + "..."
|
||||
now = datetime.datetime.now().strftime("%m-%d %H:%M:%S")
|
||||
pre = f"[{now}] [{level}] [{tag}]: {msg}"
|
||||
|
||||
pres = []
|
||||
for line in msg.split("\n"):
|
||||
if line == "\n":
|
||||
pres.append("")
|
||||
else:
|
||||
pres.append(f"[{now}] [{level}] [{tag}]: {line}")
|
||||
|
||||
if level == "INFO":
|
||||
if fg is None:
|
||||
fg = FG_COLORS["green"]
|
||||
@@ -100,8 +108,11 @@ def log(
|
||||
fg = FG_COLORS["purple"]
|
||||
if bg is None:
|
||||
bg = BG_COLORS["default"]
|
||||
|
||||
print(f"\033[{fg};{bg}m{pre}\033[0m")
|
||||
|
||||
ret = ""
|
||||
for line in pres:
|
||||
ret += f"\033[{fg};{bg}m{line}\033[0m\n"
|
||||
print(ret)
|
||||
|
||||
|
||||
def port_checker(port: int, host: str = "localhost"):
|
||||
@@ -501,14 +512,12 @@ def create_markdown_image(text: str):
|
||||
return p
|
||||
except Exception as e:
|
||||
raise e
|
||||
|
||||
def test_markdown():
|
||||
# 示例使用
|
||||
markdown_text = """# Help Center
|
||||
! [] (https://soulter.top/helpme.jpg)
|
||||
"""
|
||||
image = render_markdown(markdown_text)
|
||||
image.show()
|
||||
|
||||
# test_markdown()
|
||||
|
||||
# 迁移配置文件到 cmd_config.json
|
||||
def try_migrate_config(old_config: dict):
|
||||
cc = CmdConfig()
|
||||
if cc.get("qqbot", None) is None:
|
||||
# 未迁移过
|
||||
for k in old_config:
|
||||
cc.put(k, old_config[k])
|
||||
Reference in New Issue
Block a user