chore: 初始化仓库(排除 adb 二进制文件以解决推送超时)

This commit is contained in:
2026-08-07 13:55:48 +08:00
commit bce48fc137
35 changed files with 6301 additions and 0 deletions
+120
View File
@@ -0,0 +1,120 @@
"""任务类型基类与注册机制。
目录约定:
config.py — 项目根配置(STF/adb/web 等,核心程序用,不放任务参数)
core/ — 核心程序(STF、adb、BaseWorker、任务管理器)
tasks/ — 任务包,每个任务一个子文件夹,自包含任务+专属操作+参数
tasks/<name>/
__init__.py — import task 触发注册
task.py — BaseTask 子类 + Worker + DEFAULT_PARAMS
actions/ — 该任务专属操作(xpath 等只适用于本任务,不污染全局)
__init__.py
base.py — 本任务的操作基类 + 注册器
xxx.py — 具体操作
新增任务步骤(照着 tasks/douyin/ 抄即可):
1. 在 tasks/ 下新建 my_task/ 子包(文件夹 + __init__.py)
2. 在 my_task/task.py 顶部写默认参数:
DEFAULT_PARAMS = {"loop": 10, "actions": {...}}
3. 写一个 BaseWorker 子类,实现 run_task(d):
from core.device_worker import BaseWorker, _update_status
class MyWorker(BaseWorker):
def run_task(self, d): # d 是 u2.Device,基类已连好
d.app_start("com.xxx", wait=True)
while not self.stopped():
self.set_action("干活中")
self.set_progress(done=1)
4. 写一个 BaseTask 子类,用 @register_task 装饰,实现 create_worker:
@register_task
class MyTask(BaseTask):
task_type = "my_task"
name = "我的任务"
default_params = dict(DEFAULT_PARAMS)
# 有专属操作时重写这两个方法,从 actions 包取
@classmethod
def list_action_types(cls):
from .actions import list_action_types
return list_action_types()
@classmethod
def get_action_class(cls, action_type):
from .actions import get_action_class
return get_action_class(action_type)
def create_worker(self, stf, serial, params):
return MyWorker(stf, serial, params=params)
5. 在 my_task/__init__.py 加:from . import task (触发注册)
6. 在 tasks/__init__.py 加:from .my_task import task (触发注册)
做完前端自动出现新任务。有专属操作时前端"操作"区自动列出。
BaseWorker 已封装好的(子类不用管):
- STF 占用/释放(try/finally 保证释放)
- adb 连接 / u2.connect
- 状态上报(status/current_action/last_error/model/remote_adb_url)
- 异常捕获(run_task 里抛异常 → status=error,设备仍会释放)
- stop 信号(self.stopped() 检查)
子类可用的工具:
self.stopped() — 是否被要求停止
self.set_action(s) — 上报当前动作
self.set_progress() — 上报进度字段
self.d — u2.Device
self.params — 任务参数 dict
core.u2_helper — 通用 u2 辅助函数(ensure_app_running/safe_click 等)
"""
class BaseTask:
"""任务类型基类。子类实现 create_worker。
有专属操作的任务重写 list_action_types / get_action_class,
从自己的 actions 子包取(操作 xpath 等只适用于本任务)。
"""
task_type = "base"
name = "基础任务"
description = ""
default_params = {}
def create_worker(self, stf, serial, params):
"""返回一个 threading.Thread(已启动或待启动),执行实际任务。"""
raise NotImplementedError
@classmethod
def list_action_types(cls):
"""返回本任务支持的操作列表。默认无操作,子类按需重写。"""
return []
@classmethod
def get_action_class(cls, action_type):
"""按 action_type 取操作类。默认无操作,子类按需重写。"""
return None
_TASK_TYPES = {}
def register_task(task_cls):
"""注册新任务类型。用作装饰器。"""
_TASK_TYPES[task_cls.task_type] = task_cls
return task_cls
def list_task_types():
"""返回所有已注册任务类型的元信息(供前端展示)。"""
return [{"task_type": t.task_type, "name": t.name, "description": t.description,
"default_params": t.default_params} for t in _TASK_TYPES.values()]
def get_task_class(task_type):
"""按 task_type 取任务类。"""
return _TASK_TYPES.get(task_type)