diff --git a/main.py b/main.py index 32a4244..5d0b4ab 100644 --- a/main.py +++ b/main.py @@ -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 diff --git a/plugins/sentinel/dashboard.html b/plugins/sentinel/dashboard.html index 3c19db0..1b67bf4 100644 --- a/plugins/sentinel/dashboard.html +++ b/plugins/sentinel/dashboard.html @@ -295,12 +295,12 @@ '
'+esc(n.url||'')+'
'+ (n.notes ? '
📝 '+esc(n.notes)+'
' : '')+ '
⏱ —
'+ + '
'+ ''+ '
'+ '
CPU 0%
'+ '
MEM 0%
'+ '
NET 0 0
'+ - '
'+ '
'+ '
'+ '
'+ diff --git a/services/log_service.py b/services/log_service.py index 09bf231..c44e6c1 100644 --- a/services/log_service.py +++ b/services/log_service.py @@ -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) diff --git a/services/pyenv_manager.py b/services/pyenv_manager.py index c58d34e..24482bb 100644 --- a/services/pyenv_manager.py +++ b/services/pyenv_manager.py @@ -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) diff --git a/start.bat b/start.bat index ca0b8d4..28b3714 100644 --- a/start.bat +++ b/start.bat @@ -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 ( - echo [FAIL] 安装失败,请手动执行: .venv\Scripts\pip install -r requirements.txt + 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 diff --git a/static/web_panel/pages/dashboard.js b/static/web_panel/pages/dashboard.js index 8be95fa..61cad43 100644 --- a/static/web_panel/pages/dashboard.js +++ b/static/web_panel/pages/dashboard.js @@ -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() { diff --git a/static/web_panel/pages/logs.js b/static/web_panel/pages/logs.js index 1ac02bd..681e048 100644 --- a/static/web_panel/pages/logs.js +++ b/static/web_panel/pages/logs.js @@ -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() {