"""Khôi phục các dự án cloud cũ (từ git history) vào bất kỳ sonicforge.db nào. Cách dùng trên máy deployment thật (host game): python3 tools/restore_cloud_projects.py /path/to/sonicforge.db Script đọc backup projects (JSON) đã xuất từ git history và chèn vào DB chỉ định, gán tất cả cho user_id được yêu cầu (mặc định: admin đầu tiên tìm thấy). """ import json import os import sqlite3 import sys PROJECTS_BACKUP = os.path.join(os.path.dirname(__file__), "cloud_projects_backup.json") def main(db_path: str, user_id: str = None): if not os.path.exists(PROJECTS_BACKUP): print(f"Không tìm thấy {PROJECTS_BACKUP}") return 1 if not os.path.exists(db_path): print(f"Không tìm thấy DB: {db_path}") return 1 with open(PROJECTS_BACKUP) as f: projects = json.load(f) conn = sqlite3.connect(db_path) conn.row_factory = sqlite3.Row if user_id is None: row = conn.execute("SELECT id FROM users WHERE role='admin' ORDER BY created_at LIMIT 1").fetchone() if not row: print("Không có user admin nào trong DB") conn.close() return 1 user_id = row["id"] print(f"Gán tất cả cho admin: {user_id}") restored = 0 for p in projects: if conn.execute("SELECT id FROM projects WHERE id=?", (p["id"],)).fetchone(): print(f" bỏ qua (đã tồn tại): {p['name']}") continue conn.execute( "INSERT INTO projects (id, user_id, name, data_json, is_temp, size_bytes, updated_at) VALUES (?,?,?,?,0,?,?)", (p["id"], user_id, p["name"], json.dumps(p["data_json"], ensure_ascii=False), len(json.dumps(p["data_json"]).encode("utf-8")), p["updated_at"])) restored += 1 print(f" đã khôi phục: {p['name']}") conn.commit() conn.close() print(f"\nHoàn tất: {restored} dự án đã khôi phục cho user {user_id}") return 0 if __name__ == "__main__": if len(sys.argv) < 2: print("Usage: python3 restore_cloud_projects.py [user_id]") sys.exit(1) sys.exit(main(sys.argv[1], sys.argv[2] if len(sys.argv) > 2 else None))