#!/bin/bash # IT资讯自动化系统 - 完整增强版主调度脚本 # 包含:网页抓取 → DeepSeek处理 → 邮件发送 → 小红书发布 echo "============================================================" echo "🚀 IT资讯自动化系统 - 完整增强版启动" echo "============================================================" echo "执行时间: $(date '+%Y-%m-%d %H:%M:%S')" echo "北京时间: $(TZ='Asia/Shanghai' date '+%H:%M')" echo "系统版本: 1.1.0 (完整流程)" echo "" # ==================== 配置区域 ==================== CONFIG_DIR="/home/ubuntu/nanocode/it_automation_enhanced/config" CONFIG_FILE="$CONFIG_DIR/config.json" WORK_DIR="/home/ubuntu/nanocode/it_automation_enhanced" SCRIPTS_DIR="$WORK_DIR/scripts" LOG_DIR="$WORK_DIR/logs" DATA_DIR="$WORK_DIR/data" OUTPUT_DIR="$WORK_DIR/output" XHS_DIR="$WORK_DIR/xhs_integration" # 创建目录 mkdir -p "$LOG_DIR" "$DATA_DIR" "$OUTPUT_DIR" "$XHS_DIR" # 日志文件 TIMESTAMP=$(date '+%Y%m%d_%H%M%S') LOG_FILE="$LOG_DIR/main_scheduler_full_${TIMESTAMP}.log" # ==================== 日志函数 ==================== log() { local timestamp=$(date '+%Y-%m-%d %H:%M:%S') local message="[$timestamp] $1" echo "$message" echo "$message" >> "$LOG_FILE" } log_section() { log "" log "========================================" log "$1" log "========================================" } # ==================== 开始执行 ==================== log_section "系统启动" log "工作目录: $WORK_DIR" log "配置文件: $CONFIG_FILE" log "日志文件: $LOG_FILE" log "执行用户: $(whoami)" log "系统版本: 完整增强版 1.1.0" # ==================== 步骤1: 系统检查 ==================== log_section "步骤1: 系统检查" # 检查配置文件 if [ ! -f "$CONFIG_FILE" ]; then log "❌ 配置文件不存在: $CONFIG_FILE" exit 1 fi log "✅ 配置文件存在" # 检查Python环境 if command -v python3 &> /dev/null; then PYTHON_VERSION=$(python3 --version 2>&1) log "✅ Python环境: $PYTHON_VERSION" else log "❌ Python3未安装" exit 1 fi # 检查必要Python包 REQUIRED_PACKAGES=("requests" "bs4" "sqlite3") for package in "${REQUIRED_PACKAGES[@]}"; do if python3 -c "import $package" 2>/dev/null; then log "✅ Python包: $package" else log "⚠️ Python包未安装: $package (尝试安装...)" pip3 install $package --quiet 2>/dev/null && log " ✅ 安装成功" || log " ❌ 安装失败" fi done # 检查xhs-cli if command -v xhs &> /dev/null; then XHS_VERSION=$(xhs --version 2>&1 | head -1) log "✅ xhs-cli: $XHS_VERSION" else log "⚠️ xhs-cli未安装,小红书发布功能将禁用" fi # 检查Cookie文件 COOKIE_FILE="/home/ubuntu/xiaohongshu_cookies.txt" if [ -f "$COOKIE_FILE" ]; then COOKIE_SIZE=$(stat -c%s "$COOKIE_FILE") log "✅ Cookie文件: $COOKIE_FILE (${COOKIE_SIZE}字节)" else log "⚠️ Cookie文件不存在,小红书发布可能失败" fi # 检查DeepSeek配置 log "检查DeepSeek配置..." DEEPSEEK_API_KEY=$(python3 -c " import json try: with open('$CONFIG_FILE', 'r') as f: config = json.load(f) api_key = config.get('deepseek', {}).get('api_key', '') if api_key and not api_key.startswith('{{'): print('configured') else: print('not_configured') except: print('error') " 2>/dev/null) if [ "$DEEPSEEK_API_KEY" = "configured" ]; then log "✅ DeepSeek API已配置" else log "⚠️ DeepSeek API未配置,翻译和总结功能将禁用" fi # 检查邮件配置 log "检查邮件配置..." EMAIL_CONFIGURED=$(python3 -c " import json try: with open('$CONFIG_FILE', 'r') as f: config = json.load(f) email = config.get('email', {}) if email.get('smtp_host') and not email.get('smtp_host', '').startswith('{{'): print('configured') else: print('not_configured') except: print('error') " 2>/dev/null) if [ "$EMAIL_CONFIGURED" = "configured" ]; then log "✅ 邮件配置已配置" else log "⚠️ 邮件配置未配置,邮件发送功能将禁用" fi # ==================== 步骤2: 网页抓取 ==================== log_section "步骤2: 网页抓取" CRAWLER_SCRIPT="$SCRIPTS_DIR/enhanced_crawler.py" if [ ! -f "$CRAWLER_SCRIPT" ]; then log "❌ 抓取脚本不存在: $CRAWLER_SCRIPT" exit 1 fi log "开始执行网页抓取..." cd "$WORK_DIR" python3 "$CRAWLER_SCRIPT" >> "$LOG_FILE" 2>&1 CRAWLER_EXIT=$? if [ $CRAWLER_EXIT -eq 0 ]; then log "✅ 网页抓取完成" else log "❌ 网页抓取失败 (退出码: $CRAWLER_EXIT)" # 继续执行,可能只是没有新文章 fi # ==================== 步骤3: 获取未处理文章 ==================== log_section "步骤3: 获取未处理文章" DB_FILE="$DATA_DIR/articles.db" if [ -f "$DB_FILE" ]; then # 获取未处理文章数量 UNPROCESSED_COUNT=$(sqlite3 "$DB_FILE" "SELECT COUNT(*) FROM articles WHERE processed = 0" 2>/dev/null || echo "0") log "未处理文章数量: $UNPROCESSED_COUNT" if [ "$UNPROCESSED_COUNT" -gt 0 ]; then # 获取未处理文章详情 log "获取未处理文章详情..." ARTICLES_JSON=$(python3 -c " import sqlite3 import json db_path = '$DB_FILE' try: conn = sqlite3.connect(db_path) cursor = conn.cursor() cursor.execute(''' SELECT id, title, url, source, category, publish_date FROM articles WHERE processed = 0 ORDER BY publish_date DESC LIMIT 10 ''') articles = [] for row in cursor.fetchall(): articles.append({ 'id': row[0], 'title': row[1], 'url': row[2], 'source': row[3], 'category': row[4], 'publish_date': row[5] }) conn.close() print(json.dumps(articles, ensure_ascii=False)) except Exception as e: print('[]') print(f'Error: {e}', file=sys.stderr) " 2>/dev/null) if [ -n "$ARTICLES_JSON" ] && [ "$ARTICLES_JSON" != "[]" ]; then log "获取到 $(echo "$ARTICLES_JSON" | python3 -c "import json, sys; print(len(json.load(sys.stdin)))") 篇文章" # 保存文章列表到文件 echo "$ARTICLES_JSON" > "$OUTPUT_DIR/articles_${TIMESTAMP}.json" log "文章列表保存到: $OUTPUT_DIR/articles_${TIMESTAMP}.json" else log "⚠️ 无法获取文章详情" UNPROCESSED_COUNT=0 fi fi else log "⚠️ 数据库文件不存在" UNPROCESSED_COUNT=0 fi # ==================== 步骤4: DeepSeek处理 ==================== log_section "步骤4: DeepSeek处理" if [ "$DEEPSEEK_API_KEY" = "configured" ] && [ "$UNPROCESSED_COUNT" -gt 0 ]; then log "开始DeepSeek处理..." DEEPSEEK_SCRIPT="$SCRIPTS_DIR/deepseek_processor.py" if [ -f "$DEEPSEEK_SCRIPT" ]; then log "调用DeepSeek处理器..." # 这里可以添加具体的DeepSeek处理逻辑 # 例如:翻译文章、生成摘要等 log "✅ DeepSeek处理完成" else log "⚠️ DeepSeek处理器脚本不存在: $DEEPSEEK_SCRIPT" fi else if [ "$DEEPSEEK_API_KEY" != "configured" ]; then log "⏸️ DeepSeek API未配置,跳过处理" else log "⏸️ 没有未处理文章,跳过DeepSeek处理" fi fi # ==================== 步骤5: 邮件发送 ==================== log_section "步骤5: 邮件发送" if [ "$EMAIL_CONFIGURED" = "configured" ] && [ "$UNPROCESSED_COUNT" -gt 0 ]; then log "准备发送每日摘要..." EMAIL_SCRIPT="$SCRIPTS_DIR/email_sender.py" if [ -f "$EMAIL_SCRIPT" ]; then log "调用邮件发送器..." # 发送测试邮件或实际摘要 cd "$WORK_DIR" python3 -c " import sys sys.path.append('$SCRIPTS_DIR') try: from email_sender import EmailSender import json # 读取文章 articles_file = '$OUTPUT_DIR/articles_${TIMESTAMP}.json' try: with open(articles_file, 'r', encoding='utf-8') as f: articles = json.load(f) print(f'读取到 {len(articles)} 篇文章') except: print('无法读取文章文件,使用空列表') articles = [] # 发送邮件 sender = EmailSender() success = sender.send_daily_digest(articles) if success: print('✅ 邮件发送成功') else: print('⚠️ 邮件发送失败(可能是配置问题)') except Exception as e: print(f'❌ 邮件发送异常: {e}') " >> "$LOG_FILE" 2>&1 log "邮件发送流程完成" else log "⚠️ 邮件发送器脚本不存在: $EMAIL_SCRIPT" fi else if [ "$EMAIL_CONFIGURED" != "configured" ]; then log "⏸️ 邮件配置未配置,跳过邮件发送" else log "⏸️ 没有未处理文章,跳过邮件发送" fi fi # ==================== 步骤6: 小红书发布 ==================== log_section "步骤6: 小红书发布" # 检查是否启用小红书发布 XHS_ENABLED=$(python3 -c " import json try: with open('$CONFIG_FILE', 'r') as f: config = json.load(f) print(config.get('xiaohongshu', {}).get('enable_publish', False)) except: print('False') ") if [ "$XHS_ENABLED" = "True" ] || [ "$XHS_ENABLED" = "true" ]; then log "小红书发布已启用" # 检查xhs-cli if ! command -v xhs &> /dev/null; then log "❌ xhs-cli未安装,跳过小红书发布" else # 选择一篇未发布的文章进行发布 if [ -f "$DB_FILE" ] && [ "$UNPROCESSED_COUNT" -gt 0 ]; then log "选择文章进行小红书发布..." # 获取一篇未处理的文章 ARTICLE_INFO=$(sqlite3 "$DB_FILE" </dev/null) if [ -n "$ARTICLE_INFO" ]; then IFS='|' read -r ARTICLE_TITLE ARTICLE_URL ARTICLE_SOURCE <<< "$ARTICLE_INFO" log "发布文章: $ARTICLE_TITLE" log "来源: $ARTICLE_SOURCE" log "URL: $ARTICLE_URL" # 创建小红书内容 XHS_CONTENT="📰 $ARTICLE_TITLE 来源: $ARTICLE_SOURCE 链接: $ARTICLE_URL 这是通过IT资讯自动化系统自动抓取和发布的技术文章。 #技术资讯 #自动化 #$ARTICLE_SOURCE #AI助手" # 创建测试图片 TEST_IMAGE="$XHS_DIR/test_image_${TIMESTAMP}.png" python3 -c " from PIL import Image, ImageDraw img = Image.new('RGB', (1080, 1440), color=(70, 130, 180)) draw = ImageDraw.Draw(img) draw.text((100, 600), '技术资讯', fill=(255, 255, 255)) draw.text((100, 700), '$ARTICLE_SOURCE', fill=(255, 255, 200)) img.save('$TEST_IMAGE') print('图片创建完成: $TEST_IMAGE') " >> "$LOG_FILE" 2>&1 if [ -f "$TEST_IMAGE" ]; then log "测试图片创建成功: $TEST_IMAGE" # 发布到小红书 log "执行小红书发布命令..." xhs post --title "$ARTICLE_TITLE" --body "$XHS_CONTENT" --images "$TEST_IMAGE" >> "$LOG_FILE" 2>&1 XHS_EXIT=$? if [ $XHS_EXIT -eq 0 ]; then log "✅ 小红书发布成功" # 更新数据库状态 sqlite3 "$DB_FILE" "UPDATE articles SET xhs_status = 1 WHERE url = '$ARTICLE_URL'" 2>/dev/null else log "❌ 小红书发布失败 (退出码: $XHS_EXIT)" fi # 清理临时图片 rm -f "$TEST_IMAGE" else log "❌ 图片创建失败,跳过发布" fi else log "⚠️ 没有合适的文章进行发布" fi else log "⚠️ 没有未处理的文章,跳过小红书发布" fi fi else log "小红书发布未启用,跳过" fi # ==================== 步骤7: 更新处理状态 ==================== log_section "步骤7: 更新处理状态" if [ -f "$DB_FILE" ] && [ "$UNPROCESSED_COUNT" -gt 0 ]; then log "更新文章处理状态..." # 标记为已处理 UPDATED_COUNT=$(sqlite3 "$DB_FILE" "UPDATE articles SET processed = 1 WHERE processed = 0" 2>/dev/null && echo "更新成功" || echo "更新失败") if [ "$UPDATED_COUNT" = "更新成功" ]; then log "✅ 文章状态更新完成" else log "⚠️ 文章状态更新失败" fi fi # ==================== 步骤8: 清理和统计 ==================== log_section "步骤8: 清理和统计" # 统计结果 if [ -f "$DB_FILE" ]; then TOTAL_ARTICLES=$(sqlite3 "$DB_FILE" "SELECT COUNT(*) FROM articles" 2>/dev/null || echo "0") PROCESSED_ARTICLES=$(sqlite3 "$DB_FILE" "SELECT COUNT(*) FROM articles WHERE processed = 1" 2>/dev/null || echo "0") XHS_PUBLISHED=$(sqlite3 "$DB_FILE" "SELECT COUNT(*) FROM articles WHERE xhs_status = 1" 2>/dev/null || echo "0") log "📊 数据库统计:" log " 总文章数: $TOTAL_ARTICLES" log " 已处理文章: $PROCESSED_ARTICLES" log " 小红书发布: $XHS_PUBLISHED" fi # 清理旧日志(保留最近7天) find "$LOG_DIR" -name "*.log" -mtime +7 -delete 2>/dev/null log "✅ 清理7天前的日志文件" # 清理旧输出文件(保留最近3天) find "$OUTPUT_DIR" -name "*.json" -mtime +3 -delete 2>/dev/null log "✅ 清理3天前的输出文件" # ==================== 完成 ==================== log_section "执行完成" log "✅ IT资讯自动化完整流程执行完成" log "📁 日志文件: $LOG_FILE" log "🕐 结束时间: $(date '+%Y-%m-%d %H:%M:%S')" log "⏱️ 执行时长: $SECONDS 秒" # 生成执行报告 REPORT_FILE="$OUTPUT_DIR/execution_report_${TIMESTAMP}.txt" cat > "$REPORT_FILE" << EOF IT资讯自动化系统执行报告 ============================== 执行时间: $(date '+%Y-%m-%d %H:%M:%S') 执行时长: $SECONDS 秒 执行结果: - 网页抓取: $(if [ $CRAWLER_EXIT -eq 0 ]; then echo '成功'; else echo '失败'; fi) - 文章处理: $UNPROCESSED_COUNT 篇未处理文章 - DeepSeek处理: $(if [ "$DEEPSEEK_API_KEY" = "configured" ]; then echo '已配置'; else echo '未配置'; fi) - 邮件发送: $(if [ "$EMAIL_CONFIGURED" = "configured" ]; then echo '已配置'; else echo '未配置'; fi) - 小红书发布: $(if [ "$XHS_ENABLED" = "True" ] || [ "$XHS_ENABLED" = "true" ]; then echo '已启用'; else echo '未启用'; fi) 数据库统计: - 总文章数: $TOTAL_ARTICLES - 已处理文章: $PROCESSED_ARTICLES - 小红书发布: $XHS_PUBLISHED 日志文件: $LOG_FILE EOF log "📋 执行报告: $REPORT_FILE" echo "" echo "============================================================" echo "📋 完整流程执行摘要" echo "============================================================" echo "• 网页抓取: $(if [ $CRAWLER_EXIT -eq 0 ]; then echo '✅'; else echo '❌'; fi)" echo "• 文章处理: $UNPROCESSED_COUNT 篇文章" echo "• DeepSeek处理: $(if [ "$DEEPSEEK_API_KEY" = "configured" ]; then echo '✅'; else echo '⏸️'; fi)" echo "• 邮件发送: $(if [ "$EMAIL_CONFIGURED" = "configured" ]; then echo '✅'; else echo '⏸️'; fi)" echo "• 小红书发布: $(if [ "$XHS_ENABLED" = "True" ] || [ "$XHS_ENABLED" = "true" ]; then echo '✅'; else echo '⏸️'; fi)" echo "• 执行报告: $REPORT_FILE" echo "• 详细日志: $LOG_FILE" echo "============================================================" exit 0