autotrain/nextgen/scripts/autotrain_next.py
2026-07-24 10:37:32 +08:00

64 lines
3.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
from __future__ import annotations
import argparse
import json
import subprocess
import sys
import time
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT))
from autotrain_next import device, ledger, profiles, recorder, runner, sampling, web
from autotrain_next.paths import CONFIG, WORK
from autotrain_next.platform import scrcpy_binary
def config() -> dict:
return json.loads(CONFIG.read_text(encoding="utf-8")) if CONFIG.exists() else {"planner": {"enabled": False}, "safety": {"max_loop_steps": 30}}
def print_json(data: dict) -> None:
print(json.dumps(data, ensure_ascii=False, indent=2))
def main() -> int:
parser = argparse.ArgumentParser(description="Autotrain Next 原子工具编排入口")
subs = parser.add_subparsers(dest="command", required=True)
subs.add_parser("device-status")
roster = subs.add_parser("roster-import"); roster.add_argument("source", type=Path)
sample = subs.add_parser("sample-import"); sample.add_argument("recording", type=Path); sample.add_argument("--label", default=""); sample.add_argument("--serial", default="")
verify = subs.add_parser("profile-verify"); verify.add_argument("--serial", default="")
record = subs.add_parser("sample-record"); record.add_argument("--output", default=""); record.add_argument("--serial", default="")
task = subs.add_parser("task-create"); task.add_argument("--serial", default=""); task.add_argument("--roster", default=""); task.add_argument("--qr-image", default=""); task.add_argument("--success-action", choices=("download", "email"), default="download"); task.add_argument("--allow-submit", action="store_true")
run_task = subs.add_parser("task-run"); run_task.add_argument("task_id")
ui = subs.add_parser("web"); ui.add_argument("--port", type=int, default=8766)
args = parser.parse_args()
if args.command == "device-status":
target = device.selected_device(); current = device.fingerprint(target.serial); print_json({"device": current, "profile": profiles.compatibility(profiles.load(target.serial), current)}); return 0
if args.command == "sample-record":
# scrcpy 仅供人工控制;录制器明确绑定目标 serial不记录输入内容到设备档案。
target = device.selected_device(args.serial); output = args.output or str(WORK / "replay" / time.strftime("%Y%m%d-%H%M%S"))
subprocess.Popen([scrcpy_binary(), "-s", target.serial, "--window-title", "Autotrain Next 手机屏幕控制"])
recorder.record(Path(output), target.serial)
return 0
if args.command == "roster-import": print_json({"roster": str(ledger.import_roster(args.source))}); return 0
if args.command == "sample-import":
target = device.selected_device(args.serial); print_json(sampling.import_recording(args.recording, device.fingerprint(target.serial), args.label)); return 0
if args.command == "profile-verify":
target = device.selected_device(args.serial); profile = profiles.load(target.serial)
if not profile: raise RuntimeError("该手机尚未导入采样")
samples = profile.get("sampling", {}).get("samples", {})
missing = sorted(profiles.REQUIRED_SAMPLE_PAGES - set(samples))
if missing: raise RuntimeError(f"采样不完整,缺少页面:{', '.join(missing)}")
profile["status"] = "verified"; profiles.save(profile); print_json(profile); return 0
if args.command == "task-create": print_json(runner.create(args.serial, allow_submit=args.allow_submit, roster_path=args.roster, success_action=args.success_action, qr_image=args.qr_image)); return 0
if args.command == "task-run": print_json(runner.run(runner.load(args.task_id), config())); return 0
if args.command == "web": web.serve(args.port); return 0
return 2
if __name__ == "__main__":
raise SystemExit(main())