initial: blog-app snapshot

This commit is contained in:
omo
2026-08-17 17:11:27 +08:00
commit 65cb9d5ead
125 changed files with 14720 additions and 0 deletions

96
services/watchdog.py Normal file
View File

@@ -0,0 +1,96 @@
"""Watchdog service: report loading, process checks, trigger bookkeeping.
Mostly pure (no Flask imports). `trigger_watchdog_run` uses subprocess only;
the caller (route) is responsible for flash/redirect.
"""
import logging
import os
import sqlite3
import subprocess
import time
import config
from repositories import watchdog_repo
logger = logging.getLogger(__name__)
# 简单防重: 模块级变量记录上次触发时间戳, cooldown 秒内重复 POST 返回失败
_last_trigger_ts = 0.0
def parse_days(raw, default=7):
"""Clamp days query param to 1-90; non-numeric falls back to default."""
try:
value = int(raw)
except (TypeError, ValueError):
return default
return max(1, min(90, value))
def load_watchdog_reports(watchdog_conn, days=7):
"""Return recent watchdog reports; [] when db/table missing or unreadable."""
if not os.path.exists(config.WATCHDOG_DB):
return []
try:
return watchdog_repo.list_reports(watchdog_conn, days=days)
except sqlite3.Error:
logger.exception("failed to read watchdog db")
return []
def is_watchdog_running():
"""True if a python process running daily_watchdog.py already exists."""
try:
out = subprocess.run(
["pgrep", "-f", "daily_watchdog.py"],
capture_output=True, text=True, timeout=5,
).stdout
except Exception:
logger.exception("watchdog pgrep failed")
return False
for pid in out.split():
try:
with open(f"/proc/{pid}/cmdline", "rb") as f:
argv0 = f.read().split(b"\x00")[0].decode(errors="replace")
except OSError:
continue
if os.path.basename(argv0).startswith("python"):
return True
return False
def trigger_watchdog_run(cooldown=None):
"""Attempt to launch scripts/daily_watchdog.py in the background.
Returns (ok, status, message):
- (True, "started", msg) launched successfully
- (False, "cooldown", msg) hit the anti-repeat cooldown
- (False, "running", msg) an instance is already running
- (False, "error", msg) subprocess launch failed
"""
global _last_trigger_ts
cooldown = config.WATCHDOG_RUN_COOLDOWN if cooldown is None else cooldown
now = time.time()
if now - _last_trigger_ts < cooldown:
return False, "cooldown", "操作太频繁, 请稍后再试"
_last_trigger_ts = now
if is_watchdog_running():
return False, "running", "daily_watchdog.py 已在运行中, 本次触发被忽略"
try:
os.makedirs(os.path.dirname(config.WATCHDOG_RUN_LOG), exist_ok=True)
log_f = open(config.WATCHDOG_RUN_LOG, "a", encoding="utf-8")
env = dict(os.environ)
env["HOME"] = "/home/yi"
subprocess.Popen(
["/usr/bin/python3", config.WATCHDOG_SCRIPT],
stdout=log_f, stderr=subprocess.STDOUT,
cwd=config.BASE_DIR, env=env, start_new_session=True,
)
return True, "started", "已触发, 约 1-2 分钟后刷新页面查看新报告"
except Exception as exc:
logger.exception("failed to launch daily_watchdog.py")
return False, "error", f"触发失败: {exc}"