d35771f97d
* fix: patch pip distlib finder for frozen electron runtime * fix: use certifi CA bundle for runtime SSL requests * fix: configure certifi CA before core imports * fix: improve mac font fallback for dashboard text * fix: harden frozen pip patch and unify TLS connector * refactor: centralize dashboard CJK font fallback stacks * perf: reuse TLS context and avoid repeated frozen pip patch * refactor: bootstrap TLS setup before core imports * fix: use async confirm dialog for provider deletions * fix: replace native confirm dialogs in dashboard - Add shared confirm helper in dashboard/src/utils/confirmDialog.ts for async dialog usage with safe fallback. - Migrate provider, chat, config, session, platform, persona, MCP, backup, and knowledge-base delete/close confirmations to use the shared helper. - Remove scattered inline confirm handling to keep behavior consistent and avoid native blocking dialog focus/caret issues in Electron. * fix: capture runtime bootstrap logs after logger init - Add bootstrap record buffer in runtime_bootstrap for early TLS patch logs before logger is ready. - Flush buffered bootstrap logs to astrbot logger at process startup in main.py. - Include concrete exception details for TLS bootstrap failures to improve diagnosis. * fix: harden runtime bootstrap and unify confirm handling - Simplify bootstrap log buffering and add a public initialize hook for non-main startup paths. - Guard aiohttp TLS patching with feature/type checks and keep graceful fallback when internals are unavailable. - Standardize dashboard confirmation flow via shared confirm helpers across composition and options API components. * refactor: simplify runtime tls bootstrap and tighten confirm typing * refactor: align ssl helper namespace and confirm usage
129 lines
4.2 KiB
Python
129 lines
4.2 KiB
Python
import argparse
|
|
import asyncio
|
|
import mimetypes
|
|
import os
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
import runtime_bootstrap
|
|
|
|
runtime_bootstrap.initialize_runtime_bootstrap()
|
|
|
|
from astrbot.core import LogBroker, LogManager, db_helper, logger # noqa: E402
|
|
from astrbot.core.config.default import VERSION # noqa: E402
|
|
from astrbot.core.initial_loader import InitialLoader # noqa: E402
|
|
from astrbot.core.utils.astrbot_path import ( # noqa: E402
|
|
get_astrbot_config_path,
|
|
get_astrbot_data_path,
|
|
get_astrbot_plugin_path,
|
|
get_astrbot_root,
|
|
get_astrbot_site_packages_path,
|
|
get_astrbot_temp_path,
|
|
)
|
|
from astrbot.core.utils.io import ( # noqa: E402
|
|
download_dashboard,
|
|
get_dashboard_version,
|
|
)
|
|
|
|
# 将父目录添加到 sys.path
|
|
sys.path.append(Path(__file__).parent.as_posix())
|
|
|
|
logo_tmpl = r"""
|
|
___ _______.___________..______ .______ ______ .___________.
|
|
/ \ / | || _ \ | _ \ / __ \ | |
|
|
/ ^ \ | (----`---| |----`| |_) | | |_) | | | | | `---| |----`
|
|
/ /_\ \ \ \ | | | / | _ < | | | | | |
|
|
/ _____ \ .----) | | | | |\ \----.| |_) | | `--' | | |
|
|
/__/ \__\ |_______/ |__| | _| `._____||______/ \______/ |__|
|
|
|
|
"""
|
|
|
|
|
|
def check_env() -> None:
|
|
if not (sys.version_info.major == 3 and sys.version_info.minor >= 10):
|
|
logger.error("请使用 Python3.10+ 运行本项目。")
|
|
exit()
|
|
|
|
astrbot_root = get_astrbot_root()
|
|
if astrbot_root not in sys.path:
|
|
sys.path.insert(0, astrbot_root)
|
|
|
|
site_packages_path = get_astrbot_site_packages_path()
|
|
if site_packages_path not in sys.path:
|
|
sys.path.insert(0, site_packages_path)
|
|
|
|
os.makedirs(get_astrbot_config_path(), exist_ok=True)
|
|
os.makedirs(get_astrbot_plugin_path(), exist_ok=True)
|
|
os.makedirs(get_astrbot_temp_path(), exist_ok=True)
|
|
os.makedirs(site_packages_path, exist_ok=True)
|
|
|
|
# 针对问题 #181 的临时解决方案
|
|
mimetypes.add_type("text/javascript", ".js")
|
|
mimetypes.add_type("text/javascript", ".mjs")
|
|
mimetypes.add_type("application/json", ".json")
|
|
|
|
|
|
async def check_dashboard_files(webui_dir: str | None = None):
|
|
"""下载管理面板文件"""
|
|
# 指定webui目录
|
|
if webui_dir:
|
|
if os.path.exists(webui_dir):
|
|
logger.info(f"使用指定的 WebUI 目录: {webui_dir}")
|
|
return webui_dir
|
|
logger.warning(f"指定的 WebUI 目录 {webui_dir} 不存在,将使用默认逻辑。")
|
|
|
|
data_dist_path = os.path.join(get_astrbot_data_path(), "dist")
|
|
if os.path.exists(data_dist_path):
|
|
v = await get_dashboard_version()
|
|
if v is not None:
|
|
# 存在文件
|
|
if v == f"v{VERSION}":
|
|
logger.info("WebUI 版本已是最新。")
|
|
else:
|
|
logger.warning(
|
|
f"检测到 WebUI 版本 ({v}) 与当前 AstrBot 版本 (v{VERSION}) 不符。",
|
|
)
|
|
return data_dist_path
|
|
|
|
logger.info(
|
|
"开始下载管理面板文件...高峰期(晚上)可能导致较慢的速度。如多次下载失败,请前往 https://github.com/AstrBotDevs/AstrBot/releases/latest 下载 dist.zip,并将其中的 dist 文件夹解压至 data 目录下。",
|
|
)
|
|
|
|
try:
|
|
await download_dashboard(version=f"v{VERSION}", latest=False)
|
|
except Exception as e:
|
|
logger.critical(f"下载管理面板文件失败: {e}。")
|
|
return None
|
|
|
|
logger.info("管理面板下载完成。")
|
|
return data_dist_path
|
|
|
|
|
|
if __name__ == "__main__":
|
|
parser = argparse.ArgumentParser(description="AstrBot")
|
|
parser.add_argument(
|
|
"--webui-dir",
|
|
type=str,
|
|
help="指定 WebUI 静态文件目录路径",
|
|
default=None,
|
|
)
|
|
args = parser.parse_args()
|
|
|
|
check_env()
|
|
|
|
# 启动日志代理
|
|
log_broker = LogBroker()
|
|
LogManager.set_queue_handler(logger, log_broker)
|
|
|
|
# 检查仪表板文件
|
|
webui_dir = asyncio.run(check_dashboard_files(args.webui_dir))
|
|
|
|
db = db_helper
|
|
|
|
# 打印 logo
|
|
logger.info(logo_tmpl)
|
|
|
|
core_lifecycle = InitialLoader(db, log_broker)
|
|
core_lifecycle.webui_dir = webui_dir
|
|
asyncio.run(core_lifecycle.start())
|