- 新增 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/)
147 lines
5.0 KiB
Python
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,
|
|
)
|