更新: 2026年03月30日 13:07:45

This commit is contained in:
唐天洛 2026-03-30 13:07:45 +08:00
parent 3c1564967e
commit 2b26f99b47
8 changed files with 1761 additions and 0 deletions

20
.gitattributes vendored Normal file
View File

@ -0,0 +1,20 @@
# Git属性配置
*.md text eol=lf
*.sh text eol=lf
*.py text eol=lf
# 二进制文件
*.pdf binary
*.doc binary
*.docx binary
*.zip binary
*.png binary
*.jpg binary
# 自动检测换行符
* text=auto
# 排除文件
.gitignore export-ignore
.gitattributes export-ignore
README.md export-ignore

63
.gitignore vendored Normal file
View File

@ -0,0 +1,63 @@
# 临时文件
*.tmp
*.log
*.bak
*.swp
*.swo
# 系统文件
.DS_Store
Thumbs.db
desktop.ini
# 编辑器文件
.vscode/
.idea/
*.code-workspace
# 环境配置
.env
.env.local
.env.development
.env.production
*.key
*.pem
*.cert
# 依赖文件
node_modules/
__pycache__/
*.pyc
*.pyo
# 构建输出
dist/
build/
target/
*.exe
*.dll
# 日志文件
logs/
*.log
# 备份文件
*.backup
*.old
*~
# 大文件
*.zip
*.rar
*.7z
*.tar.gz
# 数据文件
*.db
*.sqlite
*.sqlite3
# 小说项目特定
backups/
temp/
drafts/

355
INSTALL.md Normal file
View File

@ -0,0 +1,355 @@
# 《末日重生》项目定时同步系统安装指南
## 🎯 系统概述
为《末日重生-开局囤货十亿物资》项目提供完整的Git版本管理和定时同步系统包含
- 🔄 **自动提交**:检测更改并自动提交
- 🏷️ **版本标签**:自动创建语义化版本标签
- 📦 **定时备份**:按计划备份项目数据
- 📊 **状态报告**:生成详细的项目状态报告
- ⏰ **Cron定时任务**:自动执行所有任务
- 📈 **健康监控**:监控系统运行状态
## 📁 已创建的文件结构
```
末日重生_囤货/
├── .gitattributes # Git文件属性配置
├── .gitignore # Git忽略文件配置
├── tools/
│ ├── git_version_manager.sh # Git版本管理主脚本
│ └── schedule_manager.py # 定时任务管理系统
├── config/
│ └── cron_schedule.json # 定时任务配置
├── backups/ # 备份文件存储
├── logs/ # 系统日志文件
├── progress/ # 进度报告文件
└── INSTALL.md # 本安装指南
```
## 🚀 快速安装
### 方法一:一键安装(推荐)
```bash
cd /root/.openclaw/workspace/projects/末日重生_囤货
# 1. 测试系统健康
./tools/schedule_manager.py health
# 2. 安装Cron定时任务
./tools/schedule_manager.py install
# 3. 显示系统仪表板
./tools/schedule_manager.py dashboard
```
### 方法二:手动安装
```bash
# 1. 设置脚本权限
chmod +x tools/git_version_manager.sh
chmod +x tools/schedule_manager.py
# 2. 创建必要的目录
mkdir -p backups logs progress
# 3. 测试Git版本管理
./tools/git_version_manager.sh status
# 4. 手动创建Cron任务
echo "*/30 * * * * cd $(pwd) && ./tools/git_version_manager.sh commit" | crontab -
```
## 🔧 配置说明
### 定时任务配置config/cron_schedule.json
```json
{
"定时同步配置": {
"自动提交": {
"启用": true,
"间隔": "30分钟"
},
"版本标签": {
"启用": true,
"触发条件": "每10次提交自动创建标签"
},
"远程同步": {
"启用": true,
"间隔": "1小时"
},
"自动备份": {
"启用": true,
"时间": "每日凌晨3点"
}
}
}
```
### Git版本管理配置
系统会自动跟踪:
- 章节数量变化
- 字数统计
- 提交历史
- 版本标签
- 同步状态
## 📊 系统功能
### 1. 自动提交每30分钟
- 检测未提交的更改
- 自动添加所有更改
- 生成包含时间戳的提交信息
- 自动提交到本地仓库
### 2. 版本标签管理
- 每10次提交自动创建新版本
- 语义化版本号v1.0.0格式)
- 包含章节和字数信息的标签描述
- 标签同步到远程仓库
### 3. 定时备份每天凌晨3点
- **完整备份**:包含所有项目文件
- **章节备份**:仅备份章节内容
- **Git包备份**可移植的Git仓库
- **自动清理**保留7天内的备份
### 4. 状态报告每天凌晨1点
- 章节统计和字数统计
- Git提交历史和版本信息
- 番茄平台适配情况
- 系统健康状态检查
### 5. 远程同步每1小时
- 自动拉取远程最新更改
- 推送本地提交到Gitea
- 同步版本标签
- 失败重试机制
## 🖥️ 使用方法
### 命令行工具
```bash
# 1. 显示系统仪表板
./tools/schedule_manager.py dashboard
# 2. 执行自动提交
./tools/git_version_manager.sh commit
# 3. 创建版本标签
./tools/git_version_manager.sh tag
# 4. 同步到远程仓库
./tools/git_version_manager.sh sync
# 5. 创建备份
./tools/schedule_manager.py backup --type full
# 6. 生成状态报告
./tools/git_version_manager.sh report
# 7. 检查系统健康
./tools/schedule_manager.py health
# 8. 显示交互式菜单
./tools/git_version_manager.sh menu
```
### 一键全流程
```bash
# 执行完整的版本管理流程
./tools/git_version_manager.sh workflow
```
这将依次执行:
1. 检查Git状态
2. 自动提交更改
3. 创建版本标签(如果需要)
4. 同步到远程仓库
5. 生成状态报告
## 📋 定时任务列表
安装后系统会自动配置以下定时任务:
| 任务 | 时间 | 描述 |
|------|------|------|
| 自动提交 | 每30分钟 | 检测并提交未提交的更改 |
| 状态报告 | 每天01:00 | 生成项目状态报告 |
| 项目备份 | 每天03:00 | 创建项目备份文件 |
| 健康检查 | 每小时 | 检查系统健康状态 |
## 🛠️ 维护和管理
### 查看Cron任务
```bash
crontab -l
```
### 查看系统日志
```bash
# 查看Git版本管理日志
tail -f logs/git_version.log
# 查看定时任务日志
tail -f /tmp/末日重生_*.log
# 查看备份目录
ls -la backups/
```
### 手动执行任务
```bash
# 手动触发自动提交
./tools/git_version_manager.sh commit
# 手动创建备份
./tools/schedule_manager.py backup
# 手动生成报告
./tools/git_version_manager.sh report
```
## 🔍 监控和告警
### 系统健康检查
系统会自动监控:
- ✅ Git仓库状态
- ✅ 磁盘空间使用
- ✅ 项目目录完整性
- ✅ 网络连接状态
- ✅ 任务执行状态
### 日志文件位置
```
末日重生_囤货/logs/
├── git_version.log # Git版本管理日志
├── schedule_YYYYMM.log # 定时任务日志
└── monitor_YYYYMMDD.json # 监控数据
/tmp/
├── 末日重生_自动提交.log # 自动提交日志
├── 末日重生_报告生成.log # 报告生成日志
├── 末日重生_备份.log # 备份任务日志
└── 末日重生_健康检查.log # 健康检查日志
```
## 🚨 故障排除
### 常见问题
1. **Cron任务未执行**
```bash
# 检查Cron服务状态
systemctl status cron
# 重新安装Cron任务
./tools/schedule_manager.py install
```
2. **Git同步失败**
```bash
# 检查网络连接
ping gitea.nevadalice.top:226
# 手动同步
./tools/git_version_manager.sh sync --force
```
3. **备份失败**
```bash
# 检查磁盘空间
df -h
# 手动创建备份
./tools/schedule_manager.py backup --type chapters
```
### 日志分析
```bash
# 查看错误日志
grep -i "error\|fatal\|failed" logs/git_version.log
# 查看最近活动
tail -100 /tmp/末日重生_自动提交.log
# 检查任务执行时间
grep "开始\|完成\|成功\|失败" logs/git_version.log | tail -20
```
## 📞 技术支持
### 紧急恢复
1. **恢复最新备份**
```bash
# 找到最新的备份文件
ls -t backups/*.tar.gz | head -1
# 恢复备份
tar -xzf 最新备份文件.tar.gz -C 目标目录
```
2. **重新初始化系统**
```bash
# 移除现有配置
crontab -r
# 重新安装
./tools/schedule_manager.py install
```
### 联系信息
- **项目名称**:《末日重生-开局囤货十亿物资》
- **作者**:唐天洛
- **Gitea仓库**https://gitea.nevadalice.top:226/liyuchen/novel-doomsday-resurgence
- **创建时间**2026年3月30日
## 🎉 安装完成
系统已成功安装!你现在拥有:
1. ✅ **自动版本管理**每30分钟自动提交更改
2. ✅ **定时备份**每天凌晨3点自动备份
3. ✅ **状态报告**每天凌晨1点生成报告
4. ✅ **远程同步**自动同步到Gitea仓库
5. ✅ **健康监控**:系统健康状态实时监控
### 下一步建议
1. **立即测试系统**
```bash
./tools/git_version_manager.sh workflow
```
2. **查看系统状态**
```bash
./tools/schedule_manager.py dashboard
```
3. **开始创作**
- 在 `chapters/` 目录下继续写第25章
- 系统会自动跟踪和备份你的创作
- 定期查看状态报告了解进度
4. **监控维护**
- 定期检查系统日志
- 确保备份文件正常创建
- 关注番茄平台更新要求
---
**系统状态**:✅ 安装完成 | **版本**v1.0.0 | **最后更新**2026-03-30

