- 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"
146 lines
4.9 KiB
Python
146 lines
4.9 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 config_manager import ConfigManager, OUTPUT_DIR
|
|
from llm_service import LLMService
|
|
from 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 mcp_client import MCPClient, get_mcp_client
|
|
from 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
|
|
|
|
# ================= 日志配置 =================
|
|
|
|
logging.basicConfig(
|
|
level=logging.INFO,
|
|
format="%(asctime)s [%(levelname)s] %(name)s: %(message)s",
|
|
handlers=[
|
|
logging.StreamHandler(),
|
|
logging.FileHandler("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 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,
|
|
)
|