# -*- coding: utf-8 -*- """1) features.py:给需要输入的功能补上参数说明(手表端据此弹输入框) 2) config.py:新增 file_roots / extra_apps / extra_commands 三个设置 3) ui.py 设置窗口:加三个多行输入框 —— 这就是"边界可配置" """ from __future__ import annotations import sys from pathlib import Path ROOT = Path(r"C:\Users\shu\Desktop\deepseekagent\LanRemote\windows\lanremote") FEATURES = ROOT / "features.py" CONFIG = ROOT / "config.py" UI = ROOT / "ui.py" # ---------------- features.py:补参数说明 ---------------- PARAM_PAIRS = [ ( 'add("list_dir", "浏览文件夹", "action", "文件")', 'add("list_dir", "浏览文件夹", "input", "文件", hint="如 Downloads", key="path")', ), ( 'add("download_file", "下载文件到手表", "action", "文件")', 'add("download_file", "下载文件到手表", "input", "文件",\n' ' hint="完整路径", key="path")', ), ( 'add("search_files", "搜索文件", "action", "文件")', 'add("search_files", "搜索文件", "input", "文件",\n' ' hint="关键词", key="keyword")', ), ( 'add("make_dir", "新建文件夹", "action", "文件")', 'add("make_dir", "新建文件夹", "input", "文件",\n' ' hint="父目录", key="path", hint2="文件夹名", key2="name")', ), ( 'add("rename_file", "重命名", "action", "文件")', 'add("rename_file", "重命名", "input", "文件",\n' ' hint="文件路径", key="path", hint2="新名字", key2="name")', ), ( 'add("delete_file", "删除到回收站", "action", "文件")', 'add("delete_file", "删除到回收站", "input", "文件",\n' ' hint="文件路径", key="path")', ), ( 'add("open_file", "用默认程序打开", "action", "文件")', 'add("open_file", "用默认程序打开", "input", "文件",\n' ' hint="文件路径", key="path")', ), ( 'add("note_add", "记一条笔记", "action", "效率")', 'add("note_add", "记一条笔记", "input", "效率", hint="内容", key="text")', ), ( 'add("todo_add", "加一条待办", "action", "效率")', 'add("todo_add", "加一条待办", "input", "效率", hint="内容", key="text")', ), ( 'add("reminder", "定时提醒", "action", "效率")', 'add("reminder", "定时提醒", "input", "效率",\n' ' hint="几分钟后", key="minutes", hint2="提醒内容", key2="text")', ), ] # ---------------- config.py ---------------- CONFIG_OLD = ' "mp3_dir": "", # 本机音乐目录,空=自动找 音乐/Music\n' CONFIG_NEW = (' "mp3_dir": "", # 本机音乐目录,空=自动找 音乐/Music\n' ' # ---- 下面三项是"边界可配置":由电脑主人决定允许什么 ----\n' ' "file_roots": "", # 额外允许的目录,分号分隔\n' ' "extra_apps": "", # 自定义快捷程序:显示名=路径,分号分隔\n' ' "extra_commands": "", # 自定义命令别名:显示名=命令,分号分隔\n') # ---------------- ui.py:设置窗口加三个多行框 ---------------- UI_ANCHOR = ''' # 本机音乐目录 row_label("本机音乐目录", "留空=自动找 音乐 / Music / Downloads") ent_mp3 = entry(str(self.store.get("mp3_dir") or "")) ''' UI_NEW = ''' # 本机音乐目录 row_label("本机音乐目录", "留空=自动找 音乐 / Music / Downloads") ent_mp3 = entry(str(self.store.get("mp3_dir") or "")) # ---- 边界可配置:由电脑主人决定允许什么 ---- row_label("额外允许的目录", "一行一个,如 D:\\\\课件") txt_roots = textbox(str(self.store.get("file_roots") or "").replace(";", "\\n")) row_label("自定义快捷程序", "一行一个,格式:显示名=程序路径") txt_apps = textbox(str(self.store.get("extra_apps") or "").replace(";", "\\n")) row_label("自定义命令", "一行一个,格式:显示名=命令。手表只能选这里登记过的") txt_cmds = textbox(str(self.store.get("extra_commands") or "").replace(";", "\\n")) ''' UI_TEXTBOX_HELPER = ''' def textbox(initial: str): box = tk.Frame(win, bg=BG) box.pack(fill="x", padx=16) widget = tk.Text(box, height=3, width=46, bg=CARD, fg=FG, relief="flat", font=("Microsoft YaHei UI", 9), highlightthickness=1, highlightbackground=BORDER, wrap="none") widget.pack(fill="x") widget.insert("1.0", initial) return widget def row_label(text, hint=""):''' UI_SAVE_OLD = ''' self.store.set("mp3_dir", ent_mp3.get().strip()) ''' UI_SAVE_NEW = ''' self.store.set("mp3_dir", ent_mp3.get().strip()) def join_lines(widget): pieces = [line.strip() for line in widget.get("1.0", "end").splitlines() if line.strip()] return ";".join(pieces) self.store.set("file_roots", join_lines(txt_roots)) self.store.set("extra_apps", join_lines(txt_apps)) self.store.set("extra_commands", join_lines(txt_cmds)) ''' def main() -> int: ok = True text = FEATURES.read_text(encoding="utf-8") hits = 0 for old, new in PARAM_PAIRS: if old not in text: print(f" [失败] features.py 锚点: {old[:46]}") ok = False else: text = text.replace(old, new, 1) hits += 1 if ok: FEATURES.write_text(text, encoding="utf-8") print(f" features.py: {hits} 个功能补上参数说明") ctext = CONFIG.read_text(encoding="utf-8") if CONFIG_OLD not in ctext: print(" [失败] config.py 锚点未匹配") ok = False else: ctext = ctext.replace(CONFIG_OLD, CONFIG_NEW, 1) CONFIG.write_text(ctext, encoding="utf-8") print(" config.py: 新增 3 个设置") utext = UI.read_text(encoding="utf-8") for old, new, tag in ((UI_ANCHOR, UI_NEW, "设置项"), (UI_SAVE_OLD, UI_SAVE_NEW, "保存")): if old not in utext: print(f" [失败] ui.py {tag} 锚点未匹配") ok = False else: utext = utext.replace(old, new, 1) print(f" ui.py / {tag}: OK") helper_anchor = " def row_label(text, hint=\"\"):" if helper_anchor not in utext: print(" [失败] ui.py row_label 锚点未匹配") ok = False else: utext = utext.replace(helper_anchor, UI_TEXTBOX_HELPER, 1) print(" ui.py / textbox 辅助: OK") if ok: UI.write_text(utext, encoding="utf-8") print("\n语法检查:") import ast for name, path in (("features.py", FEATURES), ("config.py", CONFIG), ("ui.py", UI)): try: ast.parse(path.read_text(encoding="utf-8")) print(f" {name}: OK") except SyntaxError as exc: print(f" {name}: 语法错误 {exc}") ok = False return 0 if ok else 1 if __name__ == "__main__": sys.exit(main())