File size: 4,307 Bytes
56ddb31
9841f0b
 
 
56ddb31
9841f0b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56ddb31
9841f0b
 
56ddb31
 
 
 
 
 
 
 
 
 
 
 
9841f0b
56ddb31
 
9841f0b
 
 
56ddb31
9841f0b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56ddb31
9841f0b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56ddb31
9841f0b
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
import os
import sqlite3
import uuid
import datetime

# 1. 定位原项目在 Docker 容器内生成的 SQLite 数据库路径
# 原项目默认存放在 server/prisma/dev.db 或类似路径下,根据容器内实际路径做安全兼容
DB_PATHS = [
    "/app/server/prisma/dev.db",
    "server/prisma/dev.db",
    "prisma/dev.db"
]

def get_active_db():
    for path in DB_PATHS:
        if os.path.exists(path):
            return path
    # 如果还没生成,尝试初始化一个路径
    return "/app/server/prisma/dev.db"

def inject_secrets_to_sqlite():
    db_path = get_active_db()
    print(f"📦 正在连接 FreeLLMAPI 核心数据库: {db_path}")
    
    # 对齐你配置的 HF Secrets 名字与项目数据库里的 Provider 标识
    secrets_map = {
        "GOOGLE_API_KEY": "google",
        "GROQ_API_KEY": "groq",
        "GITHUB_TOKEN": "github",
        "OPENROUTER_API_KEY": "openrouter",
        "MISTRAL_API_KEY": "mistral",
        "TOGETHER_API_KEY": "together",
        "NVIDIA_API_KEY": "nvidia",
        "COHERE_API_KEY": "cohere",
        "HF_TOKEN": "huggingface",
        "CEREBRAS_API_KEY": "cerebras",
        "SAMBANOVA_API_KEY": "sambanova",
        "CLOUDFLARE_API_TOKEN": "cloudflare",
        "ZHIPU_API_KEY": "zhipu"
    }
    
    try:
        conn = sqlite3.connect(db_path)
        cursor = conn.cursor()
        
        # 2. 检查原项目内 Provider 或者是 Keys 表的结构
        # 原项目的表名通常叫 Provider 或者 Credentials
        cursor.execute("SELECT name FROM sqlite_master WHERE type='table';")
        tables = [t[0] for t in cursor.fetchall()]
        print(f"📊 探测到系统当前表结构: {tables}")
        
        # 寻找存储渠道的表(通常包含 'Provider' 或 'Credential' 关键字)
        target_table = "Provider" if "Provider" in tables else None
        if not target_table:
            for t in tables:
                if "key" in t.lower() or "provider" in t.lower():
                    target_table = t
                    break
                    
        if not target_table:
            print("❌ 未能识别到原项目的密钥存储表,请先在前端随便手动添加任意一个Key以初始化数据库。")
            return

        # 3. 遍历并强行注入 Secrets
        success_count = 0
        now = datetime.datetime.utcnow().isoformat()
        
        for secret_name, provider_id in secrets_map.items():
            actual_key = os.getenv(secret_name)
            if not actual_key:
                continue
                
            # 检查数据库中是否已存在该渠道,防止重复插入
            cursor.execute(f"SELECT id FROM {target_table} WHERE name = ? OR provider = ?", (provider_id, provider_id))
            exists = cursor.fetchone()
            
            if not exists:
                # 动态生成符合 Prisma 规范的记录
                # 💡 注意:原版采用了不加密或自加密,这里直接存入(如果原版带加密,脚本运行后前端会显示加密格式)
                record_id = str(uuid.uuid4())
                try:
                    # 根据标准的 Prisma 字段结构进行弹性插入
                    cursor.execute(f"""
                        INSERT INTO {target_table} (id, name, provider, apiKey, status, createdAt, updatedAt) 
                        VALUES (?, ?, ?, ?, ?, ?, ?)
                    """, (record_id, provider_id, provider_id, actual_key, "active", now, now))
                    success_count += 1
                except sqlite3.OperationalError:
                    # 如果字段不完全对齐,尝试最简化插入
                    cursor.execute(f"""
                        INSERT INTO {target_table} (id, name, apiKey) 
                        VALUES (?, ?, ?)
                    """, (record_id, provider_id, actual_key))
                    success_count += 1
                    
        conn.commit()
        conn.close()
        print(f"🏁 注入成功!已将 {success_count} 个云端 Secrets 强制同步到本地 SQLite。")
        
    except Exception as e:
        print(f"⚠️ 自动注入过程中发生意外,正在等待系统原生初始化: {str(e)}")

if __name__ == "__main__":
    inject_secrets_to_sqlite()