Files
abot/admin/dashboard/blueprints/plugin_schedules.py
2026-05-01 12:45:40 +08:00

115 lines
3.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# -*- coding: utf-8 -*-
from datetime import datetime
from flask import Blueprint, current_app, jsonify, render_template, request
from .auth import login_required
plugin_schedules_bp = Blueprint("plugin_schedules", __name__, url_prefix="/plugin_schedules")
def _normalize_datetime_text(value):
"""统一时间文本格式为 `YYYY-MM-DD HH:MM:SS`。
兼容场景:
1. 数据库返回 datetime 对象;
2. 已经是 ISO 字符串(包含 T
3. 兜底保留原值字符串,避免因为解析失败把数据抹掉。
"""
if value is None:
return value
if isinstance(value, datetime):
return value.strftime("%Y-%m-%d %H:%M:%S")
text = str(value)
# 先处理常见 ISO 格式,直接去掉 T 并截到秒,避免前端显示异常。
if "T" in text:
return text.replace("T", " ")[:19]
return text
@plugin_schedules_bp.route("/")
@login_required
def page_plugin_schedules():
return render_template("plugin_schedules.html")
@plugin_schedules_bp.route("/api/schedules", methods=["GET"])
@login_required
def api_list_schedules():
server = current_app.dashboard_server
data = server.plugin_schedule_manager.list_schedules_with_runtime()
# 后端统一格式化时间字段,避免前端出现 Fri, 17 Apr 2026 ... 这类 RFC 时间串。
for row in data:
for key in ("next_run_at", "last_run_at", "created_at", "updated_at"):
if key in row:
row[key] = _normalize_datetime_text(row.get(key))
return jsonify({"success": True, "data": data})
@plugin_schedules_bp.route("/api/actions", methods=["GET"])
@login_required
def api_list_actions():
server = current_app.dashboard_server
data = server.plugin_schedule_manager.get_available_plugin_actions()
return jsonify({"success": True, "data": data})
@plugin_schedules_bp.route("/api/schedules/<int:schedule_id>", methods=["PUT"])
@login_required
def api_update_schedule(schedule_id: int):
server = current_app.dashboard_server
payload = request.get_json(silent=True) or {}
updates = {}
for key in (
"action_name",
"description",
"trigger_type",
"trigger_config",
"target_scope",
"target_config",
"payload",
"enabled",
):
if key in payload:
updates[key] = payload[key]
if not updates:
return jsonify({"success": False, "message": "没有可更新字段"}), 400
ok = server.plugin_schedule_manager.update_schedule(schedule_id, updates)
if not ok:
return jsonify({"success": False, "message": "更新失败"}), 500
return jsonify({"success": True, "message": "更新成功"})
@plugin_schedules_bp.route("/api/schedules/<int:schedule_id>/trigger", methods=["POST"])
@login_required
def api_trigger_schedule(schedule_id: int):
server = current_app.dashboard_server
ok, msg = server.plugin_schedule_manager.trigger_now(schedule_id)
code = 200 if ok else 400
return jsonify({"success": ok, "message": msg}), code
@plugin_schedules_bp.route("/api/schedules/<int:schedule_id>/logs", methods=["GET"])
@login_required
def api_schedule_logs(schedule_id: int):
server = current_app.dashboard_server
limit = int(request.args.get("limit", 100))
logs = server.plugin_schedule_manager.get_logs(schedule_id, limit=limit)
# 日志时间统一成固定格式,避免被 Flask JSON 序列化成 RFC 字符串。
for row in logs:
if "triggered_at" in row:
row["triggered_at"] = _normalize_datetime_text(row.get("triggered_at"))
return jsonify({"success": True, "data": logs})
@plugin_schedules_bp.route("/api/reload", methods=["POST"])
@login_required
def api_reload_schedules():
server = current_app.dashboard_server
server.plugin_schedule_manager.reload_from_db()
return jsonify({"success": True, "message": "已按数据库配置重载插件调度"})