3
chapters/test_chapter.md Normal file
View File

@ -0,0 +1,3 @@
# 测试章节 2026-03-30 13:07:45
这是一个测试章节,用于验证定时同步系统。
系统应该能自动检测并提交这个更改。

117
config/cron_schedule.json Normal file
View File

@ -0,0 +1,117 @@
{
"定时同步配置": {
"自动提交": {
"启用": true,
"间隔": "30分钟",
"条件": "检测到未提交的更改",
"提交信息模板": "定时更新: {date} {time}"
},
"版本标签": {
"启用": true,
"触发条件": "每10次提交自动创建标签",
"标签格式": "v{大版本}.{中版本}.{小版本}",
"里程碑章节": [5, 10, 20, 50, 100]
},
"远程同步": {
"启用": true,
"间隔": "1小时",
"重试次数": 3,
"重试间隔": "5分钟",
"强制推送": false
},
"自动备份": {
"启用": true,
"类型": ["章节备份", "Git包备份"],
"时间": "每日凌晨3点",
"保留天数": 7,
"存储位置": "项目目录/backups/"
},
"状态报告": {
"启用": true,
"生成时间": "每日凌晨1点",
"报告内容": ["章节统计", "字数统计", "版本信息", "健康检查"],
"存储位置": "项目目录/progress/status_report_YYYYMMDD.md"
},
"通知提醒": {
"启用": false,
"方式": "日志文件",
"成功通知": true,
"失败通知": true,
"日志路径": "项目目录/logs/git_version.log"
}
},
"番茄平台适配": {
"字数检查": {
"启用": true,
"标准字数": 2500,
"最小字数": 2000,
"最大字数": 3500,
"预警阈值": 80
},
"更新频率": {
"日更目标": 4000,
"章节目标": 1,
"提醒时间": "每日20:00",
"进度跟踪": true
},
"听书优化": {
"对话占比检查": true,
"最小占比": 30,
"段落长度检查": true,
"最大段落行数": 5
}
},
"Git工作流": {
"分支策略": {
"主分支": "master",
"开发分支": "develop",
"功能分支": "feature/*",
"发布分支": "release/*",
"修复分支": "hotfix/*"
},
"提交规范": {
"类型": ["feat", "fix", "docs", "style", "refactor", "test", "chore"],
"范围": ["chapters", "outlines", "assets", "tools", "config"],
"描述": "简洁描述更改内容",
"正文": "详细说明更改原因和影响",
"脚注": "关联Issue或任务"
},
"标签策略": {
"版本格式": "语义化版本 (SemVer)",
"预发布标签": "alpha, beta, rc",
"构建元数据": "build metadata",
"里程碑标签": "milestone-*"
}
},
"监控告警": {
"磁盘空间": {
"启用": true,
"阈值": "90%",
"检查间隔": "每日"
},
"网络连接": {
"启用": true,
"检查地址": "gitea.nevadalice.top:226",
"超时时间": 10
},
"任务执行": {
"启用": true,
"超时时间": 300,
"重试机制": true,
"失败通知": true
},
"性能监控": {
"启用": false,
"内存监控": true,
"CPU监控": true,
"磁盘IO监控": false
}
},
"配置说明": {
"最后更新": "2026-03-30",
"配置版本": "1.0.0",
"适用项目": "《末日重生-开局囤货十亿物资》",
"作者": "唐天洛",
"备注": "定时同步系统配置,如需修改请谨慎操作"
}
}

