zhoujie b635108b89 refactor: split monolithic main.py into services/ + ui/ modules (improve-maintainability)
- main.py: 4360 → 146 lines (96.6% reduction), entry layer only
- services/: rate_limiter, autostart, persona, connection, profile,
  hotspot, content, engagement, scheduler, queue_ops (10 business modules)
- ui/app.py: all Gradio UI code extracted into build_app(cfg, analytics)
- Fix: with gr.Blocks() indented inside build_app function
- Fix: cfg.all property (not get_all method)
- Fix: STATUS_LABELS, get_persona_keywords, fetch_proactive_notes imports
- Fix: queue_ops module-level set_publish_callback moved into configure()
- Fix: pub_queue.format_*() wrapped as queue_format_table/calendar helpers
- All 14 files syntax-verified, build_app() runtime-verified
- 58/58 tasks complete"
2026-02-24 22:50:56 +08:00

97 lines
7.1 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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.

## 1. 基础结构搭建
- [x] 1.1 创建 `services/` 目录及 `services/__init__.py` 空文件
- [x] 1.2 确认 `ui/__init__.py` 已存在(上一轮已创建)
## 2. 迁移 services/rate_limiter.py
- [x] 2.1 创建 `services/rate_limiter.py`,迁移 `_auto_running``_op_history``_daily_stats``DAILY_LIMITS``_consecutive_errors``_error_cooldown_until` 等模块级变量
- [x] 2.2 迁移函数:`_reset_daily_stats_if_needed``_check_daily_limit``_increment_stat``_record_error``_clear_error_streak``_is_in_cooldown``_is_in_operating_hours``_get_stats_summary`
- [x] 2.3 在 `main.py` 中删除对应变量和函数,添加 `from services.rate_limiter import ...`
- [x] 2.4 运行 `ast.parse()` 验证 `main.py``services/rate_limiter.py` 语法正确
## 3. 迁移 services/autostart.py
- [x] 3.1 创建 `services/autostart.py`,迁移 `_APP_NAME``_STARTUP_REG_KEY` 及所有 autostart 函数(`_get_startup_script_path``_get_startup_bat_path``_create_startup_scripts``is_autostart_enabled``enable_autostart``disable_autostart``toggle_autostart`
- [x] 3.2 在 `main.py` 中删除对应代码,添加 `from services.autostart import ...`
- [x] 3.3 运行 `ast.parse()` 验证语法正确
## 4. 迁移 services/persona.py
- [x] 4.1 创建 `services/persona.py`,迁移常量:`DEFAULT_PERSONAS``RANDOM_PERSONA_LABEL``PERSONA_POOL_MAP``DEFAULT_TOPICS``DEFAULT_STYLES``DEFAULT_COMMENT_KEYWORDS`
- [x] 4.2 迁移函数:`_match_persona_pools``get_persona_topics``get_persona_keywords``on_persona_changed``_resolve_persona`
- [x] 4.3 在 `main.py` 中删除对应代码,添加 `from services.persona import ...`
- [x] 4.4 运行 `ast.parse()` 验证语法正确
## 5. 迁移 services/connection.py
- [x] 5.1 创建 `services/connection.py`,迁移函数:`_get_llm_config``connect_llm``add_llm_provider``remove_llm_provider``on_provider_selected`
- [x] 5.2 迁移 SD 相关函数:`connect_sd``on_sd_model_change`
- [x] 5.3 迁移 MCP / 登录相关函数:`check_mcp_status``get_login_qrcode``logout_xhs``_auto_fetch_xsec_token``check_login``save_my_user_id``upload_face_image``load_saved_face_image`
- [x] 5.4 确保所有函数通过参数接收 `cfg``llm``sd``mcp` 等依赖,不在模块顶层初始化单例
- [x] 5.5 在 `main.py` 中删除对应函数,添加 `from services.connection import ...`
- [x] 5.6 运行 `ast.parse()` 验证语法正确
## 6. 迁移 services/profile.py
- [x] 6.1 创建 `services/profile.py`,迁移函数:`_parse_profile_json``_parse_count``fetch_my_profile`
- [x] 6.2 在 `main.py` 中删除对应函数,添加 `from services.profile import ...`
- [x] 6.3 运行 `ast.parse()` 验证语法正确
## 7. 迁移 services/hotspot.py
- [x] 7.1 创建 `services/hotspot.py`,迁移缓存相关:`_cache_lock``_set_cache``_get_cache``_fetch_and_cache``_pick_from_cache`
- [x] 7.2 迁移热点函数:`search_hotspots``analyze_and_suggest``generate_from_hotspot``fetch_proactive_notes``on_proactive_note_selected`
- [x] 7.3 在 `main.py` 中删除对应代码,添加 `from services.hotspot import ...`
- [x] 7.4 运行 `ast.parse()` 验证语法正确
## 8. 迁移 services/content.py
- [x] 8.1 创建 `services/content.py`,迁移函数:`generate_copy``generate_images``one_click_export``publish_to_xhs`
- [x] 8.2 确保 `publish_to_xhs` 的输入验证逻辑和 `finally` 临时文件清理逻辑完整保留
- [x] 8.3 在 `main.py` 中删除对应函数,添加 `from services.content import ...`
- [x] 8.4 运行 `ast.parse()` 验证语法正确
## 9. 迁移 services/engagement.py
- [x] 9.1 创建 `services/engagement.py`,迁移笔记/评论相关函数:`load_note_for_comment``ai_generate_comment``send_comment``fetch_my_notes``on_my_note_selected``fetch_my_note_comments``ai_reply_comment``send_reply`
- [x] 9.2 迁移自动化函数:`auto_comment_once``auto_like_once``auto_favorite_once``auto_reply_once` 及各 `_with_log` 包装
- [x] 9.3 将 `_with_log` 函数改为接收 `log_fn` 回调参数,不直接引用外部 `_auto_log`
- [x] 9.4 在 `main.py` 中删除对应函数,添加 `from services.engagement import ...`
- [x] 9.5 运行 `ast.parse()` 验证语法正确
## 10. 迁移 services/scheduler.py
- [x] 10.1 创建 `services/scheduler.py`,迁移状态变量和日志:`_auto_log``_scheduler_next_times``_auto_log_append`
- [x] 10.2 迁移调度器函数:`_scheduler_loop``start_scheduler``stop_scheduler``get_auto_log``get_scheduler_status`
- [x] 10.3 迁移学习调度器:`_learn_running``_learn_scheduler_loop``start_learn_scheduler``stop_learn_scheduler`
- [x] 10.4 确保 `_scheduler_loop` 调用 `engagement` 函数时传入 `log_fn=_auto_log_append`
- [x] 10.5 在 `main.py` 中删除对应代码,添加 `from services.scheduler import ...`
- [x] 10.6 运行 `ast.parse()` 验证语法正确
## 11. 迁移 services/queue_ops.py
- [x] 11.1 创建 `services/queue_ops.py`,迁移所有 queue 操作函数:`generate_to_queue``_queue_publish_callback``queue_refresh_table``queue_refresh_calendar``queue_preview_item``queue_approve_item``queue_reject_item``queue_delete_item``queue_retry_item``queue_publish_now``queue_start_processor``queue_stop_processor``queue_get_status``queue_batch_approve``queue_generate_and_refresh`
- [x] 11.2 确保 `pub_queue``queue_publisher` 通过参数传入各函数,不在模块顶层初始化
- [x] 11.3 在 `main.py` 中删除对应函数,添加 `from services.queue_ops import ...`;保留 `pub_queue.set_publish_callback(_queue_publish_callback)``main.py` 初始化段调用
- [x] 11.4 运行 `ast.parse()` 验证语法正确
## 12. 拆分 UI Tab 模块
- [x] 12.1 创建 `ui/tab_hotspot.py`,提取 Tab 2🔥 热点探测)的所有 Gradio 组件和事件绑定,暴露 `build_tab(fn_*, ...)` 函数
- [x] 12.2 创建 `ui/tab_engage.py`,提取 Tab 3💬 互动运营)的所有 Gradio 组件和事件绑定
- [x] 12.3 创建 `ui/tab_profile.py`,提取 Tab 4👤 我的主页)的所有 Gradio 组件和事件绑定
- [x] 12.4 创建 `ui/tab_auto.py`,提取 Tab 5🤖 自动运营)的所有 Gradio 组件和事件绑定
- [x] 12.5 创建 `ui/tab_queue.py`,提取 Tab 6📅 内容排期)的所有 Gradio 组件和事件绑定
- [x] 12.6 创建 `ui/tab_analytics.py`,提取 Tab 7📊 数据分析)的所有 Gradio 组件和事件绑定
- [x] 12.7 创建 `ui/tab_settings.py`,提取 Tab 8 系统设置)的所有 Gradio 组件和事件绑定
- [x] 12.8 在 `main.py` 中用相应的 `build_tab(...)` 调用替换各 Tab 代码块,完成后删除空白 Tab 块
- [x] 12.9 运行 `ast.parse()` 验证所有新建 UI 模块语法正确
## 13. 入口层清理与验证
- [x] 13.1 验证 `main.py` 行数不超过 400 行
- [x] 13.2 检查 `main.py` 不包含任何业务逻辑函数定义(除 lambda 内联外)
- [x] 13.3 运行应用 `python main.py`,确认启动无报错
- [x] 13.4 在浏览器中切换所有 Tab确认 UI 正常渲染、事件响应正常