Update main.py
Browse files
main.py
CHANGED
|
@@ -92,17 +92,17 @@ def gregorian_to_jalali(gy, gm, gd):
|
|
| 92 |
return jy, jm, jd
|
| 93 |
|
| 94 |
# ==============================================================================
|
| 95 |
-
# 🟢 پارت 4: دیتابیس SQLite (نسخه
|
| 96 |
# ==============================================================================
|
| 97 |
import os
|
| 98 |
import sqlite3
|
| 99 |
import json
|
| 100 |
import copy
|
| 101 |
|
| 102 |
-
# ت
|
| 103 |
-
DB_FILE = "/data/
|
| 104 |
-
|
| 105 |
-
|
| 106 |
|
| 107 |
last_saved_state = {}
|
| 108 |
|
|
@@ -110,49 +110,32 @@ def init_sqlite_db():
|
|
| 110 |
try:
|
| 111 |
os.makedirs(os.path.dirname(DB_FILE), exist_ok=True)
|
| 112 |
|
| 113 |
-
#
|
| 114 |
-
|
| 115 |
-
|
| 116 |
-
|
| 117 |
-
|
| 118 |
-
|
| 119 |
-
|
| 120 |
-
|
| 121 |
-
|
| 122 |
-
|
| 123 |
-
|
| 124 |
-
|
| 125 |
-
|
| 126 |
-
|
| 127 |
-
|
| 128 |
-
|
| 129 |
-
|
| 130 |
-
print("🚨 فایل v2 هم خراب شده، نیاز به بازسازی مجدد...")
|
| 131 |
-
|
| 132 |
-
if should_rebuild:
|
| 133 |
-
print("🛠 در حال ساخت دیتابیس جدید و سالم...")
|
| 134 |
-
if os.path.exists(DB_FILE):
|
| 135 |
-
os.rename(DB_FILE, DB_FILE + ".broken")
|
| 136 |
-
|
| 137 |
-
conn = sqlite3.connect(DB_FILE, timeout=60.0)
|
| 138 |
-
cursor = conn.cursor()
|
| 139 |
-
cursor.execute('PRAGMA journal_mode=DELETE;') # امنترین حالت برای درایو شبکه
|
| 140 |
-
cursor.execute('CREATE TABLE users (chat_id TEXT PRIMARY KEY, user_data TEXT)')
|
| 141 |
-
cursor.execute('CREATE TABLE processed_messages (message_id TEXT PRIMARY KEY)')
|
| 142 |
-
conn.commit()
|
| 143 |
-
conn.close()
|
| 144 |
-
|
| 145 |
-
# بلافاصله اطلاعات کاربران را از بکآپ سالم برگردان
|
| 146 |
-
restore_from_json()
|
| 147 |
|
| 148 |
except Exception as e:
|
| 149 |
-
print(f"❌ خطا در راه اندازی: {e}")
|
| 150 |
|
| 151 |
-
def
|
| 152 |
-
if os.path.exists(
|
| 153 |
-
print("📥 در حال
|
| 154 |
try:
|
| 155 |
-
with open(
|
| 156 |
data = json.load(f)
|
| 157 |
if data:
|
| 158 |
conn = sqlite3.connect(DB_FILE, timeout=60.0)
|
|
@@ -160,9 +143,27 @@ def restore_from_json():
|
|
| 160 |
conn.execute("INSERT OR REPLACE INTO users VALUES (?, ?)", (str(cid), json.dumps(udata)))
|
| 161 |
conn.commit()
|
| 162 |
conn.close()
|
| 163 |
-
print(f"✅ ا
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 164 |
except Exception as e:
|
| 165 |
-
print(f"
|
| 166 |
|
| 167 |
def load_db():
|
| 168 |
global last_saved_state
|
|
@@ -176,10 +177,10 @@ def load_db():
|
|
| 176 |
db_dict[row[0]] = json.loads(row[1])
|
| 177 |
conn.close()
|
| 178 |
last_saved_state = copy.deepcopy(db_dict)
|
| 179 |
-
print(f"
|
| 180 |
return db_dict
|
| 181 |
except Exception as e:
|
| 182 |
-
print(f"⚠️ ارور
|
| 183 |
return {}
|
| 184 |
|
| 185 |
def save_db(db_data):
|
|
@@ -192,7 +193,7 @@ def save_db(db_data):
|
|
| 192 |
if not changed: return
|
| 193 |
conn = sqlite3.connect(DB_FILE, timeout=60.0)
|
| 194 |
conn.execute('PRAGMA journal_mode=DELETE;')
|
| 195 |
-
conn.executemany("INSERT OR REPLACE INTO users VALUES (?, ?)", changed)
|
| 196 |
conn.commit()
|
| 197 |
conn.close()
|
| 198 |
for cid, _ in changed:
|
|
|
|
| 92 |
return jy, jm, jd
|
| 93 |
|
| 94 |
# ==============================================================================
|
| 95 |
+
# 🟢 پارت 4: دیتابیس SQLite (نسخه نجات همهجانبه: اعتبارها + پیامهای قدیمی)
|
| 96 |
# ==============================================================================
|
| 97 |
import os
|
| 98 |
import sqlite3
|
| 99 |
import json
|
| 100 |
import copy
|
| 101 |
|
| 102 |
+
# استفاده از نام جدید v3 برای شروع کاملاً پاک و بدون قفل
|
| 103 |
+
DB_FILE = "/data/users_v3.db"
|
| 104 |
+
CORRUPT_FILE = "/data/users_db.db" # فایل ۱۱.۷ مگابایتی شما
|
| 105 |
+
BACKUP_JSON = "/data/users_db.json.bak" # فایل ۴.۷ مگابایتی اعتبارها
|
| 106 |
|
| 107 |
last_saved_state = {}
|
| 108 |
|
|
|
|
| 110 |
try:
|
| 111 |
os.makedirs(os.path.dirname(DB_FILE), exist_ok=True)
|
| 112 |
|
| 113 |
+
# اگر فایل v3 وجود ندارد، یعنی بار اول است و باید نجات را شروع کنیم
|
| 114 |
+
is_first_run = not os.path.exists(DB_FILE)
|
| 115 |
+
|
| 116 |
+
conn = sqlite3.connect(DB_FILE, timeout=60.0)
|
| 117 |
+
cursor = conn.cursor()
|
| 118 |
+
cursor.execute('PRAGMA journal_mode=DELETE;') # امنترین حالت برای شبکه
|
| 119 |
+
cursor.execute('CREATE TABLE IF NOT EXISTS users (chat_id TEXT PRIMARY KEY, user_data TEXT)')
|
| 120 |
+
cursor.execute('CREATE TABLE IF NOT EXISTS processed_messages (message_id TEXT PRIMARY KEY)')
|
| 121 |
+
conn.commit()
|
| 122 |
+
conn.close()
|
| 123 |
+
|
| 124 |
+
if is_first_run:
|
| 125 |
+
print("🚨 عملیات نجات آغاز شد...")
|
| 126 |
+
# ۱. بازیابی اعتبارها از JSON (۱۰۰ درصد مطمئن)
|
| 127 |
+
restore_users_from_json()
|
| 128 |
+
# ۲. نجات شناسههای پیام از فایل ۱۱.۷ مگابایتی (تا جایی که راه بدهد)
|
| 129 |
+
salvage_messages_from_corrupt_db()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 130 |
|
| 131 |
except Exception as e:
|
| 132 |
+
print(f"❌ خطا در راه اندازی دیتابیس: {e}")
|
| 133 |
|
| 134 |
+
def restore_users_from_json():
|
| 135 |
+
if os.path.exists(BACKUP_JSON):
|
| 136 |
+
print("📥 در حال بازیابی اعتبار کاربران از فایل پشتیبان...")
|
| 137 |
try:
|
| 138 |
+
with open(BACKUP_JSON, "r", encoding="utf-8") as f:
|
| 139 |
data = json.load(f)
|
| 140 |
if data:
|
| 141 |
conn = sqlite3.connect(DB_FILE, timeout=60.0)
|
|
|
|
| 143 |
conn.execute("INSERT OR REPLACE INTO users VALUES (?, ?)", (str(cid), json.dumps(udata)))
|
| 144 |
conn.commit()
|
| 145 |
conn.close()
|
| 146 |
+
print(f"✅ اعتبار {len(data)} کاربر با موفقیت بازیابی شد.")
|
| 147 |
+
except Exception as e:
|
| 148 |
+
print(f"❌ خطا در بازیابی اعتبارها: {e}")
|
| 149 |
+
|
| 150 |
+
def salvage_messages_from_corrupt_db():
|
| 151 |
+
if os.path.exists(CORRUPT_FILE):
|
| 152 |
+
print(f"🔍 در حال تلاش برای نجات شناسههای پیام از فایل {CORRUPT_FILE} ...")
|
| 153 |
+
try:
|
| 154 |
+
# وصل کردن فایل خراب به دیتابیس جدید
|
| 155 |
+
conn = sqlite3.connect(DB_FILE, timeout=60.0)
|
| 156 |
+
conn.execute(f"ATTACH DATABASE '{CORRUPT_FILE}' AS old_db")
|
| 157 |
+
|
| 158 |
+
# کپی کردن شناسهها (با استفاده از INSERT OR IGNORE که اگر خراب بود رد شود)
|
| 159 |
+
# این دستور تلاش میکند حتی اگر فایل Malformed باشد، ردیفهای سالم را بردارد
|
| 160 |
+
conn.execute("INSERT OR IGNORE INTO processed_messages SELECT message_id FROM old_db.processed_messages")
|
| 161 |
+
|
| 162 |
+
conn.commit()
|
| 163 |
+
conn.close()
|
| 164 |
+
print("✅ شناسههای پیام قدیمی با موفقیت نجات یافتند و به دیتابیس جدید منتقل شدند.")
|
| 165 |
except Exception as e:
|
| 166 |
+
print(f"⚠️ هشدار: برخی پیامها به دلیل خرابی شدید فایل اصلی قابل نجات نبودند، اما نگران نباشید، ربات دوباره آنها را شناسایی میکند. ارور: {e}")
|
| 167 |
|
| 168 |
def load_db():
|
| 169 |
global last_saved_state
|
|
|
|
| 177 |
db_dict[row[0]] = json.loads(row[1])
|
| 178 |
conn.close()
|
| 179 |
last_saved_state = copy.deepcopy(db_dict)
|
| 180 |
+
print(f"🚀 دیتابیس نهایی آماده شد. تعداد کاربران: {len(db_dict)}")
|
| 181 |
return db_dict
|
| 182 |
except Exception as e:
|
| 183 |
+
print(f"⚠️ ارور در لود نهایی: {e}")
|
| 184 |
return {}
|
| 185 |
|
| 186 |
def save_db(db_data):
|
|
|
|
| 193 |
if not changed: return
|
| 194 |
conn = sqlite3.connect(DB_FILE, timeout=60.0)
|
| 195 |
conn.execute('PRAGMA journal_mode=DELETE;')
|
| 196 |
+
conn.executemany("INSERT OR REPLACE INTO users (chat_id, user_data) VALUES (?, ?)", changed)
|
| 197 |
conn.commit()
|
| 198 |
conn.close()
|
| 199 |
for cid, _ in changed:
|