Merge branch 'dev'
This commit is contained in:
@@ -4,9 +4,23 @@
|
||||
import logging
|
||||
import asyncio
|
||||
import sys
|
||||
import os as _os
|
||||
import signal
|
||||
import time
|
||||
import argparse
|
||||
|
||||
# 确保项目根目录在 sys.path 中 (嵌入式 CPython / PyPy 需要)
|
||||
_sys_path_root = _os.path.dirname(_os.path.abspath(__file__))
|
||||
if _sys_path_root not in sys.path:
|
||||
sys.path.insert(0, _sys_path_root)
|
||||
|
||||
# Windows 控制台强制 UTF-8 (避免 GBK 编解码 emoji 报错)
|
||||
try:
|
||||
sys.stdout.reconfigure(encoding='utf-8', errors='replace')
|
||||
sys.stderr.reconfigure(encoding='utf-8', errors='replace')
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
from services.project_engine import ProjectEngine
|
||||
from services.pyenv_manager import PyEnvManager
|
||||
from services.proxy_service import ProxyService
|
||||
|
||||
@@ -295,12 +295,12 @@
|
||||
'<div class="node-url">'+esc(n.url||'')+'</div>'+
|
||||
(n.notes ? '<div class="node-notes">📝 '+esc(n.notes)+'</div>' : '')+
|
||||
'<div class="node-latency" style="font-size:.7rem;color:var(--text-dim);margin-top:4px">⏱ —</div>'+
|
||||
'<div class="col-info" style="font-size:.65rem;color:var(--text-dim);margin-top:2px"></div>'+
|
||||
'</div>'+
|
||||
'<div class="col-right-stack">'+
|
||||
'<div class="mtr" id="mtr-'+id+'-cpu"><div class="mtr-data"><span class="rlabel">CPU</span> <span class="rval cpu-val">0%</span></div><canvas id="'+id+'-cpu" height="60"></canvas></div>'+
|
||||
'<div class="mtr" id="mtr-'+id+'-mem"><div class="mtr-data"><span class="rlabel">MEM</span> <span class="rval mem-val">0%</span> <span class="mem-row-detail" style="font-size:.65rem;color:var(--text-dim)"></span></div><canvas id="'+id+'-mem" height="60"></canvas></div>'+
|
||||
'<div class="mtr" id="mtr-'+id+'-net"><div class="mtr-data"><span class="rlabel">NET</span> <span class="rval net-down" style="font-size:.85rem">0</span> <span class="rval net-up" style="font-size:.85rem">0</span></div><canvas id="'+id+'-net" height="60"></canvas></div>'+
|
||||
'<div class="col-info" style="text-align:right;font-size:.7rem;color:var(--text-dim);margin-top:4px"></div>'+
|
||||
'</div>'+
|
||||
'<div class="col-disk"><div class="disk-list"></div></div>'+
|
||||
'<div class="col-extra">'+
|
||||
|
||||
@@ -89,7 +89,8 @@ class LogService:
|
||||
runtime_handler = logging.handlers.RotatingFileHandler(
|
||||
self.log_dir / "runtime" / runtime_log_file,
|
||||
maxBytes=self._parse_size(self.config['logging'].get('max_file_size', '10MB')),
|
||||
backupCount=self.config['logging'].get('max_log_files', 3)
|
||||
backupCount=self.config['logging'].get('max_log_files', 3),
|
||||
encoding='utf-8'
|
||||
)
|
||||
runtime_handler.setLevel(getattr(logging, self.config['logging']['level'], logging.INFO))
|
||||
runtime_handler.setFormatter(file_formatter)
|
||||
@@ -101,7 +102,8 @@ class LogService:
|
||||
debug_handler = logging.handlers.RotatingFileHandler(
|
||||
self.log_dir / "debug" / debug_log_file,
|
||||
maxBytes=self._parse_size(self.config['logging'].get('max_file_size', '10MB')),
|
||||
backupCount=self.config['logging'].get('max_log_files', 3)
|
||||
backupCount=self.config['logging'].get('max_log_files', 3),
|
||||
encoding='utf-8'
|
||||
)
|
||||
debug_handler.setLevel(logging.DEBUG)
|
||||
debug_handler.setFormatter(file_formatter)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env python3
|
||||
"""SenSu PyEnvManager — Python 版本管理 + venv + 依赖安装"""
|
||||
import os, sys, subprocess, logging, venv, shutil
|
||||
import os, sys, subprocess, logging, shutil
|
||||
from pathlib import Path
|
||||
from typing import Optional, List
|
||||
|
||||
@@ -76,7 +76,8 @@ class PyEnvManager:
|
||||
logger.info(f"创建 venv: {venv_path} (Python {python_version or 'default'})")
|
||||
|
||||
try:
|
||||
venv.create(str(venv_path), with_pip=True, clear=True)
|
||||
import venv as _venv
|
||||
_venv.create(str(venv_path), with_pip=True, clear=True)
|
||||
# Install/upgrade pip
|
||||
pip = str(venv_path / "bin" / "pip")
|
||||
subprocess.run([pip, "install", "--upgrade", "pip"], capture_output=True, timeout=60)
|
||||
|
||||
@@ -71,9 +71,13 @@ if exist "config\framework\base_config.yaml" (
|
||||
echo.
|
||||
if %FAIL% gtr 0 (
|
||||
echo [WARN] %FAIL% 项缺失,自动安装...
|
||||
"%PYTHON%" -m pip install -r requirements.txt
|
||||
"%PYTHON%" -m pip install -r requirements.txt --no-warn-script-location --root-user-action=ignore 2>&1
|
||||
if %errorlevel% neq 0 (
|
||||
if %NO_VENV% equ 1 (
|
||||
echo [FAIL] 安装失败,请手动执行: pip install -r requirements.txt
|
||||
) else (
|
||||
echo [FAIL] 安装失败,请手动执行: .venv\Scripts\pip install -r requirements.txt
|
||||
)
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
@@ -86,6 +90,9 @@ echo 🚀 启动 SenSu (无头模式)...
|
||||
echo Web 面板: http://0.0.0.0:4200/SenSu
|
||||
echo.
|
||||
|
||||
:: 确保项目根目录在 Python 搜索路径中 (嵌入式 CPython 需要)
|
||||
set PYTHONPATH=%~dp0;%PYTHONPATH%
|
||||
|
||||
"%PYTHON%" main.py --headless
|
||||
|
||||
pause
|
||||
|
||||
@@ -50,7 +50,8 @@ window.DashboardModule = {
|
||||
}
|
||||
|
||||
var base = window.location.pathname.split("/").slice(0, 2).join("/");
|
||||
var ws = new WebSocket("ws://" + location.host + base + "/api/system/ws");
|
||||
var proto = location.protocol === 'https:' ? 'wss://' : 'ws://';
|
||||
var ws = new WebSocket(proto + location.host + base + "/api/system/ws");
|
||||
self.ws = ws;
|
||||
|
||||
ws.onopen = function() {
|
||||
|
||||
@@ -25,7 +25,8 @@ window.LogsModule = {
|
||||
}
|
||||
|
||||
var base = window.location.pathname.split("/").slice(0, 2).join("/");
|
||||
var ws = new WebSocket("ws://" + location.host + base + "/api/logs/ws");
|
||||
var proto = location.protocol === 'https:' ? 'wss://' : 'ws://';
|
||||
var ws = new WebSocket(proto + location.host + base + "/api/logs/ws");
|
||||
self.ws = ws;
|
||||
|
||||
ws.onopen = function() {
|
||||
|
||||
Reference in New Issue
Block a user