Opera8 commited on
Commit
d9beac3
·
verified ·
1 Parent(s): 3ac9a24

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +50 -49
main.py CHANGED
@@ -92,17 +92,17 @@ def gregorian_to_jalali(gy, gm, gd):
92
  return jy, jm, jd
93
 
94
  # ==============================================================================
95
- # 🟢 پارت 4: دیتابیس SQLite (نسخه فوق‌امن - بازسازی کامل برای رفع Malformed)
96
  # ==============================================================================
97
  import os
98
  import sqlite3
99
  import json
100
  import copy
101
 
102
- # تغییر نام فایل اصلی برای اطمینان از حذف کش‌های خراب سیستم‌عامل
103
- DB_FILE = "/data/users_v2.db"
104
- OLD_DB_FILE = "/data/users_db.db"
105
- BACKUP_JSON_FILE = "/data/users_db.json.bak"
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
- # حذف فایل‌های موقت WAL قدیمی اگر وجود دارند
114
- for f in [OLD_DB_FILE+"-wal", OLD_DB_FILE+"-shm", DB_FILE+"-wal", DB_FILE+"-shm"]:
115
- if os.path.exists(f):
116
- try: os.remove(f)
117
- except: pass
118
-
119
- # بررسی سلامت فایل فعلی
120
- should_rebuild = False
121
- if not os.path.exists(DB_FILE):
122
- should_rebuild = True
123
- else:
124
- try:
125
- conn = sqlite3.connect(DB_FILE, timeout=10)
126
- conn.execute("PRAGMA integrity_check").fetchone()
127
- conn.close()
128
- except:
129
- should_rebuild = True
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 restore_from_json():
152
- if os.path.exists(BACKUP_JSON_FILE):
153
- print("📥 در حال تزریق اشتراک‌ها به فایل جدید...")
154
  try:
155
- with open(BACKUP_JSON_FILE, "r", encoding="utf-8") as f:
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"✅ اطلاعات {len(data)} کاربر بازیابی شد.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
164
  except Exception as e:
165
- print(f" خطا در بازیابی بک‌آپ: {e}")
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" دیتابیس با موفقیت لود شد. کاربران: {len(db_dict)}")
180
  return db_dict
181
  except Exception as e:
182
- print(f"⚠️ ارور بحرانی در لود نهایی: {e}")
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: