# -*- coding: utf-8 -*- """两处修正: 1. 产品:_file_list 截断到 100 个时**要说出来** 现在超过 100 个文件时,老的会被静默隐藏 —— 用户看到列表里没有,会以为文件丢了。 加上 total 和 truncated,让界面能提示"还有 N 个未显示"。 2. 测试:verify_all 开始前清掉 _tests/received 这次踩的坑:历次测试攒了 116 个文件,把 java_payload.bin 挤到了 第 113 位、超出前 100 的窗口,于是"file_list 看不到刚上传的文件" 这条断言假失败。测试环境自己该保持干净。 """ from __future__ import annotations import sys from pathlib import Path ROOT = Path(r"C:\Users\shu\Desktop\deepseekagent\LanRemote") SERVER = ROOT / "windows" / "lanremote" / "server.py" VERIFY = ROOT / "_tests" / "verify_all.ps1" # ---------------- 1. _file_list 说清楚截断了 ---------------- OLD = ''' def _file_list(self) -> dict: directory = self.store.received_dir() files = [] try: for entry in sorted(directory.iterdir(), key=lambda p: p.stat().st_mtime if p.is_file() else 0, reverse=True)[:100]: if entry.is_file(): files.append({ "name": entry.name, "size": entry.stat().st_size, "mtime": entry.stat().st_mtime, }) except OSError as exc: raise ActionError(f"读取目录失败: {exc}") from exc return {"ok": True, "dir": str(directory), "files": files}''' NEW = ''' # 一次最多返回多少个文件。 # 为什么不返回全部:手表屏幕就那么大,几千条也翻不动, # 而且一条 JSON 太长会把单条消息撑爆。 FILE_LIST_LIMIT = 100 def _file_list(self) -> dict: directory = self.store.received_dir() try: entries = [p for p in directory.iterdir() if p.is_file()] except OSError as exc: raise ActionError(f"读取目录失败: {exc}") from exc total = len(entries) entries.sort(key=lambda p: p.stat().st_mtime, reverse=True) shown = entries[:self.FILE_LIST_LIMIT] files = [] for entry in shown: try: files.append({ "name": entry.name, "size": entry.stat().st_size, "mtime": entry.stat().st_mtime, }) except OSError: # 正好被别的进程删掉了,跳过就好,别让整条列表失败 continue return { "ok": True, "dir": str(directory), "files": files, # 说清楚有没有被截断 —— 不能默默藏起来, # 用户会以为文件丢了(这个坑在测试里踩过一次)。 "total": total, "shown": len(files), "truncated": total > len(files), }''' # ---------------- 2. verify_all 开始前清测试残留 ---------------- VERIFY_ANCHOR = '''# ---------------------------------------------------------------- 0 # 编码审计放最前面:编码错了后面全白搭''' VERIFY_NEW = '''# ---------------------------------------------------------------- 0a # 清掉上一次测试留在 received 里的文件。 # 不清的话会越攒越多,把 file_list 的前 100 个窗口挤满, # 导致"看不到刚上传的文件"这类假失败(真踩过:攒到 116 个)。 $receivedDir = Join-Path $root "_tests\\received" if (Test-Path $receivedDir) { $old = (Get-ChildItem $receivedDir -File -ErrorAction SilentlyContinue).Count if ($old -gt 0) { Get-ChildItem $receivedDir -File | Remove-Item -Force -ErrorAction SilentlyContinue Write-Host " 清掉上次测试残留的 $old 个文件" -ForegroundColor DarkGray } } # ---------------------------------------------------------------- 0 # 编码审计放最前面:编码错了后面全白搭''' def main() -> int: ok = True # ---- server.py ---- text = SERVER.read_text(encoding="utf-8") if "FILE_LIST_LIMIT" in text: print(" server.py: 已经改过") elif OLD in text: text = text.replace(OLD, NEW, 1) SERVER.write_text(text, encoding="utf-8", newline="\n") print(" server.py: _file_list 现在会报告 total/truncated") else: print(" [失败] server.py 锚点没找到") ok = False # ---- verify_all.ps1(保持 BOM)---- raw = VERIFY.read_bytes() had_bom = raw.startswith(b"\xef\xbb\xbf") text = raw.decode("utf-8-sig") if "清掉上次测试留在 received" in text: print(" verify_all.ps1: 已经加过清理") elif VERIFY_ANCHOR in text: text = text.replace(VERIFY_ANCHOR, VERIFY_NEW, 1) VERIFY.write_bytes((b"\xef\xbb\xbf" if had_bom else b"") + text.replace("\r\n", "\n").encode("utf-8")) print(f" verify_all.ps1: 加了测试残留清理(BOM {'保留' if had_bom else '无'})") else: print(" [失败] verify_all.ps1 锚点没找到") ok = False # ---- 语法 / BOM 复核 ---- import ast try: ast.parse(SERVER.read_text(encoding="utf-8")) print(" server.py 语法 OK") except SyntaxError as exc: print(f" server.py 语法错误: {exc}") ok = False raw = VERIFY.read_bytes() bom_state = "有" if raw.startswith(b"\xef\xbb\xbf") else "无" print(f" verify_all.ps1 BOM: {bom_state}") return 0 if ok else 1 if __name__ == "__main__": sys.exit(main())