View File

@ -0,0 +1,16 @@
{
"auto_commit": true,
"commit_pattern": "更新: {date} {time}",
"commit_threshold": 3,
"auto_tag": true,
"tag_pattern": "v{version}",
"tag_milestones": [5, 10, 20, 50, 100],
"sync_enabled": true,
"sync_schedule": "*/30 * * * *",
"backup_enabled": true,
"backup_retention": 7,
"notifications": {
"on_success": true,
"on_failure": true
}
}

626
tools/git_version_manager.sh Executable file
View File

@ -0,0 +1,626 @@
#!/bin/bash
# 《末日重生》项目Git版本管理脚本
# 提供自动提交、版本标签、定时同步功能
PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
LOG_FILE="$PROJECT_DIR/logs/git_version.log"
CONFIG_FILE="$PROJECT_DIR/config/version_config.json"
# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# 初始化日志和配置
init() {
mkdir -p "$(dirname "$LOG_FILE")"
mkdir -p "$(dirname "$CONFIG_FILE")"
if [ ! -f "$CONFIG_FILE" ]; then
cat > "$CONFIG_FILE" << EOF
{
"auto_commit": true,
"commit_pattern": "更新: {date} {time}",
"commit_threshold": 3,
"auto_tag": true,
"tag_pattern": "v{version}",
"tag_milestones": [5, 10, 20, 50, 100],
"sync_enabled": true,
"sync_schedule": "*/30 * * * *",
"backup_enabled": true,
"backup_retention": 7,
"notifications": {
"on_success": true,
"on_failure": true
}
}
EOF
fi
}
# 日志函数
log() {
local level="$1"
local message="$2"
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
case $level in
"INFO") color=$GREEN ;;
"WARN") color=$YELLOW ;;
"ERROR") color=$RED ;;
*) color=$NC ;;
esac
echo -e "${color}[$timestamp] [$level] $message${NC}"
echo "[$timestamp] [$level] $message" >> "$LOG_FILE"
}
# 检查Git状态
check_git_status() {
log "INFO" "检查Git状态..."
cd "$PROJECT_DIR"
# 检查是否有未提交的更改
if [ -n "$(git status --porcelain)" ]; then
changed_files=$(git status --porcelain | wc -l)
log "INFO" "检测到 $changed_files 个未提交的文件"
# 显示更改摘要
echo "📝 更改摘要:"
git status --short
echo ""
return 0 # 有更改
else
log "INFO" "没有未提交的更改"
return 1 # 没有更改
fi
}
# 自动提交更改
auto_commit() {
local message="$1"
if [ -z "$message" ]; then
local current_date=$(date '+%Y年%m月%d日')
local current_time=$(date '+%H:%M:%S')
message="更新: $current_date $current_time"
fi
log "INFO" "自动提交更改: $message"
cd "$PROJECT_DIR"
# 添加所有更改
git add .
# 提交
if git commit -m "$message" > /dev/null 2>&1; then
local commit_hash=$(git rev-parse --short HEAD)
log "INFO" "✅ 提交成功 (commit: $commit_hash)"
echo "提交信息: $message"
echo "提交哈希: $commit_hash"
return 0
else
log "ERROR" "❌ 提交失败"
return 1
fi
}
# 创建版本标签
create_version_tag() {
local tag_name="$1"
local tag_message="$2"
if [ -z "$tag_name" ]; then
# 自动生成标签名
local current_version=$(git tag | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' | sort -V | tail -1)
if [ -z "$current_version" ]; then
current_version="v0.0.0"
fi
# 递增版本号
local major=$(echo "$current_version" | cut -d. -f1 | tr -d 'v')
local minor=$(echo "$current_version" | cut -d. -f2)
local patch=$(echo "$current_version" | cut -d. -f3)
patch=$((patch + 1))
# 每10个小版本升级一个中版本
if [ $patch -ge 10 ]; then
patch=0
minor=$((minor + 1))
fi
# 每10个中版本升级一个大版本
if [ $minor -ge 10 ]; then
minor=0
major=$((major + 1))
fi
tag_name="v${major}.${minor}.${patch}"
fi
if [ -z "$tag_message" ]; then
local chapter_count=$(find "$PROJECT_DIR/chapters" -name "*.md" | wc -l)
local total_words=0
for chapter in "$PROJECT_DIR/chapters"/*.md; do
if [ -f "$chapter" ]; then
words=$(wc -w < "$chapter" 2>/dev/null || echo 0)
total_words=$((total_words + words))
fi
done
tag_message="版本 ${tag_name} | 章节: ${chapter_count}章 | 字数: ${total_words}"
fi
log "INFO" "创建版本标签: $tag_name"
if git tag -a "$tag_name" -m "$tag_message" > /dev/null 2>&1; then
log "INFO" "✅ 标签创建成功: $tag_name"
echo "标签名称: $tag_name"
echo "标签描述: $tag_message"
return 0
else
log "ERROR" "❌ 标签创建失败"
return 1
fi
}
# 同步到远程仓库
sync_to_remote() {
local force="$1"
log "INFO" "同步到远程仓库..."
cd "$PROJECT_DIR"
# 检查远程仓库
if ! git remote get-url origin > /dev/null 2>&1; then
log "ERROR" "❌ 未配置远程仓库"
return 1
fi
# 获取远程仓库信息
local remote_url=$(git remote get-url origin)
log "INFO" "远程仓库: $(echo $remote_url | sed 's|https://.*@||')"
# 拉取最新更改
log "INFO" "拉取远程更改..."
if ! git pull --rebase origin master 2>&1 | grep -q "Already up to date"; then
log "INFO" "✅ 已更新本地仓库"
fi
# 推送更改
log "INFO" "推送到远程仓库..."
if [ "$force" = "true" ]; then
if git push origin master --tags --force 2>&1; then
log "INFO" "✅ 强制推送成功"
else
log "ERROR" "❌ 推送失败"
return 1
fi
else
if git push origin master --tags 2>&1; then
log "INFO" "✅ 推送成功"
else
log "WARN" "⚠️ 推送失败,尝试强制推送..."
if git push origin master --tags --force 2>&1; then
log "INFO" "✅ 强制推送成功"
else
log "ERROR" "❌ 强制推送失败"
return 1
fi
fi
fi
# 显示同步结果
local current_branch=$(git branch --show-current)
local latest_commit=$(git log -1 --format="%h - %s" 2>/dev/null)
local tag_count=$(git tag | wc -l)
echo ""
echo "📊 同步完成报告"
echo "├─ 分支: $current_branch"
echo "├─ 最新提交: $latest_commit"
echo "├─ 版本标签: $tag_count"
echo "└─ 远程仓库: $(echo $remote_url | sed 's|https://.*@||')"
return 0
}
# 自动备份
create_backup() {
local backup_type="$1"
log "INFO" "创建项目备份..."
local backup_dir="$PROJECT_DIR/backups"
local timestamp=$(date '+%Y%m%d_%H%M%S')
mkdir -p "$backup_dir"
case $backup_type in
"full")
# 完整备份
local backup_file="$backup_dir/full_backup_$timestamp.tar.gz"
tar -czf "$backup_file" -C "$PROJECT_DIR" .
log "INFO" "✅ 完整备份创建: $(basename $backup_file)"
;;
"git")
# Git包备份
local backup_file="$backup_dir/git_bundle_$timestamp.bundle"
git bundle create "$backup_file" --all
log "INFO" "✅ Git包备份创建: $(basename $backup_file)"
;;
"chapters")
# 章节备份
local backup_file="$backup_dir/chapters_$timestamp.tar.gz"
tar -czf "$backup_file" -C "$PROJECT_DIR" chapters/
log "INFO" "✅ 章节备份创建: $(basename $backup_file)"
;;
*)
# 默认备份
local backup_file="$backup_dir/backup_$timestamp.tar.gz"
tar -czf "$backup_file" -C "$PROJECT_DIR" chapters/ outlines/ assets/
log "INFO" "✅ 默认备份创建: $(basename $backup_file)"
;;
esac
# 清理旧备份
local retention_days=7
find "$backup_dir" -name "*.tar.gz" -mtime +$retention_days -delete 2>/dev/null
find "$backup_dir" -name "*.bundle" -mtime +$retention_days -delete 2>/dev/null
echo "备份文件: $backup_file"
echo "备份大小: $(du -h "$backup_file" | cut -f1)"
return 0
}
# 项目状态报告
generate_status_report() {
log "INFO" "生成项目状态报告..."
cd "$PROJECT_DIR"
local report_file="$PROJECT_DIR/progress/status_report_$(date '+%Y%m%d').md"
mkdir -p "$(dirname "$report_file")"
# 收集数据
local chapter_count=$(find chapters -name "*.md" | wc -l)
local total_words=0
local latest_chapter=""
local latest_chapter_time=""
for chapter in chapters/*.md; do
if [ -f "$chapter" ]; then
words=$(wc -w < "$chapter" 2>/dev/null || echo 0)
total_words=$((total_words + words))
# 找到最新章节
chapter_time=$(stat -c %Y "$chapter" 2>/dev/null || echo 0)
if [ -z "$latest_chapter_time" ] || [ $chapter_time -gt $latest_chapter_time ]; then
latest_chapter_time=$chapter_time
latest_chapter=$(basename "$chapter" .md)
fi
fi
done
local commit_count=$(git rev-list --count HEAD 2>/dev/null || echo 0)
local latest_commit=$(git log -1 --format="%h - %s (%ad)" --date=short 2>/dev/null || echo "无")
local tag_count=$(git tag | wc -l)
local latest_tag=$(git describe --tags --abbrev=0 2>/dev/null || echo "无")
# 生成报告
cat > "$report_file" << EOF
# 《末日重生》项目状态报告
## 报告时间
$(date '+%Y年%m月%d日 %H:%M:%S')
## 创作进度
- **总章节**: ${chapter_count}
- **总字数**: ${total_words}
- **最新章节**: ${latest_chapter}
- **平均每章字数**: $((total_words / chapter_count))
## 版本管理
- **提交次数**: ${commit_count}
- **最新提交**: ${latest_commit}
- **版本标签**: ${tag_count}
- **最新版本**: ${latest_tag}
## 番茄平台适配
### 字数要求
- 标准章节字数: 2500-3500字
- 当前平均: $((total_words / chapter_count))
- 状态: $(if [ $((total_words / chapter_count)) -ge 2000 ] && [ $((total_words / chapter_count)) -le 3500 ]; then echo "✅ 符合标准"; else echo "⚠️ 需要调整"; fi)
### 更新要求
- 日更全勤要求: 4000字/天
- 当前总字数: ${total_words}
- 相当于: $((total_words / 4000)) 天的全勤更新量
## Git状态
\`\`\`bash
$(git status --short 2>/dev/null || echo "无未提交更改")
\`\`\`
## 下一步计划
1. [ ] 继续创作第 $(($chapter_count + 1))
2. [ ] 检查并优化现有章节
3. [ ] 更新项目大纲和设定
4. [ ] 同步到远程仓库
## 健康检查
- [$(if [ $chapter_count -gt 0 ]; then echo "x"; else echo " "; fi)] 章节文件正常
- [$(if [ -d ".git" ]; then echo "x"; else echo " "; fi)] Git仓库正常
- [$(if git remote get-url origin >/dev/null 2>&1; then echo "x"; else echo " "; fi)] 远程仓库配置
- [$(if [ -f "$report_file" ]; then echo "x"; else echo " "; fi)] 报告生成正常
---
*报告自动生成于 $(date '+%Y-%m-%d %H:%M:%S')*
EOF
log "INFO" "✅ 状态报告生成: $(basename $report_file)"
echo "报告文件: $report_file"
return 0
}
# 定时同步任务
setup_cron_job() {
local schedule="$1"
if [ -z "$schedule" ]; then
schedule="*/30 * * * *" # 每30分钟
fi
log "INFO" "设置定时同步任务: $schedule"
# 创建定时任务脚本
local cron_script="/tmp/末日重生_定时同步.sh"
cat > "$cron_script" << 'CRON_EOF'
#!/bin/bash
# 《末日重生》定时同步脚本
PROJECT_DIR="/root/.openclaw/workspace/projects/末日重生_囤货"
LOG_FILE="/tmp/末日重生_同步日志.log"
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE"
}
log "INFO" "开始定时同步任务"
cd "$PROJECT_DIR"
# 检查是否有未提交的更改
if [ -n "$(git status --porcelain)" ]; then
log "INFO" "检测到未提交的更改,自动提交..."
# 自动提交
commit_message="定时更新: $(date '+%Y年%m月%d日 %H:%M:%S')"
git add .
if git commit -m "$commit_message" >/dev/null 2>&1; then
commit_hash=$(git rev-parse --short HEAD)
log "INFO" "✅ 自动提交成功: $commit_hash"
else
log "ERROR" "❌ 自动提交失败"
fi
fi
# 同步到远程
log "INFO" "同步到远程仓库..."
if git pull --rebase origin master >/dev/null 2>&1 && git push origin master >/dev/null 2>&1; then
log "INFO" "✅ 同步成功"
else
log "WARN" "⚠️ 同步失败,下次重试"
fi
# 创建每日备份(只在特定时间)
if [ "$(date '+%H')" = "03" ]; then # 凌晨3点
log "INFO" "创建每日备份..."
tar -czf "/tmp/末日重生_备份_$(date '+%Y%m%d').tar.gz" -C "$PROJECT_DIR" .
log "INFO" "✅ 备份创建完成"
fi
log "INFO" "定时同步任务完成"
CRON_EOF
chmod +x "$cron_script"
# 添加cron任务
(crontab -l 2>/dev/null | grep -v "$cron_script"; echo "$schedule $cron_script") | crontab -
log "INFO" "✅ 定时任务设置完成"
echo "定时任务: $schedule"
echo "任务脚本: $cron_script"
return 0
}
# 主菜单
show_menu() {
echo ""
echo "📚 《末日重生》项目版本管理系统"
echo "================================="
echo ""
echo "1. 🔍 检查项目状态"
echo "2. 📝 自动提交更改"
echo "3. 🏷️ 创建版本标签"
echo "4. 🔄 同步到远程仓库"
echo "5. 💾 创建项目备份"
echo "6. 📊 生成状态报告"
echo "7. ⏰ 设置定时同步"
echo "8. 🚀 一键全流程"
echo "9. 📋 显示帮助"
echo "0. ❌ 退出"
echo ""
echo "================================="
}
# 一键全流程
full_workflow() {
log "INFO" "开始一键全流程..."
echo "🚀 执行一键全流程"
echo "----------------"
# 1. 检查状态
if check_git_status; then
echo "✅ 步骤1: 检查状态完成"
else
echo " 步骤1: 无未提交更改"
fi
# 2. 自动提交
if auto_commit "一键更新: $(date '+%Y年%m月%d日 %H:%M:%S')"; then
echo "✅ 步骤2: 自动提交完成"
else
echo "⚠️ 步骤2: 提交跳过"
fi
# 3. 检查是否需要创建标签
local commit_count=$(git rev-list --count HEAD 2>/dev/null || echo 0)
if [ $((commit_count % 10)) -eq 0 ]; then
if create_version_tag; then
echo "✅ 步骤3: 版本标签创建"
else
echo "⚠️ 步骤3: 标签跳过"
fi
fi
# 4. 同步到远程
if sync_to_remote; then
echo "✅ 步骤4: 远程同步完成"
else
echo "❌ 步骤4: 同步失败"
fi
# 5. 生成报告
if generate_status_report; then
echo "✅ 步骤5: 状态报告生成"
fi
log "INFO" "一键全流程完成"
echo "🎉 全流程执行完毕!"
}
# 显示帮助
show_help() {
echo ""
echo "📖 《末日重生》Git版本管理工具使用说明"
echo "========================================"
echo ""
echo "主要功能:"
echo " 🔍 检查状态 - 检查Git状态和未提交更改"
echo " 📝 自动提交 - 自动提交所有更改到本地仓库"
echo " 🏷️ 版本标签 - 创建版本标签,记录重要里程碑"
echo " 🔄 远程同步 - 同步到Gitea远程仓库"
echo " 💾 项目备份 - 创建项目备份文件"
echo " 📊 状态报告 - 生成详细的项目状态报告"
echo " ⏰ 定时同步 - 设置定时自动同步任务"
echo " 🚀 一键流程 - 执行完整的版本管理流程"
echo ""
echo "使用方式:"
echo " ./git_version_manager.sh [选项]"
echo ""
echo "选项:"
echo " status 检查项目状态"
echo " commit 自动提交更改"
echo " tag 创建版本标签"
echo " sync 同步到远程"
echo " backup 创建备份"
echo " report 生成报告"
echo " cron 设置定时任务"
echo " workflow 执行一键流程"
echo " menu 显示交互菜单"
echo " help 显示帮助"
echo ""
echo "示例:"
echo " ./git_version_manager.sh status"
echo " ./git_version_manager.sh workflow"
echo " ./git_version_manager.sh menu"
echo ""
}
# 主函数
main() {
init
case "$1" in
"status")
check_git_status
;;
"commit")
auto_commit "$2"
;;
"tag")
create_version_tag "$2" "$3"
;;
"sync")
sync_to_remote "$2"
;;
"backup")
create_backup "$2"
;;
"report")
generate_status_report
;;
"cron")
setup_cron_job "$2"
;;
"workflow"|"auto")
full_workflow
;;
"menu")
while true; do
show_menu
echo "请选择操作 (0-9): "
read choice
case $choice in
1) check_git_status ;;
2) auto_commit ;;
3) create_version_tag ;;
4) sync_to_remote ;;
5) create_backup ;;
6) generate_status_report ;;
7) setup_cron_job ;;
8) full_workflow ;;
9) show_help ;;
0)
echo "再见!"
exit 0
;;
*)
echo "❌ 无效选择"
;;
esac
echo ""
echo "按回车键继续..."
read
done
;;
"help"|"--help"|"-h")
show_help
;;
*)
echo "使用: $0 [命令]"
echo "可用命令: status, commit, tag, sync, backup, report, cron, workflow, menu, help"
exit 1
;;
esac
}
# 运行主函数
main "$@"

