- ai.md: Added comprehensive documentation for TUI v1.3 conversion layer with 64+ supported components, CSS styling, and JavaScript interaction capabilities
- oss/tui/: Created complete TUI module with converter.py implementing HTML/CSS/JS to terminal conversion engine, supporting 40+ component types and advanced styling
- oss/tui/plugin.py: Implemented TUI plugin with dual startup architecture accessing WebUI's /tui interface for HTML conversion and terminal rendering
- store/@{NebulaShell}/webui/tui/: Added TUI package with converter, configuration files, and index.html for terminal interface
- store/@{NebulaShell}/webui/core/server.py: Enhanced WebUI server with TUI interface endpoints (/tui/*) for providing special-marked HTML to conversion layer
- store/@{NebulaShell}/webui/main.py: Updated WebUI plugin to support TUI dual launch with automatic homepage redirection and navigation integration
- .gitignore: Updated ignore patterns for better project cleanliness
The update provides a sophisticated terminal interface that automatically converts WebUI content through a powerful transformation layer, enabling seamless dual-mode operation.
149 lines
4.9 KiB
Python
149 lines
4.9 KiB
Python
"""WebUI - Web 控制台 (容器模式) + TUI 双启动"""
|
||
from pathlib import Path
|
||
from oss.logger.logger import Log
|
||
from oss.plugin.types import Plugin, Response, register_plugin_type
|
||
from oss.config import get_config
|
||
from .core.server import WebUIServer
|
||
|
||
|
||
class WebUIPlugin(Plugin):
|
||
"""WebUI 插件 - 提供页面容器,同时启动 TUI"""
|
||
|
||
def __init__(self):
|
||
self.http_api = None
|
||
self.server = None
|
||
self.tui = None
|
||
self.config = {}
|
||
|
||
def meta(self):
|
||
from oss.plugin.types import Metadata, PluginConfig, Manifest
|
||
config = get_config()
|
||
return Manifest(
|
||
metadata=Metadata(
|
||
name="webui",
|
||
version="2.1.0",
|
||
author="NebulaShell",
|
||
description="Web 控制台容器 + TUI 双启动 - 供其他插件注册页面"
|
||
),
|
||
config=PluginConfig(
|
||
enabled=True,
|
||
args={
|
||
"port": config.get("HTTP_API_PORT", 8080),
|
||
"theme": "dark",
|
||
"title": "NebulaShell",
|
||
"tui_enabled": True # 默认启用 TUI
|
||
}
|
||
),
|
||
dependencies=["http-api"]
|
||
)
|
||
|
||
def set_http_api(self, http_api):
|
||
"""注入 http-api"""
|
||
self.http_api = http_api
|
||
|
||
def set_tui(self, tui):
|
||
"""注入 tui 引用"""
|
||
self.tui = tui
|
||
|
||
def init(self, deps: dict = None):
|
||
"""初始化 WebUI 服务器和 TUI"""
|
||
if not self.http_api:
|
||
Log.error("webui", "错误:未找到 http-api 依赖")
|
||
return
|
||
|
||
config = {}
|
||
if deps:
|
||
config = deps.get("config", {})
|
||
|
||
self.config = {
|
||
"port": config.get("port", get_config().get("HTTP_API_PORT", 8080)),
|
||
"theme": config.get("theme", "dark"),
|
||
"title": config.get("title", "NebulaShell"),
|
||
"tui_enabled": config.get("tui_enabled", True)
|
||
}
|
||
|
||
# 使用 http-api 的路由器
|
||
self.server = WebUIServer(
|
||
self.http_api.router,
|
||
self.config
|
||
)
|
||
Log.info("webui", "容器初始化完成")
|
||
|
||
# 如果启用了 TUI,通知 TUI 插件
|
||
if self.config.get("tui_enabled") and self.tui:
|
||
Log.info("webui", "TUI 已启用,将双启动")
|
||
|
||
def start(self):
|
||
"""启动服务器(注册默认路由)"""
|
||
if self.server:
|
||
# 检测仪表盘是否已安装,自动设为首页
|
||
self._setup_home_page()
|
||
|
||
self.server.start()
|
||
Log.info("webui", f"WebUI 容器已启动:http://localhost:{self.config['port']}")
|
||
|
||
# 如果启用了 TUI,在后台启动
|
||
if self.config.get("tui_enabled"):
|
||
Log.info("webui", "TUI 双启动中...")
|
||
|
||
def _setup_home_page(self):
|
||
"""设置首页:如果仪表盘已安装则跳转到仪表盘,否则显示默认首页"""
|
||
# 通过文件系统检查 dashboard 是否存在
|
||
dashboard_exists = False
|
||
store_dirs = [
|
||
Path("store/@{NebulaShell}/dashboard"),
|
||
]
|
||
for d in store_dirs:
|
||
if d.exists() and (d / "main.py").exists():
|
||
dashboard_exists = True
|
||
break
|
||
|
||
if dashboard_exists:
|
||
# 仪表盘已安装,注册首页重定向到仪表盘
|
||
self.server.router.get("/", self._handle_home_redirect)
|
||
Log.info("webui", "检测到仪表盘,首页自动跳转到 /dashboard")
|
||
else:
|
||
# 默认首页
|
||
self.server.register_page(
|
||
path="/",
|
||
content_provider=self.server._default_home_content,
|
||
nav_item={'icon': 'ri-home-4-line', 'text': '首页'}
|
||
)
|
||
|
||
def _handle_home_redirect(self, request):
|
||
"""处理首页重定向到仪表盘"""
|
||
return Response(
|
||
status=302,
|
||
headers={"Location": "/dashboard", "Content-Type": "text/html"},
|
||
body=""
|
||
)
|
||
|
||
def stop(self):
|
||
Log.error("webui", "WebUI 容器已停止")
|
||
|
||
# --- 公开 API 供其他插件调用 ---
|
||
|
||
def register_page(self, path: str, content_provider, nav_item: dict = None):
|
||
"""
|
||
其他插件调用此方法注册页面。
|
||
:param path: 路由路径 (e.g., '/dashboard')
|
||
:param content_provider: 无参函数,返回 HTML 字符串
|
||
:param nav_item: 导航项 {'icon': '📊', 'text': '仪表盘'}
|
||
"""
|
||
if self.server:
|
||
self.server.register_page(path, content_provider, nav_item)
|
||
else:
|
||
Log.warn("webui", f"警告:试图注册页面 {path},但服务器未初始化")
|
||
|
||
def add_nav_item(self, item: dict):
|
||
"""仅添加导航项(如果页面由其他方式处理)"""
|
||
if self.server:
|
||
self.server.nav_items.append(item)
|
||
|
||
|
||
register_plugin_type("WebUIPlugin", WebUIPlugin)
|
||
|
||
|
||
def New():
|
||
return WebUIPlugin()
|