refactor: web_server 模块化拆分(web/ 蓝图包 auth/monitor/tasks/admin/tools/devices/apks/tailscale + context/common,web_server 1796→193 行仅留装配与启动)+ 大屏优化(网格 5s 轮询、弹窗独占缩略图、流支持 q/fps)+ 三修复(MIUI 屏幕状态检测改 dumpsys power、补 ADB_PATH 导入修复一键亮屏、renderGrid 增量渲染不重载缩略图)
This commit is contained in:
+30
-30
@@ -10,8 +10,8 @@
|
||||
|
||||
| 层 | 路径 | 职责 |
|
||||
|----|------|------|
|
||||
| 配置层 | `config.py` | 项目根配置:STF 地址、adb 路径、web 端口等基础设施。**不放任务参数** |
|
||||
| 核心层 | `core/` | 框架运行时:日志、STF 客户端、adb 操作、Worker 基类、任务管理器、u2 辅助、Action 基类 |
|
||||
| 配置层 | `config.py` | 项目根配置:adb 路径、web 端口、USB 远程 adb server 等基础设施。**不放任务参数** |
|
||||
| 核心层 | `core/` | 框架运行时:日志、设备池、adb 操作、Worker 基类、任务管理器、u2 辅助、Action 基类 |
|
||||
| 任务层 | `tasks/` | 每个 App 一个子包,自包含 `task.py` + `actions/`,互不依赖 |
|
||||
| 前端层 | `templates/admin/` | 单页应用(纯 HTML+CSS+JS,无框架) |
|
||||
| 数据层 | `data/` | SQLite 持久化 |
|
||||
@@ -39,7 +39,7 @@
|
||||
│ JSON API │ ┌─────────────────┐
|
||||
▼ ┌──────────────┐ │ 设备 adb │
|
||||
┌──────────────┐ │ 看门狗监控 │ │ (IP:5555 直连 │
|
||||
│ web_server │ └──────────────┘ │ / USB 远程) │
|
||||
│ web/ 蓝图包 │ └──────────────┘ │ / USB 远程) │
|
||||
│ (Flask API) │ └─────────────────┘
|
||||
└──────────────┘
|
||||
│
|
||||
@@ -137,7 +137,7 @@ run() 主循环(不要重写):
|
||||
|
||||
**并发控制**:同一 serial 同时只允许一个 worker,避免冲突。
|
||||
|
||||
**状态缓存**:`get_status()` 带 5 秒缓存,STF 请求慢时不阻塞前端。
|
||||
**状态缓存**:`get_status()` 带 5 秒缓存,避免每次 /api/status 都查库/adb 阻塞前端。
|
||||
|
||||
### 3.4 前台 App 扫描器(`_ForegroundScanner`)
|
||||
|
||||
@@ -145,12 +145,11 @@ run() 主循环(不要重写):
|
||||
|
||||
| 设备状态 | 处理方式 | 是否打扰 |
|
||||
|---------|---------|---------|
|
||||
| worker 运行中 | 复用已有 ADB 连接查询 | 否 |
|
||||
| 自己占用无 worker | STF remoteConnect 隧道查询 | 否 |
|
||||
| 完全空闲 | 返回"空闲"(不 adb connect,避免 STF 误判离线) | 否 |
|
||||
| 他人占用 | 标记"(他人占用)" | 否 |
|
||||
| worker 运行中(IP:5555) | 复用已有 ADB 连接查询 | 否 |
|
||||
| worker 运行中(USB) | 经 220 远程 adb server 查询 | 否 |
|
||||
| 完全空闲 | 返回"空闲"(不主动 connect) | 否 |
|
||||
|
||||
> **为什么不扫描空闲设备的前台 App**:STF provider 内部通过 IP:5555 维持 adb 连接。外部 adb connect/disconnect 会让 adb server 断开该 transport,连带 STF provider 的连接断开,STF 误判设备 offline 并触发重连。
|
||||
> **为什么不扫描空闲设备的前台 App**:IP:5555 的 adb transport 是共享的(历史与 STF provider 共用),外部 connect/disconnect 会扰动共享连接,遵守既有红线。
|
||||
|
||||
### 3.5 ADB 操作(`core/adb_helper.py`)
|
||||
|
||||
@@ -158,8 +157,8 @@ run() 主循环(不要重写):
|
||||
|
||||
**铁律:绝不 kill-server**:
|
||||
- `adb kill-server` 会断开所有设备的 adb transport
|
||||
- 导致 STF provider 对全部设备误判离线并触发重连
|
||||
- 影响所有运行中的任务
|
||||
- 全部设备连接被重建,影响所有运行中的任务
|
||||
- 同理绝不 disconnect IP:5555(共享 transport 红线,见 DEVELOPMENT.md)
|
||||
|
||||
| 函数 | 说明 |
|
||||
|------|------|
|
||||
@@ -191,9 +190,9 @@ SQLAlchemy 模型,存于 `data/users.db`:
|
||||
### 权限模型
|
||||
|
||||
- `User.perms` 存业务权限位 JSON 数组(`tasks`/`devices`/`apks`/`logs`),`is_admin=true` 拥有全部权限(`has_perm` 短路)
|
||||
- 后端统一用 `@perm_required(PERM_X)` / `@admin_required` 装饰器拦截(web_server.py),无权限返回 403;
|
||||
查看类 GET 接口只要求登录;用户管理、维护接口(STF 重启 `/api/stf/restart`、adb 终端 `/api/adb/cmd`)强制 `admin_required`
|
||||
- adb 终端安全红线:拒绝 `kill-server` / `disconnect`(STF provider 共享 adb transport,断开会误判全设备离线)
|
||||
- 后端统一用 `@perm_required(PERM_X)` / `@admin_required` 装饰器拦截(web/auth.py),无权限返回 403;
|
||||
查看类 GET 接口只要求登录;用户管理、adb 终端(`/api/adb/cmd`)强制 `admin_required`
|
||||
- adb 终端安全红线:拒绝 `kill-server` / `disconnect`(共享 adb transport)
|
||||
- 前端 `loadMe()` 拉取 `/api/me`,用 `data-perm` 属性隐藏无权限的 tab/按钮,行内按钮用 `_can(perm)` 判断
|
||||
- 安全兜底:**前端隐藏只是 UX,权限强制在后端**;新增路由时按"写操作必须带权限装饰器"的约定
|
||||
|
||||
@@ -201,10 +200,10 @@ SQLAlchemy 模型,存于 `data/users.db`:
|
||||
|
||||
APK 上传/解析/批量安装。
|
||||
|
||||
**设备连接策略(直连,绕过 STF)**:
|
||||
**设备连接策略(直连)**:
|
||||
- 直接 `adb connect serial`(serial 是 IP:5555)
|
||||
- 不经过 STF occupy/release,避免 STF release 触发 agent 清理卸载 app
|
||||
- 安装后不主动 disconnect(STF provider 共享该 adb transport)
|
||||
- 不经过占用/释放(单实例互斥由调度器内存锁保证)
|
||||
- 安装后不主动 disconnect(共享 adb transport 红线)
|
||||
|
||||
**安装流程**:
|
||||
1. 上传 APK → 保存到 `data/apks/` → pyaxmlparser 解析包名/版本 → 入库
|
||||
@@ -232,23 +231,24 @@ APK 上传/解析/批量安装。
|
||||
- 引擎懒加载单例 + 并发加锁(识别约 0.2-0.5s/次)
|
||||
- 返回坐标约定:像素、原点左上
|
||||
|
||||
### 3.10 STF 设备管理(`core/stf_device_mgmt.py`)
|
||||
### 3.10 Web 层蓝图包(`web/`)
|
||||
|
||||
工具页"STF 设备管理":维护 220 上 OpenSTF 设备池。
|
||||
路由按功能域拆分(模块化开发底线,便于定位问题):
|
||||
|
||||
背景:220 的 adb 跑在 Docker 容器(`STF_ADB_CONTAINER`,默认 `adb`)里,设备池由
|
||||
`/mnt/data/openstf/connect_devices.sh`(`STF_SCRIPT_PATH`)的 `DEVICES` 数组维护,cron 每 5 分钟补连。
|
||||
|
||||
| 函数 | 说明 |
|
||||
| 模块 | 职责 |
|
||||
|------|------|
|
||||
| `status()` | 脚本配置 IP + 220 adb 实际连接状态 |
|
||||
| `add_device(ip)` | 用 220 的 python3 精确改脚本 DEVICES 块 + `docker exec adb adb connect` |
|
||||
| `remove_device(ip)` | 脚本删条目 + `adb disconnect` |
|
||||
| `auth.py` | 登录/登出/CSRF/权限装饰器/页面路由(/、/wall) |
|
||||
| `monitor.py` | 状态/运行控制/设备操作/远程看屏(流+缩略图+触控) |
|
||||
| `tasks_api.py` | 任务计划/分组/自定义动作/元素抓取/步骤测试 |
|
||||
| `admin_api.py` | 用户管理/日志 |
|
||||
| `tools_api.py` | adb 终端/剪贴板注入/应用版本 |
|
||||
| `devices_api.py` | 设备池管理(增删停用/重连/型号采集) |
|
||||
| `apks_api.py` | 应用管理 |
|
||||
| `tailscale_api.py` | Tailscale 管理 |
|
||||
| `common.py` | 跨模块共享(合并设备列表/屏幕状态) |
|
||||
| `context.py` | 共享对象注入(mgr/apk_mgr/device_pool) |
|
||||
|
||||
关键点:
|
||||
- 脚本编辑用 python3 行级增删(sed 处理多行数组易误伤)
|
||||
- `adb connect` 到不可达 IP 会挂 40s+,220 侧用 `timeout 15` 兜底,超时保留在脚本由 cron 重试
|
||||
- 断开的是 220(STF provider 侧)的 adb 连接,与本机任务直连的 adb 相互独立
|
||||
`web_server.py` 只保留:app 创建、数据库初始化、蓝图注册、uiautodev 生命周期、启动(193 行)。
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user