561
tools/schedule_manager.py Executable file
View File

@ -0,0 +1,561 @@
#!/usr/bin/env python3
"""
末日重生项目定时任务管理系统
提供完整的定时同步版本管理监控告警功能
"""
import os
import sys
import json
import time
import subprocess
from datetime import datetime, timedelta
from pathlib import Path
import shutil
import logging
from typing import Dict, List, Optional, Tuple
# 项目配置
PROJECT_DIR = Path("/root/.openclaw/workspace/projects/末日重生_囤货")
CONFIG_DIR = PROJECT_DIR / "config"
LOG_DIR = PROJECT_DIR / "logs"
TOOLS_DIR = PROJECT_DIR / "tools"
BACKUP_DIR = PROJECT_DIR / "backups"
# 确保目录存在
for dir_path in [CONFIG_DIR, LOG_DIR, BACKUP_DIR]:
dir_path.mkdir(parents=True, exist_ok=True)
class Scheduler:
"""定时任务管理器"""
def __init__(self):
self.config = self.load_config()
self.setup_logging()
def load_config(self) -> Dict:
"""加载配置文件"""
config_path = CONFIG_DIR / "cron_schedule.json"
if config_path.exists():
with open(config_path, 'r', encoding='utf-8') as f:
return json.load(f)
else:
# 默认配置
return {
"schedules": {
"auto_commit": {
"enabled": True,
"interval": "30min",
"cron_expr": "*/30 * * * *"
},
"daily_backup": {
"enabled": True,
"time": "03:00"
},
"status_report": {
"enabled": True,
"time": "01:00"
},
"weekly_cleanup": {
"enabled": True,
"day": "sunday",
"time": "02:00"
}
}
}
def setup_logging(self):
"""配置日志系统"""
log_file = LOG_DIR / f"schedule_{datetime.now().strftime('%Y%m')}.log"
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s [%(levelname)s] %(message)s',
handlers=[
logging.FileHandler(log_file, encoding='utf-8'),
logging.StreamHandler(sys.stdout)
]
)
self.logger = logging.getLogger(__name__)
def run_auto_commit(self):
"""执行自动提交任务"""
self.logger.info("开始自动提交任务...")
try:
# 运行Git版本管理脚本
script_path = TOOLS_DIR / "git_version_manager.sh"
if not script_path.exists():
self.logger.error(f"脚本不存在: {script_path}")
return False
# 检查是否有更改
result = subprocess.run(
["git", "status", "--porcelain"],
cwd=PROJECT_DIR,
capture_output=True,
text=True,
timeout=30
)
if result.stdout.strip():
# 有未提交的更改,执行提交
commit_message = f"定时更新: {datetime.now().strftime('%Y年%m月%d%H:%M:%S')}"
self.logger.info(f"检测到未提交的更改,提交信息: {commit_message}")
# 执行提交
commit_result = subprocess.run(
[str(script_path), "commit"],
cwd=PROJECT_DIR,
capture_output=True,
text=True,
timeout=60
)
if commit_result.returncode == 0:
self.logger.info("自动提交成功")
return True
else:
self.logger.error(f"自动提交失败: {commit_result.stderr}")
return False
else:
self.logger.info("没有未提交的更改,跳过提交")
return True
except subprocess.TimeoutExpired:
self.logger.error("自动提交任务超时")
return False
except Exception as e:
self.logger.error(f"自动提交任务异常: {e}")
return False
def run_backup_task(self, backup_type: str = "full"):
"""执行备份任务"""
self.logger.info(f"开始备份任务,类型: {backup_type}")
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
backup_filename = f"backup_{backup_type}_{timestamp}.tar.gz"
backup_file = BACKUP_DIR / backup_filename
try:
# 根据备份类型执行备份
if backup_type == "full":
# 完整备份
backup_items = [
"chapters", "outlines", "assets",
"tools", "config", "progress"
]
backup_cmd = ["tar", "czf", str(backup_file)] + backup_items
elif backup_type == "chapters":
# 章节备份
backup_cmd = ["tar", "czf", str(backup_file), "chapters"]
elif backup_type == "git":
# Git包备份
backup_file = BACKUP_DIR / f"git_bundle_{timestamp}.bundle"
backup_cmd = ["git", "bundle", "create", str(backup_file), "--all"]
else:
self.logger.error(f"未知的备份类型: {backup_type}")
return False
# 执行备份命令
result = subprocess.run(
backup_cmd,
cwd=PROJECT_DIR,
capture_output=True,
text=True,
timeout=300
)
if result.returncode == 0:
backup_size = backup_file.stat().st_size / (1024 * 1024) # MB
self.logger.info(f"备份成功: {backup_filename} ({backup_size:.2f} MB)")
# 清理旧备份
self.cleanup_old_backups()
return True
else:
self.logger.error(f"备份失败: {result.stderr}")
return False
except Exception as e:
self.logger.error(f"备份任务异常: {e}")
return False
def cleanup_old_backups(self):
"""清理旧备份文件"""
retention_days = 7
cutoff_time = datetime.now() - timedelta(days=retention_days)
deleted_files = []
for backup_file in BACKUP_DIR.glob("*.tar.gz"):
file_time = datetime.fromtimestamp(backup_file.stat().st_mtime)
if file_time < cutoff_time:
try:
backup_file.unlink()
deleted_files.append(backup_file.name)
except Exception as e:
self.logger.warning(f"删除旧备份失败 {backup_file}: {e}")
if deleted_files:
self.logger.info(f"清理旧备份: {len(deleted_files)} 个文件")
def run_status_report(self):
"""执行状态报告任务"""
self.logger.info("开始状态报告任务...")
try:
# 运行Git版本管理脚本生成报告
script_path = TOOLS_DIR / "git_version_manager.sh"
if not script_path.exists():
self.logger.error(f"脚本不存在: {script_path}")
return False
# 执行报告生成
result = subprocess.run(
[str(script_path), "report"],
cwd=PROJECT_DIR,
capture_output=True,
text=True,
timeout=120
)
if result.returncode == 0:
self.logger.info("状态报告生成成功")
# 发送通知(可选)
if self.config.get("notifications", {}).get("enabled", False):
self.send_notification("状态报告已生成")
return True
else:
self.logger.error(f"状态报告生成失败: {result.stderr}")
return False
except Exception as e:
self.logger.error(f"状态报告任务异常: {e}")
return False
def send_notification(self, message: str):
"""发送通知(示例)"""
# 这里可以实现邮件、钉钉、飞书等通知方式
# 示例:输出到日志和终端
print(f"📢 通知: {message}")
self.logger.info(f"通知已发送: {message}")
def check_health(self) -> Dict:
"""检查系统健康状态"""
health_status = {
"timestamp": datetime.now().isoformat(),
"components": {}
}
# 检查磁盘空间
disk_usage = shutil.disk_usage(PROJECT_DIR)
disk_percent = disk_usage.used / disk_usage.total * 100
health_status["components"]["disk"] = {
"total_gb": disk_usage.total / (1024**3),
"used_gb": disk_usage.used / (1024**3),
"free_gb": disk_usage.free / (1024**3),
"percent_used": disk_percent,
"status": "OK" if disk_percent < 90 else "WARNING"
}
# 检查Git仓库
git_status = subprocess.run(
["git", "status"],
cwd=PROJECT_DIR,
capture_output=True,
text=True
)
health_status["components"]["git"] = {
"repository_healthy": git_status.returncode == 0,
"status": "OK" if git_status.returncode == 0 else "ERROR"
}
# 检查项目文件
required_dirs = ["chapters", "outlines", "assets"]
for dir_name in required_dirs:
dir_path = PROJECT_DIR / dir_name
health_status["components"][dir_name] = {
"exists": dir_path.exists(),
"file_count": len(list(dir_path.glob("*"))) if dir_path.exists() else 0,
"status": "OK" if dir_path.exists() else "MISSING"
}
# 总体状态
all_ok = all(
comp.get("status") == "OK"
for comp in health_status["components"].values()
)
health_status["overall_status"] = "HEALTHY" if all_ok else "UNHEALTHY"
return health_status
def monitor_task_execution(self):
"""监控任务执行状态"""
health_status = self.check_health()
self.logger.info("系统健康状态检查")
self.logger.info(f"总体状态: {health_status['overall_status']}")
# 记录到监控日志
monitor_log = LOG_DIR / f"monitor_{datetime.now().strftime('%Y%m%d')}.json"
monitor_data = {
"timestamp": datetime.now().isoformat(),
"health": health_status,
"tasks": {
"auto_commit": self.config.get("schedules", {}).get("auto_commit", {}),
"daily_backup": self.config.get("schedules", {}).get("daily_backup", {}),
"status_report": self.config.get("schedules", {}).get("status_report", {})
}
}
try:
with open(monitor_log, 'a', encoding='utf-8') as f:
f.write(json.dumps(monitor_data, ensure_ascii=False) + "\n")
self.logger.info(f"监控数据已记录: {monitor_log}")
except Exception as e:
self.logger.error(f"记录监控数据失败: {e}")
def install_cron_jobs(self):
"""安装Cron定时任务"""
cron_script = """
#!/bin/bash
# 《末日重生》定时任务配置
# 自动安装和配置定时同步任务
# 自动提交任务每30分钟
*/30 * * * * cd /root/.openclaw/workspace/projects/末日重生_囤货 && ./tools/git_version_manager.sh commit >> /tmp/末日重生_自动提交.log 2>&1
# 状态报告任务每天凌晨1点
0 1 * * * cd /root/.openclaw/workspace/projects/末日重生_囤货 && ./tools/git_version_manager.sh report >> /tmp/末日重生_报告生成.log 2>&1
# 备份任务每天凌晨3点
0 3 * * * cd /root/.openclaw/workspace/projects/末日重生_囤货 && ./tools/schedule_manager.py backup >> /tmp/末日重生_备份.log 2>&1
# 健康检查(每小时)
0 * * * * cd /root/.openclaw/workspace/projects/末日重生_囤货 && ./tools/schedule_manager.py health >> /tmp/末日重生_健康检查.log 2>&1
"""
cron_file = "/tmp/末日重生_cron.conf"
try:
with open(cron_file, 'w', encoding='utf-8') as f:
f.write(cron_script)
# 安装Cron任务
subprocess.run(["crontab", cron_file], check=True)
self.logger.info("Cron定时任务安装成功")
self.logger.info("已配置以下定时任务:")
self.logger.info(" - 自动提交每30分钟")
self.logger.info(" - 状态报告每天凌晨1点")
self.logger.info(" - 项目备份每天凌晨3点")
self.logger.info(" - 健康检查:每小时")
os.unlink(cron_file)
return True
except Exception as e:
self.logger.error(f"安装Cron任务失败: {e}")
return False
def show_dashboard(self):
"""显示系统仪表板"""
health = self.check_health()
print("=" * 60)
print("📊 《末日重生》项目管理系统仪表板")
print("=" * 60)
print()
print("📈 项目统计")
print("" * 40)
# 章节统计
chapters_dir = PROJECT_DIR / "chapters"
if chapters_dir.exists():
chapter_files = list(chapters_dir.glob("*.md"))
print(f" 📖 章节数量: {len(chapter_files)}")
# 计算总字数
total_words = 0
for chapter in chapter_files:
try:
content = chapter.read_text(encoding='utf-8')
words = len(content.split())
total_words += words
except:
continue
print(f" 📝 总字数: {total_words}")
avg_words = total_words // len(chapter_files) if chapter_files else 0
print(f" ⚖️ 平均每章: {avg_words}")
else:
print(" ⚠️ 章节目录不存在")
print()
print("💾 备份管理")
print("" * 40)
backup_files = list(BACKUP_DIR.glob("*.tar.gz")) + list(BACKUP_DIR.glob("*.bundle"))
if backup_files:
backup_files.sort(key=lambda x: x.stat().st_mtime, reverse=True)
print(f" 🗂️ 备份数量: {len(backup_files)}")
print(f" 🗓️ 最新备份: {backup_files[0].name}")
print(f" 备份时间: {datetime.fromtimestamp(backup_files[0].stat().st_mtime).strftime('%Y-%m-%d %H:%M:%S')}")
# 计算总备份大小
total_size = sum(f.stat().st_size for f in backup_files) / (1024**3) # GB
print(f" 📦 总备份大小: {total_size:.2f} GB")
else:
print(" ⚠️ 暂无备份文件")
print()
print("🔄 任务配置")
print("" *40)
for task_name, task_config in self.config.get("schedules", {}).items():
status = "✅ 启用" if task_config.get("enabled", False) else "❌ 停用"
if task_name == "auto_commit":
interval = task_config.get("interval", "未知")
print(f" 📝 {task_name}: {status} (间隔: {interval})")
elif task_name == "daily_backup":
backup_time = task_config.get("time", "未知")
print(f" 💾 {task_name}: {status} (时间: {backup_time})")
elif task_name == "status_report":
report_time = task_config.get("time", "未知")
print(f" 📊 {task_name}: {status} (时间: {report_time})")
elif task_name == "weekly_cleanup":
cleanup_day = task_config.get("day", "未知")
cleanup_time = task_config.get("time", "未知")
print(f" 🧹 {task_name}: {status} (时间: 每周{cleanup_day}{cleanup_time})")
print()
print("📈 健康状态")
print("" *40)
if health.get("overall_status") == "HEALTHY":
print(" 🟢 系统状态: 健康")
else:
print(" 🔴 系统状态: 异常")
# 显示异常组件
for comp_name, comp_status in health.get("components", {}).items():
if comp_status.get("status") != "OK":
print(f" ⚠️ {comp_name}: {comp_status.get('status')}")
print()
print("=" *60)
def main():
"""主函数"""
import argparse
parser = argparse.ArgumentParser(
description="《末日重生》项目定时任务管理系统",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
使用示例:
# 显示系统仪表板
python schedule_manager.py dashboard
# 执行自动提交
python schedule_manager.py commit
# 执行备份任务
python schedule_manager.py backup --type full
# 安装定时任务
python schedule_manager.py install
# 检查系统健康
python schedule_manager.py health
# 运行状态报告
python schedule_manager.py report
"""
)
parser.add_argument(
"action",
choices=[
"dashboard", "commit", "backup", "report", "health", "install"
],
help="要执行的操作"
)
parser.add_argument(
"--type",
default="full",
choices=["full", "chapters", "git"],
help="备份类型"
)
parser.add_argument(
"--verbose",
action="store_true",
help="显示详细日志"
)
args = parser.parse_args()
scheduler = Scheduler()
if args.verbose:
scheduler.logger.setLevel(logging.DEBUG)
if args.action == "dashboard":
scheduler.show_dashboard()
elif args.action == "commit":
success = scheduler.run_auto_commit()
exit(0 if success else 1)
elif args.action == "backup":
success = scheduler.run_backup_task(args.type)
exit(0 if success else 1)
elif args.action == "report":
success = scheduler.run_status_report()
exit(0 if success else 1)
elif args.action == "health":
health_status = scheduler.check_health()
print(json.dumps(health_status, ensure_ascii=False, indent=2))
exit(0 if health_status["overall_status"] == "HEALTHY" else 1)
elif args.action == "install":
success = scheduler.install_cron_jobs()
exit(0 if success else 1)
if __name__ == "__main__":
main()