合并远程变更: adbutils 改造 + 无线 ADB 支持 + TUI 优化
合并内容: - 远程: adbutils 库替换 subprocess、无线 ADB 连接、TUI 闪烁修复 - 本地: 审计日志、命令执行后验证重试、安装脚本 - 合并后保留双方特性: adbutils + 审计日志 + 无线 ADB + 命令验证
This commit is contained in:
+95
-13
@@ -135,7 +135,6 @@ class TuiApp:
|
||||
|
||||
while True:
|
||||
self.height, self.width = self.stdscr.getmaxyx()
|
||||
self.stdscr.clear()
|
||||
self._draw()
|
||||
self.stdscr.refresh()
|
||||
|
||||
@@ -198,6 +197,9 @@ class TuiApp:
|
||||
elif key == ord("s") or key == ord("S"):
|
||||
self._dlg_select_device()
|
||||
|
||||
elif key == ord("w") or key == ord("W"):
|
||||
self._dlg_connect_wireless()
|
||||
|
||||
elif key == ord("h") or key == ord("H"):
|
||||
self._show_help()
|
||||
|
||||
@@ -228,6 +230,14 @@ class TuiApp:
|
||||
y = self._draw_status_panel(y)
|
||||
self._draw_bottombar()
|
||||
|
||||
def _clear_line(self, y: int):
|
||||
"""清空指定行,防止残留内容。"""
|
||||
if 0 <= y < self.height:
|
||||
try:
|
||||
self.stdscr.addstr(y, 0, " " * self.width)
|
||||
except curses.error:
|
||||
pass
|
||||
|
||||
def _draw_titlebar(self):
|
||||
h, w = self.height, self.width
|
||||
title = " padsleep 配置工具 "
|
||||
@@ -262,6 +272,7 @@ class TuiApp:
|
||||
periods = (self.config or {}).get("screen_on_periods", [])
|
||||
if not periods:
|
||||
if y < h:
|
||||
self._clear_line(y)
|
||||
try:
|
||||
self.stdscr.addstr(y, 4, "(暂无时间段 — 按 A 新增)")
|
||||
except curses.error:
|
||||
@@ -270,6 +281,7 @@ class TuiApp:
|
||||
else:
|
||||
# 表头
|
||||
if y < h:
|
||||
self._clear_line(y)
|
||||
try:
|
||||
self.stdscr.addstr(y, 4, " # │ 开始 │ 结束 │", curses.A_UNDERLINE)
|
||||
except curses.error:
|
||||
@@ -278,6 +290,7 @@ class TuiApp:
|
||||
for i, p in enumerate(periods):
|
||||
if y >= h:
|
||||
break
|
||||
self._clear_line(y)
|
||||
sel = "▸" if i == self.selected else " "
|
||||
line = f"{sel}{i+1:>2} │ {p['start']} │ {p['end']} "
|
||||
try:
|
||||
@@ -290,6 +303,7 @@ class TuiApp:
|
||||
y += 1
|
||||
|
||||
if y < h:
|
||||
self._clear_line(y)
|
||||
try:
|
||||
self.stdscr.addstr(y, 4, "[A]新增 [E]编辑 [D]删除 ↑↓选择", curses.A_DIM)
|
||||
except curses.error:
|
||||
@@ -303,38 +317,59 @@ class TuiApp:
|
||||
if self.status:
|
||||
serial_cfg = self.status.get("device_serial", "")
|
||||
detected = self.status.get("device", "")
|
||||
conn_type = self.status.get("connection_type", "none")
|
||||
conn_icon = "USB" if conn_type == "usb" else "WiFi" if conn_type == "wireless" else "---"
|
||||
|
||||
if serial_cfg:
|
||||
dev_str = f"{serial_cfg} (已指定)"
|
||||
elif detected and detected != "无":
|
||||
dev_str = f"{detected} (自动检测)"
|
||||
|
||||
if detected and detected != "无":
|
||||
try:
|
||||
self.stdscr.addstr(y, 4, f"当前设备: {dev_str or detected}")
|
||||
self.stdscr.addstr(y, 4 + len(f"当前设备: {dev_str or detected}"), " ✓", curses.color_pair(3))
|
||||
except curses.error:
|
||||
pass
|
||||
else:
|
||||
try:
|
||||
dev_str = detected or "未连接"
|
||||
|
||||
has_device = conn_type != "none" or (detected and detected != "无")
|
||||
self._clear_line(y)
|
||||
try:
|
||||
label = f"当前设备: {dev_str} [{conn_icon}]"
|
||||
if has_device:
|
||||
self.stdscr.addstr(y, 4, label)
|
||||
self.stdscr.addstr(y, 4 + len(label), " ✓", curses.color_pair(3))
|
||||
else:
|
||||
self.stdscr.addstr(y, 4, "当前设备: 未连接", curses.color_pair(2))
|
||||
except curses.error:
|
||||
pass
|
||||
y += 1
|
||||
y += 1
|
||||
|
||||
# 显示无线连接配置
|
||||
wireless_host = self.status.get("wireless_host", "")
|
||||
wireless_port = self.status.get("wireless_port", 5555)
|
||||
if wireless_host:
|
||||
self._clear_line(y)
|
||||
try:
|
||||
self.stdscr.addstr(y, 4, f"无线配置: {wireless_host}:{wireless_port}", curses.A_DIM)
|
||||
except curses.error:
|
||||
pass
|
||||
y += 1
|
||||
y += 1
|
||||
|
||||
if self.devices:
|
||||
for d in self.devices:
|
||||
if y >= h:
|
||||
break
|
||||
self._clear_line(y)
|
||||
icon = "✓" if d["status"] == "device" else "✗"
|
||||
conn_type = d.get("connection_type", "usb")
|
||||
conn_icon = "USB" if conn_type == "usb" else "WiFi"
|
||||
pair = 3 if d["status"] == "device" else 2
|
||||
try:
|
||||
self.stdscr.addstr(y, 4, f"{icon} {d['serial']}", curses.color_pair(pair))
|
||||
self.stdscr.addstr(f" ({d['status']})")
|
||||
self.stdscr.addstr(f" [{conn_icon}]")
|
||||
except curses.error:
|
||||
pass
|
||||
y += 1
|
||||
else:
|
||||
if y < h:
|
||||
self._clear_line(y)
|
||||
try:
|
||||
self.stdscr.addstr(y, 4, "(无设备 — 请连接平板)", curses.color_pair(2))
|
||||
except curses.error:
|
||||
@@ -342,8 +377,9 @@ class TuiApp:
|
||||
y += 1
|
||||
|
||||
if y < h:
|
||||
self._clear_line(y)
|
||||
try:
|
||||
self.stdscr.addstr(y, 4, "[S]选择设备 [R]刷新", curses.A_DIM)
|
||||
self.stdscr.addstr(y, 4, "[S]选择设备 [W]无线连接 [R]刷新", curses.A_DIM)
|
||||
except curses.error:
|
||||
pass
|
||||
return y + 1
|
||||
@@ -365,6 +401,7 @@ class TuiApp:
|
||||
wf = s.get("wakefulness", "?")
|
||||
|
||||
if y < h:
|
||||
self._clear_line(y)
|
||||
try:
|
||||
self.stdscr.addstr(y, 4, "屏幕: ")
|
||||
self.stdscr.addstr(f"{sc}", curses.color_pair(sc_color) | curses.A_BOLD)
|
||||
@@ -373,6 +410,7 @@ class TuiApp:
|
||||
pass
|
||||
y += 1
|
||||
if y < h:
|
||||
self._clear_line(y)
|
||||
try:
|
||||
self.stdscr.addstr(y, 4, "时段内: ")
|
||||
self.stdscr.addstr(f"{wp}", curses.color_pair(wp_color) | curses.A_BOLD)
|
||||
@@ -381,9 +419,13 @@ class TuiApp:
|
||||
pass
|
||||
y += 1
|
||||
if y < h:
|
||||
self._clear_line(y)
|
||||
try:
|
||||
self.stdscr.addstr(y, 4, "ADB: ")
|
||||
self.stdscr.addstr(f"{ar}", curses.color_pair(ar_color) | curses.A_BOLD)
|
||||
conn_type = s.get("connection_type", "none")
|
||||
if conn_type != "none":
|
||||
self.stdscr.addstr(f" ({conn_type})")
|
||||
except curses.error:
|
||||
pass
|
||||
y += 1
|
||||
@@ -394,6 +436,7 @@ class TuiApp:
|
||||
pass
|
||||
else:
|
||||
if y < h:
|
||||
self._clear_line(y)
|
||||
try:
|
||||
self.stdscr.addstr(y, 4, "(未连接守护进程 — 按 T 重连)")
|
||||
except curses.error:
|
||||
@@ -420,12 +463,13 @@ class TuiApp:
|
||||
bar_y += 1
|
||||
if bar_y >= h:
|
||||
return
|
||||
self._clear_line(bar_y)
|
||||
msg = self.message
|
||||
if msg and time.time() - self.msg_time < 5:
|
||||
pass # show message below separator
|
||||
else:
|
||||
if self.connected:
|
||||
msg = "已连接 | ↑↓/jk 选择 A新增 E编辑 D删除 S选设备 V日志 H帮助"
|
||||
msg = "已连接 | ↑↓/jk 选择 A新增 E编辑 D删除 S选设备 W无线 V日志 H帮助"
|
||||
else:
|
||||
msg = "未检测到守护进程 | T 尝试连接"
|
||||
try:
|
||||
@@ -605,6 +649,43 @@ class TuiApp:
|
||||
else:
|
||||
self.msg(f"选择失败: {r.get('error', '')}")
|
||||
|
||||
def _dlg_connect_wireless(self):
|
||||
"""无线连接对话框。"""
|
||||
# 获取当前无线配置作为默认值
|
||||
wireless_host = ""
|
||||
wireless_port = "5555"
|
||||
if self.status:
|
||||
wireless_host = self.status.get("wireless_host", "")
|
||||
wireless_port = str(self.status.get("wireless_port", 5555))
|
||||
|
||||
# 输入 IP 地址
|
||||
host = self._dlg_input("无线设备 IP 地址:", wireless_host)
|
||||
if not host:
|
||||
return
|
||||
|
||||
# 输入端口
|
||||
port_str = self._dlg_input("端口号:", wireless_port)
|
||||
if not port_str:
|
||||
return
|
||||
|
||||
try:
|
||||
port = int(port_str)
|
||||
if not (1 <= port <= 65535):
|
||||
self.msg("端口范围错误 (1-65535)")
|
||||
return
|
||||
except ValueError:
|
||||
self.msg("端口格式错误")
|
||||
return
|
||||
|
||||
# 发送连接请求
|
||||
self.msg(f"正在连接 {host}:{port} ...")
|
||||
r = self.client.send("connect_wireless", host=host, port=port)
|
||||
if r.get("ok"):
|
||||
self.msg(f"无线设备已连接: {host}:{port}")
|
||||
self.refresh()
|
||||
else:
|
||||
self.msg(f"连接失败: {r.get('error', '未知错误')}")
|
||||
|
||||
@staticmethod
|
||||
def _validate_time(tstr: str) -> bool:
|
||||
try:
|
||||
@@ -678,6 +759,7 @@ class TuiApp:
|
||||
" E 编辑选中时间段",
|
||||
" D 删除选中时间段",
|
||||
" S 选择 ADB 设备",
|
||||
" W 无线连接设备",
|
||||
" R 刷新状态",
|
||||
" L 重载守护进程配置",
|
||||
" V 查看审计日志",
|
||||
|
||||
Reference in New Issue
Block a user