xhs_factory/main.py
zhoujie 2ba87c8f6e
Some checks failed
CI / Lint (ruff) (push) Has been cancelled
CI / Import Check (push) Has been cancelled
📝 docs(project): 添加开源社区标准文档与 CI 工作流
- 新增 GitHub Issue 模板(Bug 报告、功能请求)和 Pull Request 模板
- 新增 Code of Conduct(贡献者行为准则)和 Security Policy(安全政策)
- 新增 CI 工作流(GitHub Actions),包含 ruff 代码检查和导入验证
- 新增开发依赖文件 requirements-dev.txt

📦 build(ci): 配置 GitHub Actions 持续集成

- 在 push 到 main 分支和 pull request 时自动触发 CI
- 添加 lint 任务执行 ruff 代码风格检查
- 添加 import-check 任务验证核心服务模块导入

♻️ refactor(structure): 重构项目目录结构

- 将根目录的 6 个服务模块迁移至 services/ 包
- 更新所有相关文件的导入语句(main.py、ui/、services/)
- 根目录仅保留 main.py 作为唯一 Python 入口文件

🔧 chore(config): 调整配置和资源文件路径

- 将 config.json 移至 config/ 目录,更新相关引用
- 将个人头像图片移至 assets/faces/ 目录,更新 .gitignore
- 更新 Dockerfile 和 docker-compose.yml 中的配置路径

📝 docs(readme): 完善 README 文档

- 添加项目状态徽章(Python 版本、License、CI)
- 更新项目结构图反映实际目录布局
- 修正使用指南中的 Tab 名称和操作路径
- 替换 your-username 占位符为格式提示

🗑️ chore(cleanup): 清理冗余文件

- 删除旧版备份文件、测试脚本、临时记录和运行日志
- 删除散落的个人图片文件(已归档至 assets/faces/)
2026-02-27 22:12:39 +08:00

147 lines
5.0 KiB
Python

"""
小红书 AI 爆文生产工坊 V2.0
全自动工作台:灵感 -> 文案 -> 绘图 -> 发布 -> 运营
"""
import gradio as gr
import os
import re
import json
import time
import logging
import platform
import subprocess
import threading
import random
from datetime import datetime
from PIL import Image
import matplotlib
import matplotlib.pyplot as plt
from services.config_manager import ConfigManager, OUTPUT_DIR
from services.llm_service import LLMService
from services.sd_service import SDService, DEFAULT_NEGATIVE, FACE_IMAGE_PATH, SD_PRESET_NAMES, get_sd_preset, get_model_profile, get_model_profile_info, detect_model_profile, SD_MODEL_PROFILES
from services.mcp_client import MCPClient, get_mcp_client
from services.analytics_service import AnalyticsService
from ui.tab_create import build_tab
# ================= matplotlib 中文字体配置 =================
_font_candidates = ["Microsoft YaHei", "SimHei", "PingFang SC", "WenQuanYi Micro Hei"]
for _fn in _font_candidates:
try:
matplotlib.font_manager.findfont(_fn, fallback_to_default=False)
plt.rcParams["font.sans-serif"] = [_fn]
break
except Exception:
continue
plt.rcParams["axes.unicode_minus"] = False
# ================= 日志配置 =================
os.makedirs("logs", exist_ok=True)
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s [%(levelname)s] %(name)s: %(message)s",
handlers=[
logging.StreamHandler(),
logging.FileHandler("logs/autobot.log", encoding="utf-8"),
],
)
logger = logging.getLogger("autobot")
# 强制不走代理连接本地服务
os.environ["NO_PROXY"] = "127.0.0.1,localhost"
# ================= 全局服务初始化 =================
cfg = ConfigManager()
cfg.ensure_workspace()
mcp = get_mcp_client(cfg.get("mcp_url", "http://localhost:18060/mcp"))
analytics = AnalyticsService(OUTPUT_DIR)
# ================= 发布队列 =================
from services.publish_queue import (
PublishQueue, QueuePublisher,
STATUS_DRAFT, STATUS_APPROVED, STATUS_SCHEDULED, STATUS_PUBLISHING,
STATUS_PUBLISHED, STATUS_FAILED, STATUS_REJECTED, STATUS_LABELS,
)
pub_queue = PublishQueue(OUTPUT_DIR)
queue_publisher = QueuePublisher(pub_queue)
from services.connection import (
_get_llm_config, connect_llm, add_llm_provider, remove_llm_provider,
on_provider_selected, connect_sd, on_sd_model_change, 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,
)
from services.content import (
generate_copy, generate_images, one_click_export, publish_to_xhs,
)
from services.hotspot import (
_cache_lock, _set_cache, _get_cache, _fetch_and_cache, _pick_from_cache,
search_hotspots, analyze_and_suggest, generate_from_hotspot,
fetch_proactive_notes, on_proactive_note_selected,
)
from services.engagement import (
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,
)
from services.profile import _parse_profile_json, _parse_count, fetch_my_profile
from services.scheduler import (
_auto_log_append, _auto_log, _auto_running, _auto_thread,
_auto_comment_with_log, auto_comment_once,
_auto_like_with_log, auto_like_once,
_auto_favorite_with_log, auto_favorite_once,
_auto_publish_with_log, auto_publish_once,
_auto_reply_with_log, auto_reply_once,
_scheduler_next_times, _scheduler_loop,
start_scheduler, stop_scheduler, get_auto_log, get_scheduler_status,
_learn_running, _learn_scheduler_loop, start_learn_scheduler, stop_learn_scheduler,
analytics_collect_data, analytics_calculate_weights,
analytics_llm_deep_analysis, analytics_get_report, analytics_get_weighted_topics,
configure_analytics,
)
from services.queue_ops import (
generate_to_queue, 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,
configure as configure_queue_ops,
)
# 注入依赖
configure_analytics(analytics)
configure_queue_ops(pub_queue, queue_publisher, analytics, _auto_log_append)
from ui.app import build_app, _GRADIO_CSS
app = build_app(cfg, analytics)
if __name__ == "__main__":
logger.info("🍒 小红书 AI 爆文工坊 V2.0 启动中...")
# ---- Gradio 登录认证 ----
# 从配置或环境变量读取,默认用户名/密码: admin / admin123
_auth_user = os.environ.get("GRADIO_AUTH_USER", cfg.get("auth_user", "admin"))
_auth_pass = os.environ.get("GRADIO_AUTH_PASS", cfg.get("auth_pass", "admin123"))
app.launch(
server_name=os.environ.get("GRADIO_SERVER_NAME", "127.0.0.1"),
server_port=int(os.environ.get("GRADIO_SERVER_PORT", "7860")),
inbrowser=True,
share=False,
auth=(_auth_user, _auth_pass),
theme=gr.themes.Soft(),
css=_GRADIO_CSS,
)