From 28670204cfa3a77915e9ea10cc0d6a99204ac54f Mon Sep 17 00:00:00 2001 From: qinglong Date: Sun, 14 Jun 2026 17:03:03 +0800 Subject: [PATCH 1/8] =?UTF-8?q?fix:=20=E6=A8=AA=E7=89=88=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=97=B6=E9=97=B4=E7=A7=BB=E8=87=B3=E5=8D=A1?= =?UTF-8?q?=E7=89=87=E5=B7=A6=E4=B8=8B=E8=A7=92col-left?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugins/sentinel/dashboard.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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
'+ - '
'+ '
'+ '
'+ '
'+ From 6d30096005f2f3af6dc33b61c27e235bc7318473 Mon Sep 17 00:00:00 2001 From: qinglong Date: Sun, 14 Jun 2026 18:28:49 +0800 Subject: [PATCH 2/8] =?UTF-8?q?feat:=20start.bat=E6=94=AF=E6=8C=81--no-ven?= =?UTF-8?q?v=E8=B7=B3=E8=BF=87=E8=99=9A=E6=8B=9F=E7=8E=AF=E5=A2=83?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=E7=B3=BB=E7=BB=9FPython?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- start.bat | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/start.bat b/start.bat index 419b969..ca0b8d4 100644 --- a/start.bat +++ b/start.bat @@ -11,9 +11,22 @@ echo. set PASS=0 set FAIL=0 -:: ── Python (venv) ── -set PYTHON=%~dp0.venv\Scripts\python.exe -if not exist "%PYTHON%" (echo [FAIL] .venv 未创建,请先运行: python -m venv .venv ^&^& .venv\Scripts\pip install -r requirements.txt & pause & exit /b 1) +:: ── 检查 --no-venv 参数 ── +set NO_VENV=0 +echo %* | findstr /i "\-\-no-venv" >nul && set NO_VENV=1 + +:: ── Python ── +if %NO_VENV% equ 1 ( + set PYTHON=python + echo [INFO] --no-venv: 使用系统 Python +) else ( + set PYTHON=%~dp0.venv\Scripts\python.exe + if not exist "%PYTHON%" ( + echo [FAIL] .venv 未创建,请先运行: python -m venv .venv ^&^& .venv\Scripts\pip install -r requirements.txt + echo 或使用: start.bat --no-venv 跳过虚拟环境 + pause & exit /b 1 + ) +) "%PYTHON%" --version >nul 2>&1 if %errorlevel% equ 0 ( echo [OK] Python From b9252bdc58f65852b83e163adb8553b32ddf78db Mon Sep 17 00:00:00 2001 From: qinglong Date: Sun, 14 Jun 2026 18:59:37 +0800 Subject: [PATCH 3/8] =?UTF-8?q?fix:=20start.bat=E6=B7=BB=E5=8A=A0PYTHONPAT?= =?UTF-8?q?H=E7=A1=AE=E4=BF=9D=E5=B5=8C=E5=85=A5=E5=BC=8FCPython=E8=83=BD?= =?UTF-8?q?=E6=89=BE=E5=88=B0=E9=A1=B9=E7=9B=AE=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- start.bat | 3 +++ 1 file changed, 3 insertions(+) diff --git a/start.bat b/start.bat index ca0b8d4..6c41f73 100644 --- a/start.bat +++ b/start.bat @@ -86,6 +86,9 @@ echo 🚀 启动 SenSu (无头模式)... echo Web 面板: http://0.0.0.0:4200/SenSu echo. +:: 确保项目根目录在 Python 搜索路径中 (嵌入式 CPython 需要) +set PYTHONPATH=%~dp0;%PYTHONPATH% + "%PYTHON%" main.py --headless pause From 2c5cd57ad477bf1168147216b4affde6452ad881 Mon Sep 17 00:00:00 2001 From: qinglong Date: Sun, 14 Jun 2026 19:02:27 +0800 Subject: [PATCH 4/8] =?UTF-8?q?fix:=20venv=E6=94=B9=E4=B8=BA=E6=87=92?= =?UTF-8?q?=E5=8A=A0=E8=BD=BD=EF=BC=8C=E5=85=BC=E5=AE=B9=E5=B5=8C=E5=85=A5?= =?UTF-8?q?=E5=BC=8FCPython=E6=97=A0venv=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.py | 7 +++++++ services/pyenv_manager.py | 5 +++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/main.py b/main.py index 32a4244..68c6d10 100644 --- a/main.py +++ b/main.py @@ -4,9 +4,16 @@ 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) + from services.project_engine import ProjectEngine from services.pyenv_manager import PyEnvManager from services.proxy_service import ProxyService 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) From 846b8a979a4ae266bed95205069f93baaf523f8c Mon Sep 17 00:00:00 2001 From: qinglong Date: Sun, 14 Jun 2026 19:03:23 +0800 Subject: [PATCH 5/8] =?UTF-8?q?fix:=20Windows=E6=8E=A7=E5=88=B6=E5=8F=B0?= =?UTF-8?q?=E5=BC=BA=E5=88=B6UTF-8=E9=81=BF=E5=85=8Demoji=E7=BC=96?= =?UTF-8?q?=E8=A7=A3=E7=A0=81=E6=8A=A5=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/main.py b/main.py index 68c6d10..5d0b4ab 100644 --- a/main.py +++ b/main.py @@ -14,6 +14,13 @@ _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 From d626a0631a4ee65c3eba148df3306589d0f5a440 Mon Sep 17 00:00:00 2001 From: qinglong Date: Sun, 14 Jun 2026 19:06:32 +0800 Subject: [PATCH 6/8] =?UTF-8?q?fix:=20RotatingFileHandler=E5=BC=BA?= =?UTF-8?q?=E5=88=B6UTF-8=E7=BC=96=E7=A0=81=E9=81=BF=E5=85=8DWindows=20GBK?= =?UTF-8?q?=E6=97=A5=E5=BF=97=E4=B9=B1=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- services/log_service.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) 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) From cd45372141bfb84d5f5659cd0e07e554dc41a36d Mon Sep 17 00:00:00 2001 From: qinglong Date: Sun, 14 Jun 2026 19:23:50 +0800 Subject: [PATCH 7/8] =?UTF-8?q?fix:=20start.bat=20pip=E5=AE=89=E8=A3=85?= =?UTF-8?q?=E6=8A=91=E5=88=B6=E8=AD=A6=E5=91=8A=E9=81=BF=E5=85=8D=E8=AF=AF?= =?UTF-8?q?=E5=88=A4=E5=A4=B1=E8=B4=A5=EF=BC=8C=E6=8A=A5=E9=94=99=E4=BF=A1?= =?UTF-8?q?=E6=81=AF=E5=8C=BA=E5=88=86venv/no-venv?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- start.bat | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/start.bat b/start.bat index 6c41f73..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 ) From 26d515e08088a88f52a9c7613101c4c31e24ba45 Mon Sep 17 00:00:00 2001 From: qinglong Date: Sun, 14 Jun 2026 19:39:36 +0800 Subject: [PATCH 8/8] =?UTF-8?q?fix:=20WebSocket=E8=BF=9E=E6=8E=A5=E6=A0=B9?= =?UTF-8?q?=E6=8D=AE=E9=A1=B5=E9=9D=A2=E5=8D=8F=E8=AE=AE=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E9=80=89=E6=8B=A9ws/wss=EF=BC=8C=E4=BF=AE=E5=A4=8DHTTPS?= =?UTF-8?q?=E4=B8=8BMixed=20Content=E6=8A=A5=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- static/web_panel/pages/dashboard.js | 3 ++- static/web_panel/pages/logs.js | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) 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() {