Commit Graph
26 Commits
Author SHA1 Message Date
butubb 10d2eb8334 feat(发布计划): 新增「校验页面」步骤(expect_el)—— 每一步先确认上一步真的完成了
用户要求:"进行每一步的时候先校验上一步有没有完成,比如相册界面肯定有特征,如果没有到相册界面
就出现执行,你看看怎么处理" → 方案 A:新增只做校验、不带副作用的步骤。

· tasks/generic/task.py:新步骤 expect_el
  - 参数:特征元素选择器 / timeout(10) / what("在等什么") / on_missing
  - on_missing:skip_rest(默认,**跳过本轮剩余步骤** —— 这一条不发、换下一个号) / notify / stop
  - 为此加了 worker 级的 `_skip_rest`:_exec_steps 每步前检查,foreach_account 每轮复位
· 骨架:关键点击前各插一个 —— 相册页(//*[@text='所有照片']) → 素材已选中(desc 选择/预览)
  → 剪辑页(desc 文字/话题) → 发布页(含'添加标题'/'添加作品描述') → 发布按钮
· 通知:新增 task.page.mismatch(页面不对,本轮剩余步骤已跳过)
· 昵称选择器改**两版通吃**(实测 A06=40.7.0):xpath 联合
  `//*[@resource-id="…:id/tkv"] | //*[@resource-id="…:id/tk+"]`
  —— 40.7 是 tkv、40.6 是 tk+,联合在 40.7 上实测能读到名字;.env(dev)已改,切号入口两版同为 desc=切换账号
· 前端:编辑器面板 + 参数表单 + 发布页就地编辑字段表都认 expect_el
· 文档:TASK_DEV §3(27→28 种)+ §4.7("每步先校验上一步")、NOTIFY、research §七·补(40.7.0 对照表
  + 联合 xpath + 各页特征 + "别按坐标点页签"的坑)、.env.example
· 测试:新增 scripts/tests/test_expect_el.py(特征在/不在、三种 on_missing、选择器为空),全套 7 个用例通过
2026-10-12 11:49:48 +08:00
butubb 063818e086 fix(切号): 切完只等(默认 15 秒)不再去点「我」刷新 —— wait_after 可调
用户实测要求:"去掉切完账号下拉刷新这一步,直接改成等待 15 秒"。
原来的做法是"回读不到就再点一次「我」页签"—— 在设备上看着像去点刷新,还可能打断
抖音换号后的整体重载。

· tasks/generic/task.py:切完后按 wait_after(默认 15s,步骤参数可调)静等,等完只回读、
  **不再点任何东西**(读不到就多读几次,页面渲染有零点几秒抖动)
· 参数落到位:STEP_TYPES / 骨架 build_switch_step / 编辑器面板 / 发布页就地编辑字段表
· 测试:用例里 wait_after=0.2(不然一跑就一分多钟)
· 文档:TASK_DEV §3 的 switch_account 行 + research/U2_ELEMENT_SELECTORS §七(记下"只能等"这条实测教训)
2026-10-12 11:04:03 +08:00
butubb 1b65ffe089 feat(发布计划): 素材支持图片(图文)—— 上传视频/图片,发布流程共用一条 + 切号健壮性再修
用户实测反馈:"图片流程一样,现在也是点第一个" → 图片不做单独一套流程,只放开上传侧;
扩展名一路原样带到手机上(抖音按扩展名/MIME 判断视频还是图文,图片推成 .mp4 会变坏视频)。

· core/video_plan.py:VIDEO_EXTS + IMAGE_EXTS(jpg/jpeg/png/webp/heic) → MEDIA_EXTS;
  报错文案改"不是视频/图片文件"
· tasks/generic/publish_flow.push_video:ext 默认**从本地文件名取**(不再硬编码 .mp4);
  drop_old_copies 收到真实扩展名
· tasks/generic/task.py:删手机素材优先用推送时记下的 push_remote,其次按素材扩展名现算;
  切号:等面板开稳再点(刚出现就点会被入场动画吞掉)、点完面板还开着(点的就是当前号)
  就先关面板、一切以**回读**为准、回读窗口 12s→30s(换号会触发抖音整体重启,实测 77s 才回来);
  失败时日志附带"当时屏幕上是什么"(亮屏/前台包/屏上文字)—— "点了没反应"一眼可判
· 骨架:先 stop_app 冷启动(抖音可能停在发布页/别的视频页,那种页面上没有「我」页签,
  切号第一步就废);「校验账号」的选择器与「读名字」统一从 .env 取(漏了这一步会静默跳过
  整个发布流程 —— 用户实际遇到的"直接完成、没发布"就是这个)
· 界面:上传视频 → 上传视频/图片,accept 加 image/*,明细表"视频文件"→"素材文件",help 文案
· 文档:TASK_DEV §4.7 / API / DATA_MODEL / ARCHITECTURE / README 同步
· 测试:解析用例补图片(jpg/png/webp/大写 JPG 认,gif 不收)+ 改报错文案期望
2026-10-12 10:13:49 +08:00
butubb beda0f3779 feat(发布计划): 改按名字发(文件名 名字_日期_编号)+ 账号管理整页下线 + 自动切号一轮发完
发布计划不再绑设备、不再依赖账号台账:上传文件名 `名字_日期_编号`(标题行
`标题 || 正文_名字_日期_编号`),运行时读本机当前抖音昵称取计划;靠循环块
「一轮把本机待发的号跑完」自动切号,一直发到发完。

· 解析/配对换键:右锚定认名字(不许含下划线、不许纯数字 —— 不合法直接拒收并说清原因),
  删掉三处"手机号必须命中台账"的校验,加索引 ix_video_plan_name_date(启动时补建)
· 新步骤三个:读本机账号名字 / 切换账号(**按名字点控件**、切完回读校验、遇登录页停本设备)/
  循环本机待发的号(试过不回头、跑一轮没进展就换号、停止·超时·上限三个干净出口)
· 发布骨架改 18 步:读名字 → 校验账号(cmp_source=account_target)→ 推送(**推送前重读昵称核对**)
  → 抖音流程 → 标记结果;push_release 的 account 默认 name
· 账号管理整页下线:删 core/ledger.py(serial_of 迁到 core/device_pool.py)、6 个 /api/ledger*、
  「账号」页与 ledger.js、设备池「账号」列、设备端账号块;发布计划升为一级页签;
  device_account 表与 42 行历史数据保留、仍在备份清单内(**停用不等于删数据**)
· 人工入口「按名字找设备」:新增 core/account_probe.py(只读探测、跳过在跑任务的设备)
  + POST /api/video_plan/push_by_account,没设备登着的号逐条报出来;
  推送时把"实际是谁发的"写进 posted_serial / posted_device_name
· 通知:新增 task.account.switch_failed / task.account.need_login
· schema v12(posted_*)/ v13(device.cur_account_name / cur_name_at)
· 文档同步:TASK_DEV / API / DATA_MODEL / ARCHITECTURE / NOTIFY / DEVICE_AGENT / DEPLOY /
  DEVELOPMENT / README / .env.example(两个抖音控件选择器抓一次填 .env)
· 新增 scripts/tests/:6 套用例 + run_all.py(临时库 + 假设备,不碰真实数据、不连真机)
2026-10-12 09:02:40 +08:00
butubb 6fd9e6f8f3 chore: 容器依赖守卫补 qrcode——设备配置二维码用了它,不加的话容器重启不会安装(守卫只看固定模块列表) 2026-09-13 17:36:03 +08:00
butubb c6fda262db fix: 回归脚本两处"自己坏掉"的问题——GBK 控制台崩在汇总、写死过期设备串
在 MySQL dev 库上跑全量回归时暴露:
1. 汇总里的 ⚠/❌/✅ 在 Windows GBK 控制台抛 UnicodeEncodeError,而且崩在打印
   汇总那一步 —— 探测其实全跑完了,看起来却像脚本挂了(stdout 重设为 UTF-8)
2. `100.100.10.11:5555` 是 Tailscale 时代的地址,设备早换了:路径参数与两个关键
   POST 都拿它当目标 → 每次回归要等好几轮 30s adb connect 超时,还误报
   "关键 POST 测试步骤(wait) 失败"。改为**运行期从设备池挑一台启用设备**

结果(对 MySQL dev 库):99 项检查全通过(38 GET + 60 写探测 + 7 关键业务),
仅 3 条 Tailscale 未配置的业务提示。
2026-09-13 11:05:44 +08:00
butubb da77d8eb6b fix: 回归脚本 Windows 可用 + 加"禁止对生产库跑"安全闸;迁移脚本去掉 GBK 控制台会崩的符号
- scripts/regression_test.py:
  * signal.alarm 加 hasattr 守卫(Windows 上直接 AttributeError 退出,
    backlog A4)→ 本机终于能跑"一条命令扫全接口 500"
  * 新增安全闸:.env 声明 prod、或目标库 app_meta.deployment_env=prod 时
    **拒绝运行**(exit 3)。本脚本会发真实写请求(设备池增删/剪贴板注入/
    亮灭屏),跑在生产配置上就是拿正式数据做实验
- scripts/migrate_sqlite_to_mysql.py: stdout 重设为 UTF-8 并去掉 ✔/✘ 符号。
  实测在 GBK 控制台里打印 ✔ 会抛 UnicodeEncodeError,而且崩在"写库标签"之前,
  看起来像迁移失败(数据其实已搬完)
- doc/backlog/TODO.md: A4 移入已完成;gitignore 条目更新(mcp_audit.log 已补,
  uiauto.pid 仍缺);登记 MySQL 迁移与回归安全闸

实测(对 192.168.2.27 的 auto_control_dev):数据迁移 12 张表逐表 SHA-256 一致;
应用直连 MySQL 全部接口 200,设备名/指纹唯一索引语义与 SQLite 一致(空值可重复、
非空重复被拦、大小写敏感 A08≠a08);备份导出→预览→应用往返正常。
2026-09-13 10:48:36 +08:00
butubb 429aaf6283 feat: SQLite → MySQL 数据迁移脚本 + 建库建账号 SQL(P3)
- scripts/migrate_sqlite_to_mysql.py(新增):源库完整性校验 → 列宽审计(SQLite 不强制
  长度,MySQL 严格模式下超长直接报错,先拦下)→ 建目标 schema(复用平台的 create_all
  + _sync_columns + 唯一索引)→ 逐表单事务搬行 → 逐表行数 + 全行 SHA-256 比对 →
  写库环境标签与 schema_version。支持 --dry-run / --mode verify / --schema-only;
  --env prod 必须 --allow-prod(+ 交互确认或 --yes);目标库已登记别的环境时拒绝
- scripts/sql/init_mysql_5.7.sql(新增):建 auto_control / auto_control_dev 两个库
  (utf8mb4 + utf8mb4_bin)+ 专用账号与授权
- doc/DEPLOY.md §7.2:补 SQLite→MySQL 迁移流程与注意事项

比对口径踩坑记录:验证哈希必须两边都从**驱动层原生读**。走 ORM/Core 的 typed
select 会把 Boolean 读成 True/False,而源库 SQLite 原始读出来是 1/0 —— 三张带
布尔列的表(user/device/task_job)会全部误报"不一致"。现在统一用原生 SQL 回读 +
值规范化(bool→int、整数值浮点→int、bytes→str)。

自测(目标用 SQLite 代跑,MySQL 专属部分待 P4 真库验证):12 张表逐表 SHA-256 一致、
重复迁移幂等、verify 模式通过。
2026-09-13 10:37:15 +08:00
butubb f22263ab45 feat: 数据库连接层改造——库目标由 .env 装配 + 环境防呆(迁 MySQL 第一步)
为把数据库从单文件 SQLite 迁到 MySQL 5.7 铺路。本期不改后端:
DB_HOST 为空时仍走 SQLite,本地开发无感。

- config.py: 新增 DEPLOY_ENV(默认 dev)与 DB_HOST/PORT/USER/PASSWORD/NAME/
  CHARSET/COLLATION、DATABASE_URL、两个逃生阀(DB_ALLOW_ENV_MISMATCH /
  DB_ALLOW_SQLITE_FALLBACK)
- core/db_config.py(新增): URI 组装;按方言分叉的引擎参数(utf8mb4、
  pool_pre_ping、pool_recycle=1800、READ COMMITTED、STRICT_TRANS_TABLES);
  连接探活;app_meta 方言中立读写(MySQL 里 key 是保留字,需反引号)
- 防混库三层: ①库名与环境绑定(dev→auto_control_dev / prod→auto_control)
  ②库标签 app_meta.deployment_env 与 .env 声明比对 ③启动横幅打印当前库
  (生产用 WARNING 级)。不符直接拒绝启动并说明两边分别是什么
- web_server.py: 硬编码 sqlite URI → db_config;配置错在装配期就 exit 2;
  init_db 之后跑库标签校验 + 横幅
- core/models.py: PRAGMA 监听器加 sqlite 类型守卫——它挂在 Engine 基类上,
  MySQL 连接执行 PRAGMA 会直接导致建连失败
- requirements.txt 加 PyMySQL;scripts/start.sh 依赖守卫加 pymysql,
  并在 exec 前打印 DEPLOY_ENV/DB_NAME/DB_HOST
- .env.example 新增「数据库」段;DEVELOPMENT.md §4.1/4.2、DEPLOY.md §2.2 同步

验证: 用 DATABASE_URL 指向 users.db 的一致快照副本跑通主要只读接口
(health/devices/jobs/pool/groups/discovery/summary 全 200,app_meta 读写正常);
DEPLOY_ENV=prod 且无 DB_HOST 时退出码 2;开 DB_ALLOW_SQLITE_FALLBACK 后可回退。
2026-09-13 10:27:14 +08:00
butubb 24d57d3b96 docs: doc/ 全量重整——按现状重写并建立文档索引;项目统一更名 auto_control
背景:文档长期落后于代码(Tab 数、任务类型、接口示例等多处与现状不符),
且信息分散重复。这次按当前代码状态逐篇重写,并建立统一的文档体系。

新增
- doc/README.md:文档总索引(文档地图 / 推荐阅读路径 / **文档维护约定**)
- doc/DATA_MODEL.md:数据模型(7 张模型表 + 5 张非模型表、迁移机制、app_meta 键、
  数据目录、备份覆盖清单与双向自检)
- doc/AI_CONSOLE.md:AI 控制台机制(会话与 SSE、经验库/动作库蒸馏与召回、巡检、
  Markdown 渲染、推理链、token 统计、故障排查)

重写(按现状,去掉过时与重复)
- README.md:7 个 Tab、18 种步骤、设备生命周期、调度/窗口语义、常见问题;修掉
  「6 个 Tab / 分组为顶级 Tab」等过时内容与损坏的目录树
- doc/ARCHITECTURE.md:补启动装配顺序(import 期副作用、A~G 七阶段)、线程与锁清单、
  设备状态机、调度全链路、前端结构与实时通道、设计决策、**已知缺陷与踩坑清单**、扩展点
- doc/API.md:按蓝图重建「接口总索引」(107 条路由含鉴权)+ 分域详细说明 +
  非 JSON 响应汇总 + 错误分支速查
- doc/TASK_DEV.md:18 种步骤全表(参数/默认值/语义)、容器与公共参数、
  选择器与 XPath 序号语义、抓取器建议规则、新增任务类型骨架
- doc/DEPLOY.md:容器入口 start.sh 三件事、发布流程与检查清单、备份覆盖红线、
  按现象分类的故障排查
- doc/DEVELOPMENT.md:流程/红线/本地开发/**测试与写测试的约定**/配置速查/文档同步
- doc/MCP.md:19 个工具的参数级清单、坐标空间、写门控三连、安全与审计
- doc/MCP_DESIGN.md、doc/AI_TASK_GEN.md:标注设计 vs 实现现状,补交叉链接
- doc/backlog/TODO.md:新增「已知缺陷」小节(含复现与影响)+ 已完成留档
- .env.example:按代码实际读取的键重写(补 USB/DISCOVERY/MCP/AGENT,删死配置)

其它
- 项目名统一 auto_control:README/文档/scripts/pack.py 产物名;代码内的
  doc 章节引用(templates/admin/monitor.html)同步更新
- 校验:16 篇文档 156 条相对链接全部可解析;文档中的关键数字与代码核对一致
  (19 个 MCP 工具 / 18 种步骤 / 12 张备份表 / 1 种任务类型)
2026-09-10 22:19:18 +08:00
butubb 4865ed1d31 fix: 依赖守卫补 fastmcp——漏检导致 fastmcp 缺失时跳过安装,MCP server 持续启动失败 2026-09-04 16:30:55 +08:00
butubb 4863b9fbbe fix: cv2 空壳修复改 pip --force-reinstall——手动 wheel 解压兜底在部分环境修不好(解压后 import cv2 仍无 __version__,OCR 持续不可用);force-reinstall 已在 220 实测恢复 cv2 4.14.0 2026-09-04 16:25:24 +08:00
butubb 7fd77fa33c fix: 容器启动幂等——依赖安装段移入 start.sh 并加「就绪即跳过」守卫(flask/u2/rapidocr/cv2 全部可用则秒级启动);配合 220 compose 去掉 command 里的 pip 段,消除每次容器重启重装 opencv 5.0(73MB) 并破坏 cv2 的崩溃循环帮凶 2026-09-04 16:23:17 +08:00
butubb bdaaea3e6c fix: MCP server 固化进 start.sh 容器启动链——之前手动 docker exec 拉起、容器重启即丢(AI 控制台 agent 依赖 8033);MCP_ENABLED=0 可关,账号密码可经环境变量覆盖 2026-09-04 14:38:01 +08:00
butubb 4efe17c1c9 feat: 设备自动发现——定时扫描局域网+Tailscale 网段开放 adb 5555 的设备进入待连接池,用户确认后才加入正式设备池(不自动连接);socket 并发探测+adb 短超时验证(state=device 过滤 unauthorized),配置存 app_meta 可前端调整;配套:adb_connect_light 验证短超时、DISABLE_SCHEDULER 回归开关 2026-08-30 10:57:07 +08:00
butubb f78955f119 fix: start.sh 增加 cv2 空壳兜底——pip 24.0 解压 abi3 wheel 偶发丢根文件(cv2.abi3.so/__init__.py 缺失致 OCR 全挂),检测后 pip download + zipfile 手动解压(幂等) 2026-08-20 08:51:02 +08:00
butubb 0fab6f4de8 fix: opencv-python-headless 锁 4.x——清华源 5.0.0.93 wheel 打包异常(site-packages 无 cv2 模块),OCR 仍不可用 2026-08-19 16:23:36 +08:00
butubb 5de87465bc fix: start.sh 修复顺序——rapidocr 依赖声明 opencv-python 会被 pip 强制装回 GUI 版,uninstall 必须在 pip install 之后最后执行 2026-08-19 16:17:28 +08:00
butubb b33ff17c26 feat: 容器启动脚本 scripts/start.sh——幂等卸载 opencv-python(GUI 版缺 X11 库致 OCR 崩)并装 headless,compose 指向本脚本后环境修复全走 git 2026-08-19 16:14:15 +08:00
butubb d0cb531c20 fix: 未登录访问 500——login_view 蓝图化后未更新为 auth.login,flask_login 重定向 url_for('login') BuildError 2026-08-19 16:02:47 +08:00
butubb e0c3373dd1 feat: 全量路由回归测试脚本 scripts/regression_test.py(GET 全量 + 写操作空 body 探测抓 import 遗漏 + 关键业务 POST,500=缺陷 502/503=业务提示)+ fix: clear_all_worker_errors 缺导入(回归脚本首跑即抓到) 2026-08-19 15:24:11 +08:00
butubb 060157ea1a refactor: 前端JS拆分为8个模块(base/list/monitor/editor/tasks/tools/apps/admin,按依赖顺序加载)+ 删除废弃文件(start_web.bat/main.py/fix_web.bat/cleanup.py,web已全覆盖)+ 文档同步 + 修复/api/summary缺导入 2026-08-11 14:53:04 +08:00
butubb afeb0902a1 feat: 进程守护 supervise.sh,崩溃自动重启;DEPLOY 补 docker healthcheck
- scripts/supervise.sh:web_server 崩溃自动重启,带 2s 退避和 300s 窗口内重启上限(10次)防死循环
- doc/DEPLOY.md 补充通用守护用法 + python-app 容器 healthcheck 配置
2026-08-08 21:23:36 +08:00
butubb 468e86f0a9 feat: 新增通用步骤任务+元素抓取,完善全部项目文档
- 新增 generic_steps 通用步骤任务(可视化步骤编辑器编排流程,支持 open_app/click/swipe/input_text/wait/loop/group)

- 新增 core/uiauto_helper.py 封装 uiautodev 元素抓取客户端

- web_server 新增元素抓取/截图/设备列表等 API

- monitor.html 新增步骤编辑器、元素抓取模态框、独立关闭逻辑

- 新增 README.md 项目总览(快速上手/架构/配置/FAQ)

- 新增 doc/ARCHITECTURE.md 架构详解、doc/DEPLOY.md 部署指南、doc/API.md 接口文档

- 修复 doc/TASK_DEV.md:移除已删除的 comment 引用,补充 generic 包,更新注册示例

- .gitignore 忽略 .claude/ 工具产物
2026-08-08 10:40:06 +08:00
butubb 0fe2a2fc5f feat: 新增设备画面截图、列表复选框/排序/批量停止,修复端口绑定失败 2026-08-07 15:08:36 +08:00
butubb bce48fc137 chore: 初始化仓库(排除 adb 二进制文件以解决推送超时) 2026-08-07 13:55:48 +08:00