更新: 2026年03月30日 13:07:45
This commit is contained in:
parent
3c1564967e
commit
2b26f99b47
20
.gitattributes
vendored
Normal file
20
.gitattributes
vendored
Normal 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
63
.gitignore
vendored
Normal 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
355
INSTALL.md
Normal 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
3
chapters/test_chapter.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# 测试章节 2026-03-30 13:07:45
|
||||||
|
这是一个测试章节,用于验证定时同步系统。
|
||||||
|
系统应该能自动检测并提交这个更改。
|
||||||
117
config/cron_schedule.json
Normal file
117
config/cron_schedule.json
Normal 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",
|
||||||
|
"适用项目": "《末日重生-开局囤货十亿物资》",
|
||||||
|
"作者": "唐天洛",
|
||||||
|
"备注": "定时同步系统配置,如需修改请谨慎操作"
|
||||||
|
}
|
||||||
|
}
|
||||||
16
config/version_config.json
Normal file
16
config/version_config.json
Normal 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
626
tools/git_version_manager.sh
Executable 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
561
tools/schedule_manager.py
Executable 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()
|
||||||
Loading…
Reference in New Issue
Block a user