05635b76b9
状态: - 9 个 sync task(stock_basic / kline_daily / kline_index / kline_5min / moneyflow / industry_sector / sector_features / share_snapshot / market_regime) - 数据源:baostock + mairui + 雪球(pysnowball) + 新浪(4 个) - 项目级约束:永远不用 akshare(已落实) - kline_5min 改用 DB 快照统一全量/增量逻辑 - 零后端 Chrome 扩展 xueqiu_sync(独立项目)
69 lines
1.9 KiB
Python
69 lines
1.9 KiB
Python
"""计划任务管理:列出 / 启用 / 禁用 / 改时间。"""
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
|
|
from fastapi import APIRouter, HTTPException
|
|
from pydantic import BaseModel
|
|
|
|
from app.core.db import ops as db_ops
|
|
from app.core.scheduler import (
|
|
get_scheduler_status,
|
|
is_trading_day,
|
|
next_trading_day,
|
|
seed_schedule_configs,
|
|
)
|
|
|
|
router = APIRouter(prefix="/api/schedule", tags=["schedule"])
|
|
|
|
|
|
class ScheduleUpdate(BaseModel):
|
|
enabled: bool | None = None
|
|
time: str | None = None
|
|
intervalSeconds: int | None = None
|
|
condition: str | None = None
|
|
|
|
|
|
@router.get("")
|
|
def list_schedules():
|
|
return {"scheduler": get_scheduler_status(), "isTradingDay": is_trading_day(),
|
|
"nextTradingDay": next_trading_day().isoformat()}
|
|
|
|
|
|
@router.post("/reseed")
|
|
def reseed():
|
|
seed_schedule_configs()
|
|
return {"status": "ok"}
|
|
|
|
|
|
@router.patch("/{key}")
|
|
def update_schedule(key: str, body: ScheduleUpdate):
|
|
target = None
|
|
for r in db_ops.fetch_all_config():
|
|
if r.get("key") == key and r.get("category") == "schedule":
|
|
target = r
|
|
break
|
|
if target is None:
|
|
raise HTTPException(404, f"未知 schedule key: {key}")
|
|
try:
|
|
obj = json.loads(target.get("value", "") or "{}")
|
|
except (json.JSONDecodeError, TypeError):
|
|
obj = {}
|
|
|
|
if body.enabled is not None:
|
|
obj["enabled"] = body.enabled
|
|
if body.time is not None:
|
|
obj["time"] = body.time
|
|
if body.intervalSeconds is not None:
|
|
obj["intervalSeconds"] = body.intervalSeconds
|
|
if body.condition is not None:
|
|
if body.condition not in ("always", "trading_day"):
|
|
raise HTTPException(400, f"condition 仅支持 always / trading_day")
|
|
obj["condition"] = body.condition
|
|
|
|
db_ops.upsert_config(
|
|
key, json.dumps(obj, ensure_ascii=False),
|
|
category="schedule", description=target.get("description", ""),
|
|
)
|
|
return {"status": "ok", "key": key, "value": obj}
|