404 lines
11 KiB
Bash
404 lines
11 KiB
Bash
|
|
#!/bin/bash
|
|||
|
|
# 飞书同步系统安装脚本
|
|||
|
|
|
|||
|
|
set -e
|
|||
|
|
|
|||
|
|
echo "========================================="
|
|||
|
|
echo "飞书小说章节自动同步系统安装"
|
|||
|
|
echo "========================================="
|
|||
|
|
|
|||
|
|
# 检查Python
|
|||
|
|
if ! command -v python3 &> /dev/null; then
|
|||
|
|
echo "❌ 需要 Python3,请先安装"
|
|||
|
|
exit 1
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
PYTHON_VERSION=$(python3 --version | cut -d' ' -f2)
|
|||
|
|
echo "✅ Python 版本: $PYTHON_VERSION"
|
|||
|
|
|
|||
|
|
# 检查目录
|
|||
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|||
|
|
echo "📁 脚本目录: $SCRIPT_DIR"
|
|||
|
|
|
|||
|
|
# 创建必要的目录
|
|||
|
|
echo "📁 创建目录结构..."
|
|||
|
|
mkdir -p "$SCRIPT_DIR/logs"
|
|||
|
|
mkdir -p "$SCRIPT_DIR/reports"
|
|||
|
|
mkdir -p "$SCRIPT_DIR/backups"
|
|||
|
|
mkdir -p "$SCRIPT_DIR/config"
|
|||
|
|
|
|||
|
|
echo "✅ 目录创建完成"
|
|||
|
|
|
|||
|
|
# 检查小说路径
|
|||
|
|
NOVEL_PATH="/root/.openclaw/workspace/tomato-novel/books/末日重生-开局囤货十亿物资"
|
|||
|
|
if [ ! -d "$NOVEL_PATH" ]; then
|
|||
|
|
echo "⚠️ 小说路径不存在: $NOVEL_PATH"
|
|||
|
|
read -p "是否继续安装? (y/n): " -n 1 -r
|
|||
|
|
echo
|
|||
|
|
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
|||
|
|
echo "❌ 安装取消"
|
|||
|
|
exit 1
|
|||
|
|
fi
|
|||
|
|
else
|
|||
|
|
echo "✅ 小说路径存在: $NOVEL_PATH"
|
|||
|
|
CHAPTERS_COUNT=$(find "$NOVEL_PATH/chapters" -name "*.md" | grep -v backup | grep -v report | grep -v fix | wc -l)
|
|||
|
|
echo "📊 发现 $CHAPTERS_COUNT 个章节文件"
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
# 安装Python依赖
|
|||
|
|
echo "📦 安装Python依赖..."
|
|||
|
|
if pip3 install watchdog --quiet; then
|
|||
|
|
echo "✅ watchdog 安装成功"
|
|||
|
|
else
|
|||
|
|
echo "⚠️ watchdog 安装失败,尝试其他方式..."
|
|||
|
|
python3 -m pip install watchdog --quiet
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
# 创建配置文件
|
|||
|
|
echo "⚙️ 创建配置文件..."
|
|||
|
|
cat > "$SCRIPT_DIR/config/sync_config.json" << EOF
|
|||
|
|
{
|
|||
|
|
"system": {
|
|||
|
|
"name": "feishu_sync_system",
|
|||
|
|
"version": "1.0.0",
|
|||
|
|
"install_date": "$(date '+%Y-%m-%d %H:%M:%S')"
|
|||
|
|
},
|
|||
|
|
"novel": {
|
|||
|
|
"name": "末日重生:开局囤货十亿物资",
|
|||
|
|
"path": "$NOVEL_PATH",
|
|||
|
|
"chapters_dir": "chapters",
|
|||
|
|
"target_chapters": 200,
|
|||
|
|
"current_chapters": $CHAPTERS_COUNT
|
|||
|
|
},
|
|||
|
|
"sync": {
|
|||
|
|
"batch_size": 5,
|
|||
|
|
"max_retries": 3,
|
|||
|
|
"retry_delay": 2,
|
|||
|
|
"rate_limit": 30
|
|||
|
|
},
|
|||
|
|
"monitoring": {
|
|||
|
|
"check_interval": 300,
|
|||
|
|
"alert_on_new": true,
|
|||
|
|
"alert_on_failure": true
|
|||
|
|
},
|
|||
|
|
"notifications": {
|
|||
|
|
"enabled": true,
|
|||
|
|
"channel": "feishu",
|
|||
|
|
"notify_on_success": true,
|
|||
|
|
"notify_on_failure": true
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
EOF
|
|||
|
|
|
|||
|
|
echo "✅ 配置文件创建完成"
|
|||
|
|
|
|||
|
|
# 设置脚本权限
|
|||
|
|
echo "🔧 设置脚本权限..."
|
|||
|
|
chmod +x "$SCRIPT_DIR/sync_chapters.py"
|
|||
|
|
chmod +x "$SCRIPT_DIR/monitor_new_chapters.py"
|
|||
|
|
chmod +x "$SCRIPT_DIR/install.sh"
|
|||
|
|
chmod +x "$SCRIPT_DIR/start.sh"
|
|||
|
|
chmod +x "$SCRIPT_DIR/stop.sh"
|
|||
|
|
|
|||
|
|
echo "✅ 脚本权限设置完成"
|
|||
|
|
|
|||
|
|
# 创建初始状态文件
|
|||
|
|
echo "📄 创建初始状态文件..."
|
|||
|
|
if [ -f "$SCRIPT_DIR/sync_state.json" ]; then
|
|||
|
|
echo "✅ 状态文件已存在"
|
|||
|
|
else
|
|||
|
|
cat > "$SCRIPT_DIR/sync_state.json" << EOF
|
|||
|
|
{
|
|||
|
|
"system": {
|
|||
|
|
"version": "1.0.0",
|
|||
|
|
"install_date": "$(date '+%Y-%m-%d %H:%M:%S')",
|
|||
|
|
"last_sync": null
|
|||
|
|
},
|
|||
|
|
"novel": {
|
|||
|
|
"name": "末日重生:开局囤货十亿物资",
|
|||
|
|
"path": "$NOVEL_PATH",
|
|||
|
|
"total_chapters": $CHAPTERS_COUNT
|
|||
|
|
},
|
|||
|
|
"sync": {
|
|||
|
|
"synced_chapters": {},
|
|||
|
|
"last_sync_time": null,
|
|||
|
|
"total_syncs": 0,
|
|||
|
|
"successful_syncs": 0,
|
|||
|
|
"failed_syncs": 0
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
EOF
|
|||
|
|
echo "✅ 初始状态文件创建完成"
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
# 创建服务文件(systemd)
|
|||
|
|
if [ -d "/etc/systemd/system" ]; then
|
|||
|
|
echo "🔧 创建 systemd 服务..."
|
|||
|
|
cat > "/tmp/feishu-sync.service" << EOF
|
|||
|
|
[Unit]
|
|||
|
|
Description=Feishu Novel Chapter Sync Service
|
|||
|
|
After=network.target
|
|||
|
|
|
|||
|
|
[Service]
|
|||
|
|
Type=simple
|
|||
|
|
User=root
|
|||
|
|
WorkingDirectory=$SCRIPT_DIR
|
|||
|
|
ExecStart=/usr/bin/python3 $SCRIPT_DIR/monitor_new_chapters.py
|
|||
|
|
Restart=always
|
|||
|
|
RestartSec=10
|
|||
|
|
StandardOutput=append:$SCRIPT_DIR/logs/service.log
|
|||
|
|
StandardError=append:$SCRIPT_DIR/logs/service_error.log
|
|||
|
|
|
|||
|
|
[Install]
|
|||
|
|
WantedBy=multi-user.target
|
|||
|
|
EOF
|
|||
|
|
|
|||
|
|
sudo mv /tmp/feishu-sync.service /etc/systemd/system/
|
|||
|
|
echo "✅ systemd 服务文件创建完成"
|
|||
|
|
|
|||
|
|
echo "🔄 重新加载 systemd..."
|
|||
|
|
sudo systemctl daemon-reload
|
|||
|
|
echo "✅ systemd 重新加载完成"
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
# 创建启动脚本
|
|||
|
|
echo "🚀 创建启动脚本..."
|
|||
|
|
cat > "$SCRIPT_DIR/start.sh" << 'EOF'
|
|||
|
|
#!/bin/bash
|
|||
|
|
# 启动飞书同步系统
|
|||
|
|
|
|||
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|||
|
|
|
|||
|
|
echo "========================================="
|
|||
|
|
echo "启动飞书小说章节同步系统"
|
|||
|
|
echo "========================================="
|
|||
|
|
|
|||
|
|
# 检查Python
|
|||
|
|
if ! command -v python3 &> /dev/null; then
|
|||
|
|
echo "❌ 需要 Python3"
|
|||
|
|
exit 1
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
# 检查小说路径
|
|||
|
|
if [ ! -f "$SCRIPT_DIR/config/sync_config.json" ]; then
|
|||
|
|
echo "❌ 配置文件不存在,请先运行 install.sh"
|
|||
|
|
exit 1
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
# 检查是否已经在运行
|
|||
|
|
if ps aux | grep "monitor_new_chapters.py" | grep -v grep > /dev/null; then
|
|||
|
|
echo "⚠️ 监控脚本已经在运行"
|
|||
|
|
PID=$(ps aux | grep "monitor_new_chapters.py" | grep -v grep | awk '{print $2}')
|
|||
|
|
echo "📊 进程ID: $PID"
|
|||
|
|
else
|
|||
|
|
echo "🚀 启动监控脚本..."
|
|||
|
|
nohup python3 "$SCRIPT_DIR/monitor_new_chapters.py" > "$SCRIPT_DIR/logs/monitor.log" 2>&1 &
|
|||
|
|
MONITOR_PID=$!
|
|||
|
|
echo $MONITOR_PID > "$SCRIPT_DIR/monitor.pid"
|
|||
|
|
echo "✅ 监控脚本已启动,PID: $MONITOR_PID"
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
# 立即执行一次同步
|
|||
|
|
echo "🔄 执行首次同步..."
|
|||
|
|
python3 "$SCRIPT_DIR/sync_chapters.py"
|
|||
|
|
|
|||
|
|
echo "========================================="
|
|||
|
|
echo "🎉 飞书同步系统启动完成"
|
|||
|
|
echo "📁 日志目录: $SCRIPT_DIR/logs"
|
|||
|
|
echo "📊 状态文件: $SCRIPT_DIR/sync_state.json"
|
|||
|
|
echo "📄 监控日志: $SCRIPT_DIR/logs/monitor.log"
|
|||
|
|
echo "========================================="
|
|||
|
|
|
|||
|
|
# 显示状态
|
|||
|
|
echo "📊 当前状态:"
|
|||
|
|
python3 -c "
|
|||
|
|
import json
|
|||
|
|
try:
|
|||
|
|
with open('$SCRIPT_DIR/sync_state.json', 'r') as f:
|
|||
|
|
state = json.load(f)
|
|||
|
|
synced = len(state.get('sync', {}).get('synced_chapters', {}))
|
|||
|
|
total = state.get('novel', {}).get('total_chapters', 0)
|
|||
|
|
last_sync = state.get('sync', {}).get('last_sync_time', '从未')
|
|||
|
|
print(f'已同步章节: {synced}/{total}')
|
|||
|
|
print(f'上次同步: {last_sync}')
|
|||
|
|
except:
|
|||
|
|
print('状态文件读取失败')
|
|||
|
|
"
|
|||
|
|
EOF
|
|||
|
|
|
|||
|
|
# 创建停止脚本
|
|||
|
|
cat > "$SCRIPT_DIR/stop.sh" << 'EOF'
|
|||
|
|
#!/bin/bash
|
|||
|
|
# 停止飞书同步系统
|
|||
|
|
|
|||
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|||
|
|
|
|||
|
|
echo "========================================="
|
|||
|
|
echo "停止飞书小说章节同步系统"
|
|||
|
|
echo "========================================="
|
|||
|
|
|
|||
|
|
# 停止监控脚本
|
|||
|
|
if [ -f "$SCRIPT_DIR/monitor.pid" ]; then
|
|||
|
|
MONITOR_PID=$(cat "$SCRIPT_DIR/monitor.pid")
|
|||
|
|
if kill $MONITOR_PID 2>/dev/null; then
|
|||
|
|
echo "✅ 监控脚本已停止,PID: $MONITOR_PID"
|
|||
|
|
rm "$SCRIPT_DIR/monitor.pid"
|
|||
|
|
else
|
|||
|
|
echo "⚠️ 监控脚本不存在或已停止"
|
|||
|
|
fi
|
|||
|
|
else
|
|||
|
|
echo "⚠️ 未找到监控脚本PID文件"
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
# 检查是否还有相关进程
|
|||
|
|
PIDS=$(ps aux | grep -E "(monitor_new_chapters|sync_chapters)" | grep -v grep | awk '{print $2}')
|
|||
|
|
if [ -n "$PIDS" ]; then
|
|||
|
|
echo "🛑 停止所有相关进程..."
|
|||
|
|
for PID in $PIDS; do
|
|||
|
|
kill $PID 2>/dev/null && echo "✅ 停止进程: $PID"
|
|||
|
|
done
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
# 停止systemd服务(如果存在)
|
|||
|
|
if systemctl is-active --quiet feishu-sync 2>/dev/null; then
|
|||
|
|
echo "🛑 停止 systemd 服务..."
|
|||
|
|
sudo systemctl stop feishu-sync
|
|||
|
|
echo "✅ systemd 服务已停止"
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
echo "========================================="
|
|||
|
|
echo "🛑 飞书同步系统已停止"
|
|||
|
|
echo "========================================="
|
|||
|
|
EOF
|
|||
|
|
|
|||
|
|
chmod +x "$SCRIPT_DIR/start.sh"
|
|||
|
|
chmod +x "$SCRIPT_DIR/stop.sh"
|
|||
|
|
|
|||
|
|
echo "✅ 启动/停止脚本创建完成"
|
|||
|
|
|
|||
|
|
# 创建定时任务配置
|
|||
|
|
echo "⏰ 创建定时任务配置..."
|
|||
|
|
cat > "$SCRIPT_DIR/setup_cron.sh" << 'EOF'
|
|||
|
|
#!/bin/bash
|
|||
|
|
# 设置定时任务
|
|||
|
|
|
|||
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|||
|
|
|
|||
|
|
echo "设置定时任务..."
|
|||
|
|
|
|||
|
|
# 备份现有crontab
|
|||
|
|
CRON_BACKUP="$SCRIPT_DIR/crontab.backup.$(date +%Y%m%d%H%M%S)"
|
|||
|
|
crontab -l > "$CRON_BACKUP" 2>/dev/null || true
|
|||
|
|
echo "✅ 现有crontab已备份到: $CRON_BACKUP"
|
|||
|
|
|
|||
|
|
# 添加新的定时任务
|
|||
|
|
(crontab -l 2>/dev/null | grep -v "feishu_sync_system"; echo "
|
|||
|
|
# =========================================
|
|||
|
|
# 飞书小说章节同步系统定时任务
|
|||
|
|
# =========================================
|
|||
|
|
|
|||
|
|
# 每天凌晨2点全量同步
|
|||
|
|
0 2 * * * cd $SCRIPT_DIR && python3 sync_chapters.py >> $SCRIPT_DIR/logs/cron_daily.log 2>&1
|
|||
|
|
|
|||
|
|
# 每小时检查新章节
|
|||
|
|
0 * * * * cd $SCRIPT_DIR && python3 monitor_new_chapters.py --check-only >> $SCRIPT_DIR/logs/cron_hourly.log 2>&1
|
|||
|
|
|
|||
|
|
# 每周一上午9点生成报告
|
|||
|
|
0 9 * * 1 cd $SCRIPT_DIR && python3 sync_chapters.py --report-only >> $SCRIPT_DIR/logs/cron_weekly.log 2>&1
|
|||
|
|
|
|||
|
|
# =========================================
|
|||
|
|
") | crontab -
|
|||
|
|
|
|||
|
|
echo "✅ 定时任务设置完成"
|
|||
|
|
echo "📊 当前定时任务:"
|
|||
|
|
crontab -l | grep -A 10 "飞书小说章节同步系统"
|
|||
|
|
EOF
|
|||
|
|
|
|||
|
|
chmod +x "$SCRIPT_DIR/setup_cron.sh"
|
|||
|
|
|
|||
|
|
echo "✅ 定时任务配置脚本创建完成"
|
|||
|
|
|
|||
|
|
# 创建测试脚本
|
|||
|
|
cat > "$SCRIPT_DIR/test_sync.sh" << 'EOF'
|
|||
|
|
#!/bin/bash
|
|||
|
|
# 测试同步功能
|
|||
|
|
|
|||
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|||
|
|
|
|||
|
|
echo "🧪 测试飞书同步系统..."
|
|||
|
|
echo "========================================="
|
|||
|
|
|
|||
|
|
# 测试Python环境
|
|||
|
|
echo "1. 测试Python环境..."
|
|||
|
|
python3 --version
|
|||
|
|
if [ $? -eq 0 ]; then
|
|||
|
|
echo "✅ Python环境正常"
|
|||
|
|
else
|
|||
|
|
echo "❌ Python环境异常"
|
|||
|
|
exit 1
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
# 测试配置文件
|
|||
|
|
echo "2. 测试配置文件..."
|
|||
|
|
if [ -f "$SCRIPT_DIR/config/sync_config.json" ]; then
|
|||
|
|
echo "✅ 配置文件存在"
|
|||
|
|
python3 -m json.tool "$SCRIPT_DIR/config/sync_config.json" > /dev/null 2>&1
|
|||
|
|
if [ $? -eq 0 ]; then
|
|||
|
|
echo "✅ 配置文件格式正确"
|
|||
|
|
else
|
|||
|
|
echo "❌ 配置文件格式错误"
|
|||
|
|
fi
|
|||
|
|
else
|
|||
|
|
echo "❌ 配置文件不存在"
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
# 测试小说路径
|
|||
|
|
echo "3. 测试小说路径..."
|
|||
|
|
CONFIG_PATH=$(python3 -c "
|
|||
|
|
import json
|
|||
|
|
with open('$SCRIPT_DIR/config/sync_config.json', 'r') as f:
|
|||
|
|
config = json.load(f)
|
|||
|
|
print(config['novel']['path'])
|
|||
|
|
")
|
|||
|
|
if [ -d "$CONFIG_PATH" ]; then
|
|||
|
|
echo "✅ 小说路径存在: $CONFIG_PATH"
|
|||
|
|
CHAPTERS=$(find "$CONFIG_PATH/chapters" -name "*.md" 2>/dev/null | wc -l)
|
|||
|
|
echo "📊 找到 $CHAPTERS 个章节文件"
|
|||
|
|
else
|
|||
|
|
echo "❌ 小说路径不存在: $CONFIG_PATH"
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
# 测试同步脚本
|
|||
|
|
echo "4. 测试同步脚本..."
|
|||
|
|
python3 "$SCRIPT_DIR/sync_chapters.py" --test
|
|||
|
|
if [ $? -eq 0 ]; then
|
|||
|
|
echo "✅ 同步脚本测试通过"
|
|||
|
|
else
|
|||
|
|
echo "❌ 同步脚本测试失败"
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
echo "========================================="
|
|||
|
|
echo "🧪 测试完成"
|
|||
|
|
echo "运行 ./start.sh 启动系统"
|
|||
|
|
echo "运行 ./stop.sh 停止系统"
|
|||
|
|
EOF
|
|||
|
|
|
|||
|
|
chmod +x "$SCRIPT_DIR/test_sync.sh"
|
|||
|
|
|
|||
|
|
echo "✅ 测试脚本创建完成"
|
|||
|
|
|
|||
|
|
echo "========================================="
|
|||
|
|
echo "🎉 飞书同步系统安装完成!"
|
|||
|
|
echo "========================================="
|
|||
|
|
echo ""
|
|||
|
|
echo "📋 下一步操作:"
|
|||
|
|
echo "1. 运行测试: ./test_sync.sh"
|
|||
|
|
echo "2. 启动系统: ./start.sh"
|
|||
|
|
echo "3. 设置定时任务: ./setup_cron.sh"
|
|||
|
|
echo "4. 查看日志: tail -f logs/monitor.log"
|
|||
|
|
echo ""
|
|||
|
|
echo "📁 系统目录: $SCRIPT_DIR"
|
|||
|
|
echo "📄 配置文件: $SCRIPT_DIR/config/sync_config.json"
|
|||
|
|
echo "📊 状态文件: $SCRIPT_DIR/sync_state.json"
|
|||
|
|
echo "📝 日志目录: $SCRIPT_DIR/logs/"
|
|||
|
|
echo "========================================="
|