refactor: Web 服务内嵌主进程 + 文档移到 docs/ 二级目录

1. Web 服务改为 threading 模式:
   - 新增 run_web_server(port) / stop_web_server() 函数
   - TUI 通过 from web_api import run_web_server 直接调用
   - 使用 werkzeug make_server 实现线程内优雅启动/停止
2. 构建脚本精简为单二进制:
   - 移除 trulymem-web 独立打包步骤
   - 添加 werkzeug 到 hidden-imports
3. 详细启动文档移到 docs/zh/quick_start.md
4. README 精简为概述,指向 docs/ 目录
This commit is contained in:
root
2026-04-28 10:50:24 +08:00
parent aefaea7b90
commit 4770b3b990
11 changed files with 526 additions and 777 deletions

View File

@ -1,6 +1,6 @@
import asyncio
import sys
import subprocess
import threading
import signal
from pathlib import Path
from textual.app import App, ComposeResult
@ -31,7 +31,6 @@ class GraphMemoryApp(App):
self._backend_server = backend_server
self._backend_client = BackendClient(backend_server) if backend_server else None
self._api_configured = False
self._web_process: subprocess.Popen | None = None
self._web_running = False
self.login_user = None # 当前登录用户
self.login_user_info = None # 当前登录用户信息
@ -138,46 +137,14 @@ class GraphMemoryApp(App):
history.add_message(welcome)
def _start_web_server(self, port: int = 4096) -> None:
"""启动 Web 服务器子进程(支持打包和开发模式)"""
if self._web_process and self._web_process.poll() is None:
"""在当前进程通过线程启动 Web 服务(无需子进程)"""
if self._web_running:
self.notify("Web 服务已在运行", title="提示")
return
def _find_web_binary() -> str:
"""查找 Web 二进制或脚本路径"""
# 1. PyInstaller 打包环境下查找同目录的 trulymem-web 二进制
if getattr(sys, 'frozen', False):
base = Path(sys._MEIPASS).parent
for name in ['trulymem-web', 'trulymem-web.exe']:
candidate = base / name
if candidate.exists():
return str(candidate)
# 2. 开发模式:同目录下的 web_api.py
web_script = Path(__file__).parent.parent / "web_api.py"
if web_script.exists():
return str(web_script)
# 3. 打包环境回退:从 MEIPASS 读取 web_api.py 数据文件
if getattr(sys, 'frozen', False):
bundled = Path(sys._MEIPASS) / "web_api.py"
if bundled.exists():
return str(bundled)
return ""
target = _find_web_binary()
if not target:
self.notify("找不到 Web 服务文件(web_api.py)", severity="error")
return
try:
if target.endswith('.py'):
cmd = [sys.executable, target, "--port", str(port)]
else:
cmd = [target, "--port", str(port)]
self._web_process = subprocess.Popen(
cmd,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL
)
from web_api import run_web_server
run_web_server(port=port)
self._web_running = True
if self._backend_client:
self._backend_client.report_web_status(True, port)
@ -186,17 +153,13 @@ class GraphMemoryApp(App):
self.notify(f"启动 Web 服务失败: {e}", severity="error")
def _stop_web_server(self) -> None:
"""停止 Web 服务器子进程"""
if self._web_process:
"""停止 Web 服务线程"""
if self._web_running:
try:
self._web_process.terminate()
self._web_process.wait(timeout=5)
except:
try:
self._web_process.kill()
except:
pass
self._web_process = None
from web_api import stop_web_server
stop_web_server()
except Exception:
pass
self._web_running = False
if self._backend_client:
self._backend_client.report_web_status(False, 0)