Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f78955f119 | ||
|
|
27530ff5ac |
@@ -587,14 +587,10 @@ class TaskManager:
|
||||
return _next_run_time(job.schedule)
|
||||
|
||||
def run_job_now(self, job_id):
|
||||
"""立即执行任务(手动触发)。运行窗口外拒绝启动。"""
|
||||
"""立即执行任务(手动触发)。运行窗口只约束定时触发,手动执行不受限制。"""
|
||||
job = self.jobs.get(job_id)
|
||||
if not job:
|
||||
return {"ok": False, "error": "任务不存在"}
|
||||
if not _in_run_window(job.schedule):
|
||||
win = job.schedule.get("window") or {}
|
||||
return {"ok": False,
|
||||
"error": f"当前不在运行窗口内({win.get('start', '')}-{win.get('end', '')}),任务未启动"}
|
||||
# 在独立线程跑,不阻塞调用方
|
||||
t = threading.Thread(target=self._run_job, args=(job,), daemon=True)
|
||||
t.start()
|
||||
|
||||
@@ -16,4 +16,34 @@ fi
|
||||
pip uninstall -y -q opencv-python 2>/dev/null || true
|
||||
pip install -q -i https://pypi.tuna.tsinghua.edu.cn/simple "opencv-python-headless>=4.8,<5" # 5.x wheel 无 cv2 模块,锁定 4.x
|
||||
|
||||
# pip 24.0 解压 abi3 wheel 偶发丢根文件(4.14.0.94 实测 site-packages/cv2 只剩子目录,
|
||||
# cv2.abi3.so / __init__.py 缺失 → import cv2 成空壳,OCR 全挂)→ 空壳检测 + wheel 手动解压兜底(幂等)
|
||||
python3 - <<'PY'
|
||||
import glob, os, shutil, site, subprocess, sys, zipfile
|
||||
|
||||
def cv2_ok():
|
||||
try:
|
||||
import cv2
|
||||
return hasattr(cv2, "__version__") and cv2.__file__ is not None
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
if cv2_ok():
|
||||
sys.exit(0)
|
||||
print("cv2 空壳,wheel 手动解压修复...")
|
||||
r = subprocess.run(["pip", "download", "--no-deps", "-q",
|
||||
"-i", "https://pypi.tuna.tsinghua.edu.cn/simple",
|
||||
"-d", "/tmp/ocv", "opencv-python-headless>=4.8,<5"], capture_output=True)
|
||||
if r.returncode != 0:
|
||||
sys.exit(1)
|
||||
w = sorted(glob.glob("/tmp/ocv/opencv_python_headless*.whl"))[-1]
|
||||
with zipfile.ZipFile(w) as z:
|
||||
z.extractall("/tmp/ocv")
|
||||
dst = os.path.join(site.getsitepackages()[0], "cv2")
|
||||
shutil.rmtree(dst, ignore_errors=True)
|
||||
shutil.copytree("/tmp/ocv/cv2", dst)
|
||||
import cv2
|
||||
print(f"cv2 {cv2.__version__} 手动解压修复完成")
|
||||
PY
|
||||
|
||||
exec python -u web_server.py
|
||||
|
||||
@@ -1082,7 +1082,7 @@ async function saveTask(jobId){
|
||||
cron:buildCronFromFreq(),
|
||||
stop_cron:(parseInt(st[1])||0)+' '+(parseInt(st[0])||0)+' * * *'};
|
||||
}
|
||||
// 运行窗口:窗口外(定时触发 + 手动执行)不启动
|
||||
// 运行窗口:只约束定时触发(窗口外定时不启动),手动执行不受限制
|
||||
if(document.getElementById('f-window_enable').checked){
|
||||
schedule.window={
|
||||
start:document.getElementById('f-window_start').value||'09:00',
|
||||
|
||||
@@ -141,7 +141,7 @@ function openTaskModal(jobId){
|
||||
'<div class="form-group"><label>允许运行·开始</label><input type="time" class="form-control" id="f-window_start" value="'+esc(winStart)+'"></div>'+
|
||||
'<div class="form-group"><label>允许运行·结束</label><input type="time" class="form-control" id="f-window_end" value="'+esc(winEnd)+'"></div>'+
|
||||
'</div>'+
|
||||
'<div class="help" id="f-window_help" style="display:'+(win?'block':'none')+'">窗口外任务不会启动(定时触发和手动执行都受约束)。跨午夜示例:21:00-09:00 = 晚 9 点到次日早 9 点允许运行</div>'+
|
||||
'<div class="help" id="f-window_help" style="display:'+(win?'block':'none')+'">窗口只约束定时触发:窗口外定时不会启动,手动执行不受限制。跨午夜示例:21:00-09:00 = 晚 9 点到次日早 9 点允许运行</div>'+
|
||||
'<div class="form-row">'+
|
||||
'<div class="form-group"><label>重试次数</label><input type="number" class="form-control" id="f-retry_attempts" value="'+j.retry.max_attempts+'" min="1" max="10"></div>'+
|
||||
'<div class="form-group"><label>重试间隔(秒)</label><input type="number" class="form-control" id="f-retry_delay" value="'+j.retry.delay+'" min="10" max="3600"></div>'+
|
||||
|
||||
Reference in New Issue
Block a user