snowy-yang
|
0569b50737
|
refactor: 清理 13 处生产死代码
为什么:用 AST 级引用分析(而非文本 grep——同名符号会互相掩盖)确认这些
符号全项目零引用。文本 grep 查不出的原因是它们都有「活着的同名兄弟」:
services/downloads.py(共 6 个,93 行)
_parse_cookie_str / _global_music_u / _vip_name / _detect_vip /
_admin_client / _user_client
—— 活的是 core.media.parse_cookie_str、web/routers/music.py、account.py 的版本
随之失效的 import:USER_COOKIE_FILE / GLOBAL_MUSIC_U_CACHE / VIP_PROBE_LOCK /
account_info / detect_vip_by_probe / QRLoginClient
services/api_service.py
APIResponse 类(29 行)—— web/response.py 才是活的响应封装
services/_shared.py
_rate_ok —— 逐字复制 web.ratelimit.rate_ok
core/utils.py
safe_int / safe_console_print —— 活的是 web/request_utils.safe_int
core/repo.py
all_settings / get_user_by_name —— auth_system.get_user_by_name 才是活的
core/db.py / web/auth_state.py / web/request_utils.py
execute_many / _safe_register_credits + secrets_rand / dedup_ids
结果:生产代码死代码候选 13 → 0(余下 118 个全是 pytest 测试函数,属正常)。
|
2026-09-26 18:54:11 +08:00 |
|
snowy-yang
|
7a70eef636
|
refactor: 删除 services.runtime 兼容门面,7 处调用点直连真实子模块
为什么:上一次分包重构把 1900 行巨石按职责拆成 9 个子模块后,留了一个
runtime.py 作为「原样再导出」的兼容门面,好让调用点零改动。但迁移期结束后
没有一个调用点迁走——门面成了永久中间层:每次读代码都要先跳一层才知道
符号真正住在哪,pyright 也无法从门面追溯定义位置。
改法:保持「函数内延迟导入」的形式不变,只把导入目标换成真实子模块。
**刻意不提到模块顶部**——services/__init__.py 里有依赖自检
(缺 auth_system/podcast_api/music_api/music_downloader/qr_login 就 sys.exit(1)),
提到顶层会让「import web.*」这一步就触发该自检,改变启动语义,超出本次范围。
7 处调用点(AST 精确扫描确认全集):
- web/routers/download.py ×4:download / download_batch_zip / podcast_download /
podcast_batch_zip,分别直连 services.downloads / batch / podcast / tasks
外加 _shared._build_download_base 与 api_service.api_service
- web/routers/tasks.py ×2:_semaphores 取 _shared.BATCH_ZIP_SEM + api_service,
topen 取 _shared.ENDPOINT_NAMES
- web/tasks_registry.py ×1:start_task 直连 _taskcore._start_task_thread
子模块短名统一加 `services_` 前缀别名(services_tasks 等),避免与函数内
既有局部名相撞。
顺带清理:9 个子模块 docstring 里「(自 services/runtime.py 拆出……)」的
历史说明在门面删除后已成悬空引用,一并去掉;包的模块划分说明改为
「不再有兼容门面层」。
验证:
- 符号可达:11 个被引符号在真实子模块上全部 hasattr 通过;
services.runtime 已 ModuleNotFoundError;api_service 仍是同一实例对象
- 三个调用方模块均可正常 import
- 门禁:ruff 0 · pyright 0 errors 0 warnings · pytest 175 passed
- 真实 uvicorn 冒烟 8/8(含 POST /auth/login 400),临时数据目录独立落库
9 张表,生产 data/ 指纹三项一致
|
2026-09-26 14:48:05 +08:00 |
|
snowy-yang
|
da3d013e9c
|
chore: 清理前端与容器脚本中指向已删台账的过时编号
模板/样式/脚本的注释里散落着「第 N 条」「F59」「P3-43」这类编号,它们指向的
修复验收台账与交接文档已在本轮删除——留着既检索不到、也对不上号,还让后来读
注释的人以为存在一份可查的编号清单。本次只动注释,正文零改动。
覆盖范围(全仓一致):
- templates/index.html 163 处、static/site_auth.js 55 处,共 218 处编号整段摘除
(含「第 N 条(Px):」前缀与「(Fxx 短标签)」括号)。
- 容器/配置 16 处:docker-compose.yml、entrypoint.sh(F59 / 第 93 条 / 第 97 条)、
Dockerfile(T7 / 第 97 条)、.dockerignore(T1 / 第 97 条 / 第 55 条 / P2-9)、
.env.example(F59 / 第 100 条 / 「详见交接文档 F11」这条失效指引)、.gitignore(P3-41)。
- Python 4 处:core/config.py(D-1)、services/tasks.py(O-5×2)、services/_shared.py(O-5)
——上一轮 Python 侧清理的漏网。
为什么规则要收窄(两类误伤,实测踩到):
1. 标签首字母不能用泛化的 [A-Z]:X5 是 QQ 浏览器内核、ES5 是 JS 版本,都不是编号。
泛化后会把「微信 XWeb/X5、QQ 内置」改成「微信 XWeb/、QQ 内置」,把
「Chromium <87 的老 X5 不识别 inset」改成「老 不识别」。现按本仓真实用过的
任务族白名单收窄(A B C D F O P R S T U),X5/ES5 原样保留。
2. 括号内「编号 + 长说明」不能整段删:「(F51 只防了切歌,这里补同歌翻页)」
整段删掉会连说明一起丢;现只摘编号、保留说明文字。
为什么同步改黄金契约快照:题头注释属于模板内容,改了注释首页字节数必然变
(466261 → 464333),tests/golden/responses.json 的 index 条目按既定流程刷新
html_len/html_sha256;并在 tests/test_golden.py 补一段说明,写清该条目记的是
「当前模板」而非 Flask 期数值、以及有意改模板后如何重算
(html_len = 文件字节数 - 1,sha256 = 文件去掉末尾换行后的哈希)。
验证(全部通过):
- 与 HEAD 比对:剥离全部注释后的正文逐行一致(唯一差异是删掉了一处行尾空注释),
行数不变、每行半角括号/引号数量不变 → 代码与字符串零改动;
- node --check 通过(静态 JS + index.html 内联脚本),<style> 块花括号平衡;
- 真实 uvicorn 冒烟:/health /user/status /api/topen → 200、/admin/site/backup/list → 403,
/static/site_auth.js 响应体与本地文件 sha1 相同,/ 无「第 N 条」残留;
- ruff All checks passed;pyright 0 errors / 0 warnings;pytest 144 passed。
|
2026-09-26 13:18:44 +08:00 |
|
snowy-yang
|
6288a98ecc
|
refactor: 拆分 4 个巨石模块为包,清理过时注释并删除作废文档
为什么:单文件 1100~1900 行的巨石模块让「改一处要通读全文」;同时注释里残留
大量已删台账的编号,以及「Flask/FastAPI 双栈迁移期」这类已失实的架构描述,
会误导后来者按不复存在的架构去改代码。
拆分(对外导入路径不变,行为零变更):
- music_downloader.py -> music_downloader/(models/downloader/cover/_http/_log/_concurrency)
- auth_system.py -> auth_system/(db/security/users/credits/ledger/mail/cards/backup...)
- music_api.py -> music_api/(api/client/crypto/qr/cookies/compat/constants/errors)
- services/runtime.py -> services/(api_service/_shared/_taskcore/downloads/batch/podcast/
streaming/tasks);services/runtime.py 保留为兼容门面
兼容性做法:各包用 __init__.py 以 __all__ 原样再导出全部符号,既有调用点
(auth_system.xxx / services.xxx / from music_api import Y)零改动;路径常量改为经包属性
动态读取(auth_system.DB_PATH),否则测试的 monkeypatch 会静默失效并写到生产库。
修复 9 处代码损伤(上一轮注释清理把 `()` 当「空括号残留」删掉所致;用「与拆分前逐字
等价」校验逐一定位,静态检查只会报出其中 4 处):
- core/config.py ).strip() or '*'
- core/state.py threading.Lock() x2
- qr_login.py datetime.now() / .strip()
- music_downloader/downloader.py .lower()
- services/podcast.py set() / time.time() x2
清理与删除:
- 删除 部署文档.md / 功能介绍.md / README_私有包警告.txt
- 清理指向已删台账与文档的过时编号注释;把「迁移期 / 两栈 / 双框架 / 已迁移」等
失实描述改写为现状描述(保留 `<-> Flask /path` 映射表等仍有价值的契约来源说明)
- _mkpkg.py:公开包剔除清单去掉已不存在的文档名;私有包警告改为自包含
- pyproject.toml:补 pythonpath = ["."],使裸跑 pytest 不再 import core 失败
验证:ruff 全通过;pyright 0 errors / 0 warnings(102 文件);pytest 144 passed;
真实 uvicorn 冒烟 6 条路由符合预期且生产 data/ 指纹未变;忽略注释的逐字等价性校验通过。
|
2026-09-26 12:37:48 +08:00 |
|