novel-doomsday-resurgence/ultimate_fix.py

232 lines
8.6 KiB
Python
Raw Permalink Normal View History

#!/usr/bin/env python3
"""
inkos 终极修复方案
直接修复数据库中的数据错误
"""
import json
import os
import shutil
import sqlite3
import subprocess
import time
def stop_inkos():
"""停止inkos所有进程"""
print("1. 停止inkos所有进程...")
subprocess.run(["pkill", "-9", "-f", "node.*inkos"], capture_output=True)
subprocess.run(["pkill", "-9", "-f", "inkos"], capture_output=True)
time.sleep(3)
print(" ✅ inkos已停止")
def backup_data():
"""备份所有数据"""
print("2. 备份数据...")
backup_dir = f"/root/.openclaw/workspace/backups/inkos_ultimate_fix_{time.strftime('%Y%m%d_%H%M%S')}"
os.makedirs(backup_dir, exist_ok=True)
# 备份重要文件和目录
backup_items = [
"/root/.openclaw/workspace/tomato-novel/inkos.json",
"/root/.openclaw/workspace/tomato-novel/tomato-novel/books/末日重生-开局囤货十亿物资",
"/root/.openclaw/workspace/tomato-novel/books/末日重生-开局囤货十亿物资"
]
for item in backup_items:
if os.path.exists(item):
if os.path.isfile(item):
shutil.copy2(item, backup_dir)
else:
shutil.copytree(item, os.path.join(backup_dir, os.path.basename(item)), dirs_exist_ok=True)
print(f" 已备份: {os.path.basename(item)}")
print(f" 备份位置: {backup_dir}")
return backup_dir
def fix_database():
"""修复数据库文件"""
print("3. 修复数据库文件...")
# 找到并修复所有数据库文件
db_files = [
"/root/.openclaw/workspace/tomato-novel/tomato-novel/books/末日重生-开局囤货十亿物资/story/memory.db",
"/root/.openclaw/workspace/tomato-novel/books/末日重生-开局囤货十亿物资/story/memory.db"
]
for db_file in db_files:
if os.path.exists(db_file):
print(f" 检查数据库: {db_file}")
try:
# 备份数据库
shutil.copy2(db_file, f"{db_file}.backup")
# 尝试连接到数据库
conn = sqlite3.connect(db_file)
cursor = conn.cursor()
# 获取所有表名
cursor.execute("SELECT name FROM sqlite_master WHERE type='table';")
tables = cursor.fetchall()
print(f" 数据库表: {[t[0] for t in tables]}")
# 查找可能包含章节数据的表
for table in tables:
table_name = table[0]
if 'chapter' in table_name.lower() or 'row' in table_name.lower():
print(f" 检查表: {table_name}")
# 获取表结构
cursor.execute(f"PRAGMA table_info({table_name});")
columns = cursor.fetchall()
print(f" 列: {[col[1] for col in columns]}")
# 查找title列
title_col = None
for col in columns:
if 'title' in col[1].lower():
title_col = col[1]
break
if title_col:
# 查找空标题的行
cursor.execute(f"SELECT rowid, {title_col} FROM {table_name} WHERE {title_col} IS NULL OR {title_col} = '' OR LENGTH(TRIM({title_col})) = 0;")
empty_titles = cursor.fetchall()
if empty_titles:
print(f" 找到 {len(empty_titles)} 个空标题")
for rowid, title in empty_titles:
# 修复空标题
new_title = f"{rowid}"
cursor.execute(f"UPDATE {table_name} SET {title_col} = ? WHERE rowid = ?", (new_title, rowid))
print(f" 修复行 {rowid}: '{new_title}'")
conn.commit()
conn.close()
print(f" ✅ 数据库修复完成: {os.path.basename(db_file)}")
except Exception as e:
print(f" ❌ 修复数据库时出错: {e}")
# 如果数据库损坏严重删除它让inkos重新创建
print(f" 删除损坏的数据库: {db_file}")
os.remove(db_file)
print(f" ✅ 已删除inkos将重新创建数据库")
def clean_state_files():
"""清理状态文件让inkos重新开始"""
print("4. 清理状态文件...")
# 删除可能损坏的状态文件
state_dirs = [
"/root/.openclaw/workspace/tomato-novel/tomato-novel/books/末日重生-开局囤货十亿物资/story/state",
"/root/.openclaw/workspace/tomato-novel/tomato-novel/books/末日重生-开局囤货十亿物资/story/runtime",
"/root/.openclaw/workspace/tomato-novel/books/末日重生-开局囤货十亿物资/story/state",
"/root/.openclaw/workspace/tomato-novel/books/末日重生-开局囤货十亿物资/story/runtime"
]
for state_dir in state_dirs:
if os.path.exists(state_dir):
# 只删除特定文件,保留章节文件
for file in os.listdir(state_dir):
if file.endswith('.json') or file.endswith('.db'):
file_path = os.path.join(state_dir, file)
try:
os.remove(file_path)
print(f" 删除: {file}")
except:
pass
print(" ✅ 状态文件已清理")
def create_simple_config():
"""创建最简单的配置"""
print("5. 创建简单配置...")
config = {
"name": "tomato-novel-fixed",
"version": "0.1.0",
"language": "zh",
"llm": {
"provider": "custom",
"baseUrl": "https://ark.cn-beijing.volces.com/api/coding/v3",
"model": "deepseek-v3.2"
},
"daemon": {
"schedule": {
"writeCron": "0 */2 * * *" # 每2小时一次
},
"maxConcurrentBooks": 1
},
"quality": {
"enforcement": "none" # 完全关闭质量检查
}
}
config_path = "/root/.openclaw/workspace/tomato-novel/inkos.json"
with open(config_path, 'w', encoding='utf-8') as f:
json.dump(config, f, ensure_ascii=False, indent=2)
print(" ✅ 简单配置已创建")
def start_inkos():
"""启动inkos"""
print("6. 启动inkos...")
os.chdir("/root/.openclaw/workspace/tomato-novel")
# 启动inkos
with open("/tmp/inkos_ultimate_start.log", "w") as log_file:
process = subprocess.Popen(
["nohup", "inkos", "up"],
stdout=log_file,
stderr=subprocess.STDOUT,
start_new_session=True
)
time.sleep(10)
# 检查是否启动成功
result = subprocess.run(["ps", "aux"], capture_output=True, text=True)
if "inkos up" in result.stdout:
pid_line = [line for line in result.stdout.split('\n') if "inkos up" in line][0]
pid = pid_line.split()[1]
print(f" ✅ inkos 已启动 (PID: {pid})")
return True
else:
print(" ❌ inkos 启动失败")
return False
def main():
"""主函数"""
print("=" * 60)
print("inkos 终极修复方案")
print("=" * 60)
stop_inkos()
backup_dir = backup_data()
fix_database()
clean_state_files()
create_simple_config()
if start_inkos():
print("\n" + "=" * 60)
print("✅ 修复完成!")
print(f"备份位置: {backup_dir}")
print("=" * 60)
print("\ninkos 已重新启动,配置为:")
print("- 质量检查: 关闭")
print("- 创作频率: 每2小时")
print("- 日志文件: /tmp/inkos_ultimate_start.log")
print("\n等待5-10分钟后使用以下命令测试:")
print(" inkos status")
print(" inkos draft 末日重生-开局囤货十亿物资")
else:
print("\n" + "=" * 60)
print("❌ 修复失败!")
print("=" * 60)
print("\n请检查:")
print("1. inkos 是否安装: which inkos")
print("2. 日志文件: tail -100 /tmp/inkos_ultimate_start.log")
print("3. 可能需要重新安装 inkos")
if __name__ == "__main__":
main()