Spaces:
Running
Running
Upload 2 files
Browse files- router_messages.py +4 -0
- 临时_版本同步测试.py +109 -0
router_messages.py
CHANGED
|
@@ -59,6 +59,7 @@ class AdminScriptRequest(BaseModel):
|
|
| 59 |
# 🔒 P0安全修复:脚本白名单(仅允许执行指定的脚本)
|
| 60 |
# 警告:添加新脚本前请确保其安全性
|
| 61 |
ALLOWED_SCRIPTS = {
|
|
|
|
| 62 |
"密码迁移.py", # 用户密码哈希化迁移
|
| 63 |
"测试脚本.py", # 接口测试工具
|
| 64 |
"迁移_余额合并.py", # 一次性余额合并迁移(执行后可移除)
|
|
@@ -103,6 +104,9 @@ async def run_admin_script(request: Request, req: AdminScriptRequest, current_us
|
|
| 103 |
}
|
| 104 |
|
| 105 |
try:
|
|
|
|
|
|
|
|
|
|
| 106 |
# 清理敏感环境变量,防止泄露到子进程
|
| 107 |
sensitive_prefixes = ('GITHUB', 'JWT', 'HF_', 'DATABASE', 'ALIPAY', 'PASSWORD',
|
| 108 |
'MAKE_', 'TWILIO_', 'ALIYUN_', 'TENCENT_', 'NCA_')
|
|
|
|
| 59 |
# 🔒 P0安全修复:脚本白名单(仅允许执行指定的脚本)
|
| 60 |
# 警告:添加新脚本前请确保其安全性
|
| 61 |
ALLOWED_SCRIPTS = {
|
| 62 |
+
"临时_版本同步测试.py",
|
| 63 |
"密码迁移.py", # 用户密码哈希化迁移
|
| 64 |
"测试脚本.py", # 接口测试工具
|
| 65 |
"迁移_余额合并.py", # 一次性余额合并迁移(执行后可移除)
|
|
|
|
| 104 |
}
|
| 105 |
|
| 106 |
try:
|
| 107 |
+
if script_name == "临时_版本同步测试.py":
|
| 108 |
+
from 临时_版本同步测试 import run
|
| 109 |
+
return run()
|
| 110 |
# 清理敏感环境变量,防止泄露到子进程
|
| 111 |
sensitive_prefixes = ('GITHUB', 'JWT', 'HF_', 'DATABASE', 'ALIPAY', 'PASSWORD',
|
| 112 |
'MAKE_', 'TWILIO_', 'ALIYUN_', 'TENCENT_', 'NCA_')
|
临时_版本同步测试.py
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""管理员临时诊断:当前进程只启动一轮,后续调用查询原结果。"""
|
| 2 |
+
import asyncio
|
| 3 |
+
import logging
|
| 4 |
+
|
| 5 |
+
MAX_ITEMS = 5
|
| 6 |
+
logger = logging.getLogger("ComfyUI-Ranking.VersionSyncTest")
|
| 7 |
+
_result = dict(state="ready", selected=0, checked=0, updated=0,
|
| 8 |
+
attempted=0, cached=0, already_cached=0, failed=0)
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
def _summary():
|
| 12 |
+
return "VERSION_SYNC_TEST | " + " | ".join(f"{key}={value}" for key, value in _result.items())
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
def run():
|
| 16 |
+
from resource_work import start_resource_background
|
| 17 |
+
from script_execution import ScriptExecutionBusy
|
| 18 |
+
|
| 19 |
+
if _result["state"] == "ready":
|
| 20 |
+
_result["state"] = "running"
|
| 21 |
+
try:
|
| 22 |
+
accepted = start_resource_background(_execute)
|
| 23 |
+
except BaseException:
|
| 24 |
+
_result["state"] = "ready"
|
| 25 |
+
raise
|
| 26 |
+
if not accepted:
|
| 27 |
+
_result["state"] = "ready"
|
| 28 |
+
raise ScriptExecutionBusy()
|
| 29 |
+
failed = _result["state"] in ("failed", "cancelled")
|
| 30 |
+
return {"status": "error" if failed else "success",
|
| 31 |
+
"return_code": 1 if failed else 0, "output": _summary()}
|
| 32 |
+
|
| 33 |
+
|
| 34 |
+
async def _execute():
|
| 35 |
+
stage = "source_read"
|
| 36 |
+
try:
|
| 37 |
+
import 数据库连接 as db
|
| 38 |
+
from owned_thread import run_owned_thread
|
| 39 |
+
from github_source import repository_parts, select_github_token
|
| 40 |
+
from github_archive import cached_archive
|
| 41 |
+
from github_versions import refresh_resource_version
|
| 42 |
+
from 云端_定时版本检测引擎 import precache_github_zip
|
| 43 |
+
|
| 44 |
+
logger.info("VERSION_SYNC_TEST_STARTED | limit=%s", MAX_ITEMS)
|
| 45 |
+
items = await run_owned_thread(db.load_data, "items.json", default_data=[], strict=True, skip_cache=True)
|
| 46 |
+
versions = await run_owned_thread(db.load_data, "versions.json", default_data={}, strict=True, skip_cache=True)
|
| 47 |
+
if not isinstance(items, list) or not isinstance(versions, dict):
|
| 48 |
+
raise ValueError("invalid version source")
|
| 49 |
+
pending, available = [], []
|
| 50 |
+
for item in items:
|
| 51 |
+
if not isinstance(item, dict) or item.get("type") not in ("tool", "skill"):
|
| 52 |
+
continue
|
| 53 |
+
if not isinstance(item.get("id"), str):
|
| 54 |
+
continue
|
| 55 |
+
try:
|
| 56 |
+
repository_parts(item.get("link"))
|
| 57 |
+
token = select_github_token(item)
|
| 58 |
+
archive = cached_archive(item, token, versions.get(item["id"]), repo_id=db.DATASET_REPO_ID)
|
| 59 |
+
except ValueError:
|
| 60 |
+
continue
|
| 61 |
+
if len(available) < MAX_ITEMS:
|
| 62 |
+
available.append(item)
|
| 63 |
+
if archive is None:
|
| 64 |
+
pending.append(item)
|
| 65 |
+
if len(pending) == MAX_ITEMS:
|
| 66 |
+
break
|
| 67 |
+
selected = pending or available
|
| 68 |
+
_result["selected"] = len(selected)
|
| 69 |
+
for index, item in enumerate(selected, 1):
|
| 70 |
+
stage = "version_check"
|
| 71 |
+
try:
|
| 72 |
+
refreshed = await refresh_resource_version(db, item["id"])
|
| 73 |
+
if not refreshed:
|
| 74 |
+
_result["failed"] += 1
|
| 75 |
+
logger.warning("VERSION_SYNC_TEST_ITEM | item=%s | stage=version_check | result=unconfirmed", index)
|
| 76 |
+
continue
|
| 77 |
+
_result["checked"] += 1
|
| 78 |
+
_result["updated"] += bool(refreshed["changed"])
|
| 79 |
+
stage = "cache_read"
|
| 80 |
+
current_versions = await run_owned_thread(db.load_data, "versions.json", default_data={}, strict=True, skip_cache=True)
|
| 81 |
+
current, token = refreshed["item"], refreshed["token"]
|
| 82 |
+
if cached_archive(current, token, current_versions.get(item["id"]), repo_id=db.DATASET_REPO_ID):
|
| 83 |
+
_result["already_cached"] += 1
|
| 84 |
+
continue
|
| 85 |
+
stage = "precache"
|
| 86 |
+
_result["attempted"] += 1
|
| 87 |
+
if await precache_github_zip(current["link"], token, item["id"], refreshed["commit"]):
|
| 88 |
+
_result["cached"] += 1
|
| 89 |
+
logger.info("VERSION_SYNC_TEST_ITEM | item=%s | stage=precache | result=success", index)
|
| 90 |
+
else:
|
| 91 |
+
_result["failed"] += 1
|
| 92 |
+
logger.warning("VERSION_SYNC_TEST_ITEM | item=%s | stage=precache | result=failed", index)
|
| 93 |
+
except Exception as error:
|
| 94 |
+
_result["failed"] += 1
|
| 95 |
+
logger.warning("VERSION_SYNC_TEST_ITEM | item=%s | stage=%s | error_type=%s", index, stage, type(error).__name__)
|
| 96 |
+
_result["state"] = "failed" if _result["failed"] else "completed"
|
| 97 |
+
except asyncio.CancelledError:
|
| 98 |
+
_result["state"] = "cancelled"
|
| 99 |
+
raise
|
| 100 |
+
except Exception as error:
|
| 101 |
+
_result["state"] = "failed"
|
| 102 |
+
_result["failed"] += 1
|
| 103 |
+
logger.warning("VERSION_SYNC_TEST_FAILED | stage=%s | error_type=%s", stage, type(error).__name__)
|
| 104 |
+
finally:
|
| 105 |
+
logger.info(_summary())
|
| 106 |
+
|
| 107 |
+
|
| 108 |
+
if __name__ == "__main__":
|
| 109 |
+
raise SystemExit("Use the authenticated administrator script endpoint.")
|