chore: 删除抖音养号任务类型,平台只保留 generic_steps
tasks/douyin/(task_type=douyin_nurture)整体删除,唯一任务类型是 generic_steps。 所有默认值/文档/接口示例同步改成 generic_steps: - tasks/:删 douyin 包;__init__ 只注册 generic;base.py/generic 注释改为照 generic 抄 - 默认值:core/models.py(列默认 + 旧 JSON 迁移默认)、core/task_manager.py TaskJob、 web/tasks_api.py 建任务默认、static/admin/tasks.js 新建任务默认 - core/task_manager.py:去掉 douyin 专属的"清理废弃 comment 参数"迁移块,改为**启动时告警** 仍残留已删类型的任务(只告警不改数据);run_job_now 对已删类型直接返回明确错误, 不再"报已触发、线程里静默失败" - 清理残留:douyin_running 状态位(无任何读取方)、core/__init__、core/actions/*、 core/logger.py 注释里的抖音示例 - 文档:README(特性/目录树/类型表/参数表/示例)、TASK_DEV(目录树/注册说明/模板引用)、 ARCHITECTURE(注册示例/action 注册表示例)、API.md(task_types 与任务 JSON 示例)、 AI_TASK_GEN(P1 去掉 douyin 预设)、DEVELOPMENT - 注:示例里"抖音"作为**App 名**(MCP 列应用、AI 建任务的需求举例)保留,与任务类型无关 自测(全部通过):类型列表只剩 generic_steps;建任务不传类型默认 generic_steps;传 douyin_nurture 被 400 拒;库里塞残留旧类型任务 → 启动日志告警 + 执行返回明确错误 + 不自动删用户数据;前端新建任务下拉 1 项且默认选中、界面建任务成功;监控页卡片两个按钮 + 覆盖设备正常。临时任务/数据验完已清理,任务集合复原。
This commit is contained in:
+18
-15
@@ -1,9 +1,9 @@
|
||||
"""通用任务管理框架:任务类型注册 + 设备分组 + 任务计划 + 定时调度 + 重试 + 持久化。
|
||||
|
||||
设计目标:可扩展,未来加非抖音任务只需注册新的 Task 类。
|
||||
设计目标:可扩展——新增任务类型只需在 tasks/ 下注册新的 Task 类(见 doc/TASK_DEV.md)。
|
||||
|
||||
核心概念:
|
||||
TaskType — 任务类型(如"抖音养号"),可注册,含默认参数和 worker 工厂
|
||||
TaskType — 任务类型(如"通用步骤"),可注册,含默认参数和 worker 工厂
|
||||
DeviceGroup — 设备分组,持久化到 SQLite(core.models.DeviceGroup)
|
||||
TaskJob — 任务计划(类型+目标+参数+调度+重试),持久化到 SQLite(core.models.TaskJob)
|
||||
TaskManager — 统管调度器、分组、任务、运行实例、状态
|
||||
@@ -121,7 +121,7 @@ class DeviceGroup:
|
||||
class TaskJob:
|
||||
"""一个任务计划:什么任务、跑哪些设备、什么参数、何时跑、失败重试策略。"""
|
||||
|
||||
def __init__(self, job_id=None, name="", task_type="douyin_nurture",
|
||||
def __init__(self, job_id=None, name="", task_type="generic_steps",
|
||||
target=None, params=None, schedule=None, retry=None, enabled=True):
|
||||
self.id = job_id or uuid.uuid4().hex[:8]
|
||||
self.name = name
|
||||
@@ -378,24 +378,22 @@ class TaskManager:
|
||||
for row in GroupRow.query.all():
|
||||
g = DeviceGroup(row.name, row.get_serials(), row.description or "")
|
||||
self.groups[g.name] = g
|
||||
dirty = False # 标记是否有任务参数需要写回
|
||||
stale = [] # 任务类型已不存在(历史任务类型被删除)的任务
|
||||
for row in JobRow.query.all():
|
||||
j = TaskJob(job_id=row.id, name=row.name, task_type=row.task_type,
|
||||
target=row.get_target(), params=row.get_params(),
|
||||
schedule=row.get_schedule(), retry=row.get_retry(),
|
||||
enabled=row.enabled)
|
||||
# 数据规整:移除已废弃的 action 配置(如抖音的 comment 已删除)
|
||||
if j.task_type == "douyin_nurture":
|
||||
actions = j.params.get("actions", {})
|
||||
if "comment" in actions:
|
||||
del actions["comment"]
|
||||
row.set_params(j.params)
|
||||
dirty = True
|
||||
_log.info(f"任务 {j.name}({j.id}): 已移除废弃的 comment 配置")
|
||||
# 启动时告警:库里留着已删除的任务类型(如 douyin_nurture),
|
||||
# 这类任务跑不起来也不该静默——提示人工删除或改用现有类型。
|
||||
# 只告警不改数据(不自动删用户的任务)。
|
||||
if not get_task_class(j.task_type):
|
||||
stale.append(j)
|
||||
self.jobs[j.id] = j
|
||||
if dirty:
|
||||
db.session.commit()
|
||||
_log.info("已将规整后的任务参数写回数据库")
|
||||
if stale:
|
||||
_log.warning(
|
||||
"以下任务的任务类型已不存在,无法执行,请在「任务」页删除或改用现有类型:"
|
||||
+ ";".join(f"{j.name}({j.id}, type={j.task_type})" for j in stale))
|
||||
_log.info(f"从数据库加载 {len(self.groups)} 个分组, {len(self.jobs)} 个任务")
|
||||
except Exception as e:
|
||||
_log.error(f"从数据库加载失败: {e}")
|
||||
@@ -608,6 +606,11 @@ class TaskManager:
|
||||
job = self.jobs.get(job_id)
|
||||
if not job:
|
||||
return {"ok": False, "error": "任务不存在"}
|
||||
# 任务类型已不存在(历史类型被删除)→ 明确报错,别只返回"已触发"然后线程里静默失败
|
||||
if not get_task_class(job.task_type):
|
||||
return {"ok": False, "error":
|
||||
f"任务类型 {job.task_type} 已不存在(该类型已被删除),"
|
||||
f"请删除此任务或改用现有类型"}
|
||||
# 在独立线程跑,不阻塞调用方
|
||||
t = threading.Thread(target=self._run_job, args=(job,), daemon=True)
|
||||
t.start()
|
||||
|
||||
Reference in New Issue
Block a user