Update main.py
Browse files
main.py
CHANGED
|
@@ -58,13 +58,14 @@ ADMIN_CODE = "3011"
|
|
| 58 |
BOT_GUID = None
|
| 59 |
|
| 60 |
# =======================================================
|
| 61 |
-
# سیستم ضد اسپم کاربر-محور
|
| 62 |
# =======================================================
|
| 63 |
user_message_times = {}
|
| 64 |
|
| 65 |
def is_user_spamming(chat_id):
|
| 66 |
now = time.time()
|
| 67 |
-
times = user_message_times.get(chat_id,[])
|
|
|
|
| 68 |
times =[t for t in times if now - t < 3.0]
|
| 69 |
times.append(now)
|
| 70 |
user_message_times[chat_id] = times
|
|
@@ -92,30 +93,35 @@ 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 |
-
# استفاده از نام جدید 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 |
|
| 109 |
def init_sqlite_db():
|
| 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 |
-
|
|
|
|
|
|
|
| 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()
|
|
@@ -123,9 +129,7 @@ def init_sqlite_db():
|
|
| 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:
|
|
@@ -139,6 +143,7 @@ def restore_users_from_json():
|
|
| 139 |
data = json.load(f)
|
| 140 |
if data:
|
| 141 |
conn = sqlite3.connect(DB_FILE, timeout=60.0)
|
|
|
|
| 142 |
for cid, udata in data.items():
|
| 143 |
conn.execute("INSERT OR REPLACE INTO users VALUES (?, ?)", (str(cid), json.dumps(udata)))
|
| 144 |
conn.commit()
|
|
@@ -151,75 +156,102 @@ 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"⚠
|
| 167 |
|
| 168 |
def load_db():
|
| 169 |
-
global last_saved_state
|
| 170 |
init_sqlite_db()
|
| 171 |
db_dict = {}
|
| 172 |
try:
|
| 173 |
conn = sqlite3.connect(DB_FILE, timeout=60.0)
|
|
|
|
| 174 |
cursor = conn.cursor()
|
|
|
|
|
|
|
| 175 |
cursor.execute("SELECT chat_id, user_data FROM users")
|
| 176 |
for row in cursor.fetchall():
|
| 177 |
db_dict[row[0]] = json.loads(row[1])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 178 |
conn.close()
|
| 179 |
last_saved_state = copy.deepcopy(db_dict)
|
| 180 |
-
print(f"🚀 دیتابیس
|
| 181 |
return db_dict
|
| 182 |
except Exception as e:
|
| 183 |
print(f"⚠️ ارور در لود نهایی: {e}")
|
| 184 |
return {}
|
| 185 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 186 |
def save_db(db_data):
|
| 187 |
global last_saved_state
|
| 188 |
-
|
| 189 |
-
|
| 190 |
-
|
| 191 |
-
|
| 192 |
-
|
| 193 |
-
|
| 194 |
-
|
| 195 |
-
|
| 196 |
-
|
| 197 |
-
|
| 198 |
-
|
| 199 |
-
|
| 200 |
-
|
| 201 |
-
except Exception as e:
|
| 202 |
-
print(f"❌ خطا در ذخیره: {e}")
|
| 203 |
|
|
|
|
| 204 |
def is_message_processed(message_id):
|
| 205 |
-
|
| 206 |
-
|
| 207 |
-
|
| 208 |
-
|
| 209 |
-
|
| 210 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 211 |
|
| 212 |
def mark_message_processed(message_id):
|
| 213 |
-
|
| 214 |
-
|
| 215 |
-
|
| 216 |
-
|
| 217 |
-
|
| 218 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 219 |
|
| 220 |
user_credits_db = load_db()
|
| 221 |
|
| 222 |
-
|
| 223 |
# ==============================================================================
|
| 224 |
# 🟢 پارت 5: توابع کد معرف، مدیریت سهمیه حساب کاربری و تبدیل اعداد
|
| 225 |
# ==============================================================================
|
|
@@ -252,8 +284,8 @@ def get_user_credits(chat_id):
|
|
| 252 |
"expire_date": None,
|
| 253 |
"last_reset": "",
|
| 254 |
"chat": 10,
|
| 255 |
-
"image":
|
| 256 |
-
"edit_image":
|
| 257 |
"podcast": 2,
|
| 258 |
"tts": 5,
|
| 259 |
"file": 1,
|
|
@@ -273,6 +305,8 @@ def get_user_credits(chat_id):
|
|
| 273 |
if "voice_conv" not in user_data: user_data["voice_conv"] = 3
|
| 274 |
if "voice_clone" not in user_data: user_data["voice_clone"] = 1
|
| 275 |
if "last_msg_id" not in user_data: user_data["last_msg_id"] = 0
|
|
|
|
|
|
|
| 276 |
|
| 277 |
is_premium = user_data.get("is_premium", False)
|
| 278 |
|
|
@@ -283,21 +317,34 @@ def get_user_credits(chat_id):
|
|
| 283 |
user_data["is_premium"] = False
|
| 284 |
user_data["expire_date"] = None
|
| 285 |
is_premium = False
|
|
|
|
|
|
|
|
|
|
| 286 |
except Exception:
|
| 287 |
pass
|
| 288 |
|
| 289 |
if not is_premium:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 290 |
if user_data.get("last_reset") != today_str:
|
| 291 |
user_data["last_reset"] = today_str
|
| 292 |
user_data["chat"] = 10
|
| 293 |
-
user_data["image"] =
|
| 294 |
-
user_data["edit_image"] =
|
| 295 |
user_data["podcast"] = 2
|
| 296 |
user_data["tts"] = 5
|
| 297 |
user_data["file"] = 1
|
| 298 |
user_data["stt"] = 5
|
| 299 |
user_data["voice_conv"] = 3
|
| 300 |
user_data["voice_clone"] = 1
|
|
|
|
|
|
|
|
|
|
| 301 |
save_db(user_credits_db)
|
| 302 |
|
| 303 |
return user_data
|
|
@@ -1125,8 +1172,28 @@ async def process_gemini(client, chat_id, prompt, file_bytes=None, file_name=Non
|
|
| 1125 |
async def process_image(client, chat_id, prompt, size_choice="1"):
|
| 1126 |
str_chat_id = str(chat_id).replace("`", "").replace("'", "").replace('"', "").strip()
|
| 1127 |
creds = get_user_credits(str_chat_id)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1128 |
if creds["image"] <= 0:
|
| 1129 |
-
|
|
|
|
| 1130 |
|
| 1131 |
if not HF_TOKENS: return await send_with_keyboard(client, chat_id, "❌ توکنهای هاگینگ فیس تنظیم نشدهاند.", False)
|
| 1132 |
|
|
@@ -1192,7 +1259,6 @@ async def process_image(client, chat_id, prompt, size_choice="1"):
|
|
| 1192 |
proc_msg = await send_with_keyboard(client, chat_id, f"🎨 در حال طراحی عکس...\n\n📏 **ابعاد:** {size_name}\n📝 **پرامپت ساخته شده:**\n`{short_preview}`\n\n(ممکن است چند ثانیه زمان ببرد)", False)
|
| 1193 |
|
| 1194 |
generated_image = None
|
| 1195 |
-
last_error_log = "هیچ اتصالی برقرار نشد."
|
| 1196 |
|
| 1197 |
for attempt in range(5):
|
| 1198 |
keys_to_try = HF_TOKENS.copy()
|
|
@@ -1208,7 +1274,6 @@ async def process_image(client, chat_id, prompt, size_choice="1"):
|
|
| 1208 |
)
|
| 1209 |
break
|
| 1210 |
except Exception as e:
|
| 1211 |
-
last_error_log = str(e)
|
| 1212 |
continue
|
| 1213 |
if generated_image: break
|
| 1214 |
await asyncio.sleep(2)
|
|
@@ -1221,7 +1286,9 @@ async def process_image(client, chat_id, prompt, size_choice="1"):
|
|
| 1221 |
except Exception: pass
|
| 1222 |
|
| 1223 |
if not generated_image:
|
| 1224 |
-
|
|
|
|
|
|
|
| 1225 |
|
| 1226 |
try:
|
| 1227 |
file_name = f"image_{uuid.uuid4().hex}.jpg"
|
|
@@ -1230,27 +1297,26 @@ async def process_image(client, chat_id, prompt, size_choice="1"):
|
|
| 1230 |
caption_text = f"🎨 تصویر شما با پرامپت هوشمند آماده شد!\n\n📏 ابعاد تصویر: {size_name}\n✨ ایده اولیه: {prompt}"
|
| 1231 |
|
| 1232 |
upload_result = False
|
| 1233 |
-
error_log_img = ""
|
| 1234 |
for up_att in range(3):
|
| 1235 |
res = await helper_upload_file(client, chat_id, file_name, "Image", caption_text)
|
| 1236 |
if res is True:
|
| 1237 |
upload_result = True
|
| 1238 |
break
|
| 1239 |
else:
|
| 1240 |
-
error_log_img = res
|
| 1241 |
await asyncio.sleep(4)
|
| 1242 |
|
| 1243 |
if upload_result is True:
|
| 1244 |
-
|
| 1245 |
-
|
| 1246 |
-
|
| 1247 |
else:
|
| 1248 |
-
await send_with_keyboard(client, chat_id,
|
| 1249 |
|
| 1250 |
if os.path.exists(file_name): os.remove(file_name)
|
| 1251 |
except Exception as e:
|
| 1252 |
await send_with_keyboard(client, chat_id, f"❌ خطا در ذخیره و ارسال عکس:\n{str(e)[:150]}", True)
|
| 1253 |
|
|
|
|
| 1254 |
# ==============================================================================
|
| 1255 |
# 🟢 پارت 15: توابع ترجمه و ویرایش عکس با هوش مصنوعی (Flux.2)
|
| 1256 |
# ==============================================================================
|
|
@@ -1290,8 +1356,28 @@ async def translate_text_aloha(prompt_text):
|
|
| 1290 |
async def process_image_edit(client, chat_id, image_bytes, prompt):
|
| 1291 |
str_chat_id = str(chat_id).replace("`", "").replace("'", "").replace('"', "").strip()
|
| 1292 |
creds = get_user_credits(str_chat_id)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1293 |
if creds["edit_image"] <= 0:
|
| 1294 |
-
|
|
|
|
| 1295 |
|
| 1296 |
if not HF_TOKENS:
|
| 1297 |
return await send_with_keyboard(client, chat_id, "❌ توکنهای هاگینگ فیس تنظیم نشدهاند.", False)
|
|
@@ -1303,7 +1389,6 @@ async def process_image_edit(client, chat_id, image_bytes, prompt):
|
|
| 1303 |
translated_prompt = prompt
|
| 1304 |
|
| 1305 |
generated_image = None
|
| 1306 |
-
last_error_log = "سرور پاسخ نداد."
|
| 1307 |
|
| 1308 |
for attempt in range(5):
|
| 1309 |
keys_to_try = HF_TOKENS.copy()
|
|
@@ -1318,7 +1403,6 @@ async def process_image_edit(client, chat_id, image_bytes, prompt):
|
|
| 1318 |
)
|
| 1319 |
break
|
| 1320 |
except Exception as e:
|
| 1321 |
-
last_error_log = str(e)
|
| 1322 |
continue
|
| 1323 |
if generated_image: break
|
| 1324 |
await asyncio.sleep(2)
|
|
@@ -1331,7 +1415,9 @@ async def process_image_edit(client, chat_id, image_bytes, prompt):
|
|
| 1331 |
except Exception: pass
|
| 1332 |
|
| 1333 |
if not generated_image:
|
| 1334 |
-
|
|
|
|
|
|
|
| 1335 |
|
| 1336 |
try:
|
| 1337 |
file_name = f"edited_flux_{uuid.uuid4().hex}.jpg"
|
|
@@ -1340,22 +1426,20 @@ async def process_image_edit(client, chat_id, image_bytes, prompt):
|
|
| 1340 |
caption_text = f"🪄 ویرایش عکس با هوش مصنوعی Flux.2 انجام شد!\n\n✨ تغییرات خواسته شده: {prompt}\n🔤 متن ارسال شده به هوش: {translated_prompt}"
|
| 1341 |
|
| 1342 |
upload_result = False
|
| 1343 |
-
error_log_edit = ""
|
| 1344 |
for up_att in range(3):
|
| 1345 |
res = await helper_upload_file(client, chat_id, file_name, "Image", caption_text)
|
| 1346 |
if res is True:
|
| 1347 |
upload_result = True
|
| 1348 |
break
|
| 1349 |
else:
|
| 1350 |
-
error_log_edit = res
|
| 1351 |
await asyncio.sleep(4)
|
| 1352 |
|
| 1353 |
if upload_result is True:
|
| 1354 |
-
|
| 1355 |
-
|
| 1356 |
-
|
| 1357 |
else:
|
| 1358 |
-
await send_with_keyboard(client, chat_id,
|
| 1359 |
|
| 1360 |
if os.path.exists(file_name): os.remove(file_name)
|
| 1361 |
except Exception as e:
|
|
@@ -1886,17 +1970,25 @@ async def ram_garbage_collector():
|
|
| 1886 |
await asyncio.sleep(1800) # هر ۳۰ دقیقه یکبار بررسی میکند
|
| 1887 |
now = time.time()
|
| 1888 |
try:
|
|
|
|
| 1889 |
for uid in list(user_states.keys()):
|
| 1890 |
-
# اگر کاربر بیش از ۱ ساعت (۳۶۰۰ ثانیه) با ربات کار نکرده بود
|
| 1891 |
if now - user_states[uid].get("last_time", 0) > 3600:
|
| 1892 |
-
# پاک کردن بایتهای فایلهای سنگین از رم سرور
|
| 1893 |
if user_states[uid].get("file_bytes") is not None:
|
| 1894 |
user_states[uid]["file_bytes"] = None
|
| 1895 |
if user_states[uid].get("ref_bytes") is not None:
|
| 1896 |
user_states[uid]["ref_bytes"] = None
|
| 1897 |
-
# خالی کردن تاریخچه چت برای آزادسازی رم (نگه داشتن ۵ پیام آخر)
|
| 1898 |
if len(user_states[uid].get("history",[])) > 5:
|
| 1899 |
user_states[uid]["history"] = user_states[uid]["history"][-5:]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1900 |
except Exception as e:
|
| 1901 |
pass
|
| 1902 |
|
|
@@ -1942,10 +2034,8 @@ else:
|
|
| 1942 |
# ===================================================================
|
| 1943 |
if msg_id:
|
| 1944 |
str_msg_id = str(msg_id).strip()
|
| 1945 |
-
# 1. اگر پیام قبلاً در دیتابیس ثبت شده بود، ربات بیدرنگ کار را متوقف میکند
|
| 1946 |
if is_message_processed(str_msg_id):
|
| 1947 |
return
|
| 1948 |
-
# 2. اگر پیام جدید بود، در همان لحظه در دیتابیس ذخیره میشود تا دیگر هرگز خوانده نشود
|
| 1949 |
mark_message_processed(str_msg_id)
|
| 1950 |
# ===================================================================
|
| 1951 |
|
|
@@ -1956,13 +2046,10 @@ else:
|
|
| 1956 |
if is_user_spamming(str_chat_id):
|
| 1957 |
return
|
| 1958 |
|
| 1959 |
-
# ===================================================================
|
| 1960 |
-
# 🟢 ثبت آخرین زمان فعالیت کاربر برای سیستم پاکسازی رم
|
| 1961 |
-
# ===================================================================
|
| 1962 |
if str_chat_id not in user_states:
|
| 1963 |
user_states[str_chat_id] = {"mode": None, "text": "", "history":[], "file_bytes": None, "file_name": None, "last_time": time.time()}
|
| 1964 |
else:
|
| 1965 |
-
user_states[str_chat_id]["last_time"] = time.time()
|
| 1966 |
|
| 1967 |
if user_text_lower.startswith(f"{ADMIN_CODE} pro=") or user_text_lower.startswith(f"{ADMIN_CODE}pro="):
|
| 1968 |
parts = user_text_str.split("=", 1)
|
|
@@ -1975,8 +2062,8 @@ else:
|
|
| 1975 |
"expire_date": None,
|
| 1976 |
"last_reset": "",
|
| 1977 |
"chat": 10,
|
| 1978 |
-
"image":
|
| 1979 |
-
"edit_image":
|
| 1980 |
"podcast": 2,
|
| 1981 |
"tts": 5,
|
| 1982 |
"file": 1,
|
|
@@ -1995,8 +2082,8 @@ else:
|
|
| 1995 |
user_credits_db[target_id]["expire_date"] = expire_time.isoformat()
|
| 1996 |
|
| 1997 |
user_credits_db[target_id]["chat"] = 999999
|
| 1998 |
-
user_credits_db[target_id]["image"] =
|
| 1999 |
-
user_credits_db[target_id]["edit_image"] =
|
| 2000 |
user_credits_db[target_id]["podcast"] = 999999
|
| 2001 |
user_credits_db[target_id]["tts"] = 999999
|
| 2002 |
user_credits_db[target_id]["file"] = 999999
|
|
@@ -2020,6 +2107,8 @@ else:
|
|
| 2020 |
user_credits_db[target_id]["is_premium"] = False
|
| 2021 |
user_credits_db[target_id]["expire_date"] = None
|
| 2022 |
user_credits_db[target_id]["last_reset"] = ""
|
|
|
|
|
|
|
| 2023 |
save_db(user_credits_db)
|
| 2024 |
await send_with_keyboard(client, chat_id, f"✅ اشتراک کاربر `{target_id}` لغو شد و به رایگان تبدیل گشت.", False)
|
| 2025 |
try:
|
|
@@ -2257,8 +2346,8 @@ else:
|
|
| 2257 |
🎙 ساخت پادکست: نامحدود ∞
|
| 2258 |
📁 تحلیل فایل و سند: نامحدود ∞
|
| 2259 |
📝 تبدیل فایل صوتی به متن: نامحدود ∞
|
| 2260 |
-
🪄 ویرایش تصویر:
|
| 2261 |
-
🎨 تولید تصویر:
|
| 2262 |
━━━━━━━━━━━━━━━━━━━
|
| 2263 |
|
| 2264 |
💳 **هزینه اشتراک یک ماهه:** 250 هزار تومان
|
|
@@ -2306,6 +2395,22 @@ else:
|
|
| 2306 |
return
|
| 2307 |
|
| 2308 |
if user_text_str in["/edit_image", "ویرایش تصاویر 🪄"]:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2309 |
user_states[str_chat_id]["mode"] = "image_edit_waiting_for_image"
|
| 2310 |
user_states[str_chat_id]["file_bytes"] = None
|
| 2311 |
await send_with_keyboard(client, chat_id, "🪄 به بخش **ویرایش عکس (Flux.2)** خوش آمدید.\n\nلطفاً ابتدا عکسی که میخواهید ویرایش کنید را بفرستید:\n(برای خروج دکمه «برگشت♻️» را بزنید)", True)
|
|
@@ -2321,9 +2426,6 @@ else:
|
|
| 2321 |
await send_with_keyboard(client, chat_id, "📻 شما وارد بخش **ساخت پادکست** شدید.\n\nلطفاً موضوع پادکست خود را بفرستید.\nمثال: درباره تاریخچه پیدایش قهوه با ۳ گوینده یک پادکست جذاب بساز . همچنین این قسمت متصل به مدل زبانی است و درخواست هارو قبل از ساخت درک میکنه. میتوانید مقاله کامل یک سایت بفرستید با تبلیغات یا هرچی، هوش مصنوعی متن مقاله رو استخراج و پادکست براتون میسازه . در توضیحات امکان مشخص کردن تعداد گوینده به همراه اسم شون نیز از سمت شما امکان پذیر است.\n\n(برای خروج دکمه «برگشت♻️» را بزنید)", True)
|
| 2322 |
return
|
| 2323 |
|
| 2324 |
-
# ===============================================
|
| 2325 |
-
# بخشهای تغییر صدا و کلون کردن صدا
|
| 2326 |
-
# ===============================================
|
| 2327 |
if user_text_str in["/vc", "تغییر صدا 🎙️"]:
|
| 2328 |
user_states[str_chat_id]["mode"] = "vc_waiting_for_voice"
|
| 2329 |
user_states[str_chat_id]["file_bytes"] = None
|
|
@@ -2350,7 +2452,6 @@ else:
|
|
| 2350 |
*(برای خروج دکمه «برگشت♻️» را بزنید)*"""
|
| 2351 |
await send_with_keyboard(client, chat_id, clone_text, True)
|
| 2352 |
return
|
| 2353 |
-
# ===============================================
|
| 2354 |
|
| 2355 |
if user_text_str in["/file", "تحلیل فایل 📁"]:
|
| 2356 |
user_states[str_chat_id]["mode"] = "file_waiting_for_file"
|
|
@@ -2419,8 +2520,8 @@ else:
|
|
| 2419 |
|
| 2420 |
inviter_data["expire_date"] = new_exp.isoformat()
|
| 2421 |
inviter_data["chat"] = 999999
|
| 2422 |
-
inviter_data["image"] =
|
| 2423 |
-
inviter_data["edit_image"] =
|
| 2424 |
inviter_data["podcast"] = 999999
|
| 2425 |
inviter_data["tts"] = 999999
|
| 2426 |
inviter_data["file"] = 999999
|
|
@@ -2591,9 +2692,6 @@ else:
|
|
| 2591 |
await send_with_keyboard(client, chat_id, "⚠️ لطفاً موضوع مقاله خود را به صورت متنی بفرستید.", False)
|
| 2592 |
return
|
| 2593 |
|
| 2594 |
-
# ===============================================
|
| 2595 |
-
# بخشهای تغییر صدا و کلون صدا
|
| 2596 |
-
# ===============================================
|
| 2597 |
elif current_mode == "vc_waiting_for_voice":
|
| 2598 |
if not is_file: return await send_with_keyboard(client, chat_id, "⚠️ لطفاً یک فایل صوتی یا ویس ارسال کنید.", False)
|
| 2599 |
await send_with_keyboard(client, chat_id, "📥 در حال دانلود فایل صوتی شما...", False)
|
|
@@ -2631,7 +2729,6 @@ else:
|
|
| 2631 |
asyncio.create_task(process_standard_vc_job(client, chat_id, src_bytes, ref_bytes, model["name"], "voice_conv"))
|
| 2632 |
|
| 2633 |
elif choice in LEGACY_MODELS:
|
| 2634 |
-
# اگر شماره مدل ۸ نبود و اعتبار هم صفر بود، ارور بده
|
| 2635 |
if choice != "8" and creds["voice_conv"] <= 0:
|
| 2636 |
return await send_with_keyboard(client, chat_id, "❌ سهمیه تغییر صدای شما تمام شده است. لطفاً از منوی اصلی وارد بخش «خرید اشتراک 💎» شوید.", False)
|
| 2637 |
|
|
@@ -2700,10 +2797,8 @@ if __name__ == "__main__":
|
|
| 2700 |
if bot_token:
|
| 2701 |
loop = asyncio.get_event_loop()
|
| 2702 |
|
| 2703 |
-
# 🟢 تونلهای پرسرعت: ارتقا از 32 کارگر به 256 کارگر برای پاسخگویی همزمان به هزاران نفر
|
| 2704 |
loop.set_default_executor(concurrent.futures.ThreadPoolExecutor(max_workers=256))
|
| 2705 |
|
| 2706 |
-
# 🟢 روشن کردن سیستم پاکسازی هوشمند رم در پسزمینه
|
| 2707 |
loop.create_task(ram_garbage_collector())
|
| 2708 |
|
| 2709 |
print("🚀 ربات آلفا پرو (نسخه صنعتی + دیتابیس هوشمند + پاکسازی رم + 256 تونل همزمان) روشن شد...")
|
|
|
|
| 58 |
BOT_GUID = None
|
| 59 |
|
| 60 |
# =======================================================
|
| 61 |
+
# سیستم ضد اسپم کاربر-محور (بهینه شده برای جلوگیری از نشت مموری)
|
| 62 |
# =======================================================
|
| 63 |
user_message_times = {}
|
| 64 |
|
| 65 |
def is_user_spamming(chat_id):
|
| 66 |
now = time.time()
|
| 67 |
+
times = user_message_times.get(chat_id, [])
|
| 68 |
+
# فقط زمانهای ۳ ثانیه اخیر رو نگه دار
|
| 69 |
times =[t for t in times if now - t < 3.0]
|
| 70 |
times.append(now)
|
| 71 |
user_message_times[chat_id] = times
|
|
|
|
| 93 |
return jy, jm, jd
|
| 94 |
|
| 95 |
# ==============================================================================
|
| 96 |
+
# 🟢 پارت 4: دیتابیس SQLite (نسخه فوقسریع Non-Blocking با سیستم Threading)
|
| 97 |
# ==============================================================================
|
| 98 |
import os
|
| 99 |
import sqlite3
|
| 100 |
import json
|
| 101 |
import copy
|
| 102 |
+
import threading
|
| 103 |
|
|
|
|
| 104 |
DB_FILE = "/data/users_v3.db"
|
| 105 |
+
CORRUPT_FILE = "/data/users_db.db"
|
| 106 |
+
BACKUP_JSON = "/data/users_db.json.bak"
|
| 107 |
|
| 108 |
last_saved_state = {}
|
| 109 |
+
# حافظه کش برای پیامهای پردازش شده جهت جلوگیری از قفل شدن دیتابیس
|
| 110 |
+
recent_messages_dict = {}
|
| 111 |
+
# قفلها برای جلوگیری از تداخل رشتهها (Threads)
|
| 112 |
+
db_lock = threading.Lock()
|
| 113 |
+
msg_cache_lock = threading.Lock()
|
| 114 |
|
| 115 |
def init_sqlite_db():
|
| 116 |
try:
|
| 117 |
os.makedirs(os.path.dirname(DB_FILE), exist_ok=True)
|
|
|
|
|
|
|
| 118 |
is_first_run = not os.path.exists(DB_FILE)
|
| 119 |
|
| 120 |
conn = sqlite3.connect(DB_FILE, timeout=60.0)
|
| 121 |
cursor = conn.cursor()
|
| 122 |
+
# 🚀 تغییر بسیار مهم: استفاده از WAL به جای DELETE برای پشتیبانی از هزاران کاربر همزمان
|
| 123 |
+
cursor.execute('PRAGMA journal_mode=WAL;')
|
| 124 |
+
cursor.execute('PRAGMA synchronous=NORMAL;')
|
| 125 |
cursor.execute('CREATE TABLE IF NOT EXISTS users (chat_id TEXT PRIMARY KEY, user_data TEXT)')
|
| 126 |
cursor.execute('CREATE TABLE IF NOT EXISTS processed_messages (message_id TEXT PRIMARY KEY)')
|
| 127 |
conn.commit()
|
|
|
|
| 129 |
|
| 130 |
if is_first_run:
|
| 131 |
print("🚨 عملیات نجات آغاز شد...")
|
|
|
|
| 132 |
restore_users_from_json()
|
|
|
|
| 133 |
salvage_messages_from_corrupt_db()
|
| 134 |
|
| 135 |
except Exception as e:
|
|
|
|
| 143 |
data = json.load(f)
|
| 144 |
if data:
|
| 145 |
conn = sqlite3.connect(DB_FILE, timeout=60.0)
|
| 146 |
+
conn.execute('PRAGMA journal_mode=WAL;')
|
| 147 |
for cid, udata in data.items():
|
| 148 |
conn.execute("INSERT OR REPLACE INTO users VALUES (?, ?)", (str(cid), json.dumps(udata)))
|
| 149 |
conn.commit()
|
|
|
|
| 156 |
if os.path.exists(CORRUPT_FILE):
|
| 157 |
print(f"🔍 در حال تلاش برای نجات شناسههای پیام از فایل {CORRUPT_FILE} ...")
|
| 158 |
try:
|
|
|
|
| 159 |
conn = sqlite3.connect(DB_FILE, timeout=60.0)
|
| 160 |
+
conn.execute('PRAGMA journal_mode=WAL;')
|
| 161 |
conn.execute(f"ATTACH DATABASE '{CORRUPT_FILE}' AS old_db")
|
|
|
|
|
|
|
|
|
|
| 162 |
conn.execute("INSERT OR IGNORE INTO processed_messages SELECT message_id FROM old_db.processed_messages")
|
|
|
|
| 163 |
conn.commit()
|
| 164 |
conn.close()
|
| 165 |
+
print("✅ شناسههای پیام قدیمی نجات یافتند.")
|
| 166 |
except Exception as e:
|
| 167 |
+
print(f"⚠️ هشدار فایل قدیمی: {e}")
|
| 168 |
|
| 169 |
def load_db():
|
| 170 |
+
global last_saved_state, recent_messages_dict
|
| 171 |
init_sqlite_db()
|
| 172 |
db_dict = {}
|
| 173 |
try:
|
| 174 |
conn = sqlite3.connect(DB_FILE, timeout=60.0)
|
| 175 |
+
conn.execute('PRAGMA journal_mode=WAL;')
|
| 176 |
cursor = conn.cursor()
|
| 177 |
+
|
| 178 |
+
# لود کردن کاربران
|
| 179 |
cursor.execute("SELECT chat_id, user_data FROM users")
|
| 180 |
for row in cursor.fetchall():
|
| 181 |
db_dict[row[0]] = json.loads(row[1])
|
| 182 |
+
|
| 183 |
+
# 🚀 لود کردن 15 هزار پیام آخر به داخل RAM برای سرعت فوق العاده
|
| 184 |
+
cursor.execute("SELECT message_id FROM processed_messages ORDER BY ROWID DESC LIMIT 15000")
|
| 185 |
+
for row in cursor.fetchall():
|
| 186 |
+
recent_messages_dict[row[0]] = True
|
| 187 |
+
|
| 188 |
conn.close()
|
| 189 |
last_saved_state = copy.deepcopy(db_dict)
|
| 190 |
+
print(f"🚀 دیتابیس آماده شد. تعداد کاربران: {len(db_dict)} | پیامهای کش شده در رم: {len(recent_messages_dict)}")
|
| 191 |
return db_dict
|
| 192 |
except Exception as e:
|
| 193 |
print(f"⚠️ ارور در لود نهایی: {e}")
|
| 194 |
return {}
|
| 195 |
|
| 196 |
+
# --- سیستم ذخیره سازی در پسزمینه (بدون معطل کردن ربات) ---
|
| 197 |
+
def background_save_worker(changed_data):
|
| 198 |
+
with db_lock:
|
| 199 |
+
try:
|
| 200 |
+
conn = sqlite3.connect(DB_FILE, timeout=60.0)
|
| 201 |
+
conn.execute('PRAGMA journal_mode=WAL;')
|
| 202 |
+
conn.execute('PRAGMA synchronous=NORMAL;')
|
| 203 |
+
conn.executemany("INSERT OR REPLACE INTO users (chat_id, user_data) VALUES (?, ?)", changed_data)
|
| 204 |
+
conn.commit()
|
| 205 |
+
conn.close()
|
| 206 |
+
except Exception as e:
|
| 207 |
+
print(f"❌ خطا در ذخیره بکگراند: {e}")
|
| 208 |
+
|
| 209 |
def save_db(db_data):
|
| 210 |
global last_saved_state
|
| 211 |
+
changed =[]
|
| 212 |
+
for cid, data in db_data.items():
|
| 213 |
+
if cid not in last_saved_state or last_saved_state[cid] != data:
|
| 214 |
+
changed.append((str(cid), json.dumps(data, ensure_ascii=False)))
|
| 215 |
+
|
| 216 |
+
if not changed: return
|
| 217 |
+
|
| 218 |
+
# آپدیت وضعیت استیت محلی
|
| 219 |
+
for cid, _ in changed:
|
| 220 |
+
last_saved_state[cid] = copy.deepcopy(db_data[cid])
|
| 221 |
+
|
| 222 |
+
# 🚀 پرتاب عملیات سنگین به یک پردازشگر دیگر تا ربات متوقف نشود
|
| 223 |
+
threading.Thread(target=background_save_worker, args=(changed,), daemon=True).start()
|
|
|
|
|
|
|
| 224 |
|
| 225 |
+
# --- سیستم بررسی پیام تکراری (کاملا منتقل شده به RAM سرور) ---
|
| 226 |
def is_message_processed(message_id):
|
| 227 |
+
# چک کردن داخل RAM (زمان اجرا: 0.0001 ثانیه)
|
| 228 |
+
return str(message_id) in recent_messages_dict
|
| 229 |
+
|
| 230 |
+
def background_mark_message(msg_id):
|
| 231 |
+
with db_lock:
|
| 232 |
+
try:
|
| 233 |
+
conn = sqlite3.connect(DB_FILE, timeout=30.0)
|
| 234 |
+
conn.execute('PRAGMA journal_mode=WAL;')
|
| 235 |
+
conn.execute("INSERT OR IGNORE INTO processed_messages VALUES (?)", (msg_id,))
|
| 236 |
+
conn.commit()
|
| 237 |
+
conn.close()
|
| 238 |
+
except: pass
|
| 239 |
|
| 240 |
def mark_message_processed(message_id):
|
| 241 |
+
msg_id_str = str(message_id)
|
| 242 |
+
with msg_cache_lock:
|
| 243 |
+
# ثبت در RAM
|
| 244 |
+
recent_messages_dict[msg_id_str] = True
|
| 245 |
+
# جلوگیری از پر شدن بیش از حد RAM
|
| 246 |
+
if len(recent_messages_dict) > 15000:
|
| 247 |
+
oldest_key = next(iter(recent_messages_dict))
|
| 248 |
+
del recent_messages_dict[oldest_key]
|
| 249 |
+
|
| 250 |
+
# ذخیره در دیتابیس به صورت پسزمینه
|
| 251 |
+
threading.Thread(target=background_mark_message, args=(msg_id_str,), daemon=True).start()
|
| 252 |
|
| 253 |
user_credits_db = load_db()
|
| 254 |
|
|
|
|
| 255 |
# ==============================================================================
|
| 256 |
# 🟢 پارت 5: توابع کد معرف، مدیریت سهمیه حساب کاربری و تبدیل اعداد
|
| 257 |
# ==============================================================================
|
|
|
|
| 284 |
"expire_date": None,
|
| 285 |
"last_reset": "",
|
| 286 |
"chat": 10,
|
| 287 |
+
"image": 0,
|
| 288 |
+
"edit_image": 0,
|
| 289 |
"podcast": 2,
|
| 290 |
"tts": 5,
|
| 291 |
"file": 1,
|
|
|
|
| 305 |
if "voice_conv" not in user_data: user_data["voice_conv"] = 3
|
| 306 |
if "voice_clone" not in user_data: user_data["voice_clone"] = 1
|
| 307 |
if "last_msg_id" not in user_data: user_data["last_msg_id"] = 0
|
| 308 |
+
if "image" not in user_data: user_data["image"] = 0
|
| 309 |
+
if "edit_image" not in user_data: user_data["edit_image"] = 0
|
| 310 |
|
| 311 |
is_premium = user_data.get("is_premium", False)
|
| 312 |
|
|
|
|
| 317 |
user_data["is_premium"] = False
|
| 318 |
user_data["expire_date"] = None
|
| 319 |
is_premium = False
|
| 320 |
+
user_data["image"] = 0
|
| 321 |
+
user_data["edit_image"] = 0
|
| 322 |
+
save_db(user_credits_db)
|
| 323 |
except Exception:
|
| 324 |
pass
|
| 325 |
|
| 326 |
if not is_premium:
|
| 327 |
+
changed = False
|
| 328 |
+
# صفر کردن سهمیه عکس کاربرانی که از دیروز اعتبار رایگان جا مانده دارند
|
| 329 |
+
if user_data.get("image", 0) > 0 or user_data.get("edit_image", 0) > 0:
|
| 330 |
+
user_data["image"] = 0
|
| 331 |
+
user_data["edit_image"] = 0
|
| 332 |
+
changed = True
|
| 333 |
+
|
| 334 |
if user_data.get("last_reset") != today_str:
|
| 335 |
user_data["last_reset"] = today_str
|
| 336 |
user_data["chat"] = 10
|
| 337 |
+
user_data["image"] = 0
|
| 338 |
+
user_data["edit_image"] = 0
|
| 339 |
user_data["podcast"] = 2
|
| 340 |
user_data["tts"] = 5
|
| 341 |
user_data["file"] = 1
|
| 342 |
user_data["stt"] = 5
|
| 343 |
user_data["voice_conv"] = 3
|
| 344 |
user_data["voice_clone"] = 1
|
| 345 |
+
changed = True
|
| 346 |
+
|
| 347 |
+
if changed:
|
| 348 |
save_db(user_credits_db)
|
| 349 |
|
| 350 |
return user_data
|
|
|
|
| 1172 |
async def process_image(client, chat_id, prompt, size_choice="1"):
|
| 1173 |
str_chat_id = str(chat_id).replace("`", "").replace("'", "").replace('"', "").strip()
|
| 1174 |
creds = get_user_credits(str_chat_id)
|
| 1175 |
+
|
| 1176 |
+
is_prem = creds.get("is_premium", False)
|
| 1177 |
+
|
| 1178 |
+
# === بررسی کاربران رایگان ===
|
| 1179 |
+
if not is_prem:
|
| 1180 |
+
msg = """کاربر گرامی،
|
| 1181 |
+
|
| 1182 |
+
ضمن تشکر از توجه شما، به اطلاع میرساند که قابلیت ساخت تصاویر در حال حاضر به صورت رایگان در دسترس نمیباشد. این سرویس به دلیل نیاز به منابع پردازشی بالا، جزو خدمات ویژه و نیازمند تهیه اشتراک است.
|
| 1183 |
+
|
| 1184 |
+
با این حال، شما میتوانید از تست رایگان و امکانات سایر بخشهای پلتفرم ما بهرهمند شوید.
|
| 1185 |
+
|
| 1186 |
+
ما همواره در تلاش برای افزایش منابع و اضافه کردن خدمات رایگان بیشتر به کاربران عزیز هستیم.
|
| 1187 |
+
|
| 1188 |
+
در حال حاضر، میتوانید از سایر بخشهای رایگان موجود استفاده کنید و یا برای دسترسی کامل و نامحدود به تمامی قابلیتها (از جمله ساخت تصاویر)، اشتراک تهیه نمایید.
|
| 1189 |
+
|
| 1190 |
+
از صبوری و همراهی شما سپاسگزاریم."""
|
| 1191 |
+
return await send_with_keyboard(client, chat_id, msg, False)
|
| 1192 |
+
|
| 1193 |
+
# === بررسی اعتبار کاربران پولی ===
|
| 1194 |
if creds["image"] <= 0:
|
| 1195 |
+
msg = "⚠️ **اعتبار شما برای این بخش تمام شده است!**\nاز بقیه بخشها میتوانید نامحدود استفاده کنید. در حال افزایش منابع برای این بخش هستیم."
|
| 1196 |
+
return await send_with_keyboard(client, chat_id, msg, False)
|
| 1197 |
|
| 1198 |
if not HF_TOKENS: return await send_with_keyboard(client, chat_id, "❌ توکنهای هاگینگ فیس تنظیم نشدهاند.", False)
|
| 1199 |
|
|
|
|
| 1259 |
proc_msg = await send_with_keyboard(client, chat_id, f"🎨 در حال طراحی عکس...\n\n📏 **ابعاد:** {size_name}\n📝 **پرامپت ساخته شده:**\n`{short_preview}`\n\n(ممکن است چند ثانیه زمان ببرد)", False)
|
| 1260 |
|
| 1261 |
generated_image = None
|
|
|
|
| 1262 |
|
| 1263 |
for attempt in range(5):
|
| 1264 |
keys_to_try = HF_TOKENS.copy()
|
|
|
|
| 1274 |
)
|
| 1275 |
break
|
| 1276 |
except Exception as e:
|
|
|
|
| 1277 |
continue
|
| 1278 |
if generated_image: break
|
| 1279 |
await asyncio.sleep(2)
|
|
|
|
| 1286 |
except Exception: pass
|
| 1287 |
|
| 1288 |
if not generated_image:
|
| 1289 |
+
# === پیام اختصاصی جایگزین ارور اسپیس ===
|
| 1290 |
+
error_msg = "⚠️ **منابع این بخش در حال افزایش است!**\nموقتاً این بخش در حال ارتقا است. فعلاً اعتباری از شما کم نشد، بهزودی این بخش در دسترس قرار خواهد گرفت."
|
| 1291 |
+
return await send_with_keyboard(client, chat_id, error_msg, True)
|
| 1292 |
|
| 1293 |
try:
|
| 1294 |
file_name = f"image_{uuid.uuid4().hex}.jpg"
|
|
|
|
| 1297 |
caption_text = f"🎨 تصویر شما با پرامپت هوشمند آماده شد!\n\n📏 ابعاد تصویر: {size_name}\n✨ ایده اولیه: {prompt}"
|
| 1298 |
|
| 1299 |
upload_result = False
|
|
|
|
| 1300 |
for up_att in range(3):
|
| 1301 |
res = await helper_upload_file(client, chat_id, file_name, "Image", caption_text)
|
| 1302 |
if res is True:
|
| 1303 |
upload_result = True
|
| 1304 |
break
|
| 1305 |
else:
|
|
|
|
| 1306 |
await asyncio.sleep(4)
|
| 1307 |
|
| 1308 |
if upload_result is True:
|
| 1309 |
+
# کسر اعتبار از کاربران پولی
|
| 1310 |
+
user_credits_db[str_chat_id]["image"] -= 1
|
| 1311 |
+
save_db(user_credits_db)
|
| 1312 |
else:
|
| 1313 |
+
await send_with_keyboard(client, chat_id, "❌ عکس ساخته شد اما آپلود در روبیکا با خطا مواجه شد.", True)
|
| 1314 |
|
| 1315 |
if os.path.exists(file_name): os.remove(file_name)
|
| 1316 |
except Exception as e:
|
| 1317 |
await send_with_keyboard(client, chat_id, f"❌ خطا در ذخیره و ارسال عکس:\n{str(e)[:150]}", True)
|
| 1318 |
|
| 1319 |
+
|
| 1320 |
# ==============================================================================
|
| 1321 |
# 🟢 پارت 15: توابع ترجمه و ویرایش عکس با هوش مصنوعی (Flux.2)
|
| 1322 |
# ==============================================================================
|
|
|
|
| 1356 |
async def process_image_edit(client, chat_id, image_bytes, prompt):
|
| 1357 |
str_chat_id = str(chat_id).replace("`", "").replace("'", "").replace('"', "").strip()
|
| 1358 |
creds = get_user_credits(str_chat_id)
|
| 1359 |
+
|
| 1360 |
+
is_prem = creds.get("is_premium", False)
|
| 1361 |
+
|
| 1362 |
+
# === بررسی کاربران رایگان (جهت اطمینان در لایه دوم) ===
|
| 1363 |
+
if not is_prem:
|
| 1364 |
+
msg = """کاربر گرامی،
|
| 1365 |
+
|
| 1366 |
+
ضمن تشکر از توجه شما، به اطلاع میرساند که قابلیت ویرایش تصاویر در حال حاضر به صورت رایگان در دسترس نمیباشد. این سرویس به دلیل نیاز به منابع پردازشی بالا، جزو خدمات ویژه و نیازمند تهیه اشتراک است.
|
| 1367 |
+
|
| 1368 |
+
با این حال، شما میتوانید از تست رایگان و امکانات سایر بخشهای پلتفرم ما بهرهمند شوید.
|
| 1369 |
+
|
| 1370 |
+
ما همواره در تلاش برای افزایش منابع و اضافه کردن خدمات رایگان بیشتر به کاربران عزیز هستیم.
|
| 1371 |
+
|
| 1372 |
+
در حال حاضر، میتوانید از سایر بخشهای رایگان موجود استفاده کنید و یا برای دسترسی کامل و نامحدود به تمامی قابلیتها (از جمله ویرایش تصاویر)، اشتراک تهیه نمایید.
|
| 1373 |
+
|
| 1374 |
+
از صبوری و همراهی شما سپاسگزاریم."""
|
| 1375 |
+
return await send_with_keyboard(client, chat_id, msg, False)
|
| 1376 |
+
|
| 1377 |
+
# === بررسی اعتبار کاربران پولی ===
|
| 1378 |
if creds["edit_image"] <= 0:
|
| 1379 |
+
msg = "⚠️ **اعتبار شما برای این بخش تمام شده است!**\nاز بقیه بخشها میتوانید نامحدود استفاده کنید. در حال افزایش منابع برای این بخش هستیم."
|
| 1380 |
+
return await send_with_keyboard(client, chat_id, msg, False)
|
| 1381 |
|
| 1382 |
if not HF_TOKENS:
|
| 1383 |
return await send_with_keyboard(client, chat_id, "❌ توکنهای هاگینگ فیس تنظیم نشدهاند.", False)
|
|
|
|
| 1389 |
translated_prompt = prompt
|
| 1390 |
|
| 1391 |
generated_image = None
|
|
|
|
| 1392 |
|
| 1393 |
for attempt in range(5):
|
| 1394 |
keys_to_try = HF_TOKENS.copy()
|
|
|
|
| 1403 |
)
|
| 1404 |
break
|
| 1405 |
except Exception as e:
|
|
|
|
| 1406 |
continue
|
| 1407 |
if generated_image: break
|
| 1408 |
await asyncio.sleep(2)
|
|
|
|
| 1415 |
except Exception: pass
|
| 1416 |
|
| 1417 |
if not generated_image:
|
| 1418 |
+
# === پیام اختصاصی جایگزین ارور اسپیس ===
|
| 1419 |
+
error_msg = "⚠️ **منابع این بخش در حال افزایش است!**\nموقتاً این بخش در حال ارتقا است. فعلاً اعتباری از شما کم نشد، بهزودی این بخش در دسترس قرار خواهد گرفت."
|
| 1420 |
+
return await send_with_keyboard(client, chat_id, error_msg, True)
|
| 1421 |
|
| 1422 |
try:
|
| 1423 |
file_name = f"edited_flux_{uuid.uuid4().hex}.jpg"
|
|
|
|
| 1426 |
caption_text = f"🪄 ویرایش عکس با هوش مصنوعی Flux.2 انجام شد!\n\n✨ تغییرات خواسته شده: {prompt}\n🔤 متن ارسال شده به هوش: {translated_prompt}"
|
| 1427 |
|
| 1428 |
upload_result = False
|
|
|
|
| 1429 |
for up_att in range(3):
|
| 1430 |
res = await helper_upload_file(client, chat_id, file_name, "Image", caption_text)
|
| 1431 |
if res is True:
|
| 1432 |
upload_result = True
|
| 1433 |
break
|
| 1434 |
else:
|
|
|
|
| 1435 |
await asyncio.sleep(4)
|
| 1436 |
|
| 1437 |
if upload_result is True:
|
| 1438 |
+
# کسر اعتبار از کاربران پولی
|
| 1439 |
+
user_credits_db[str_chat_id]["edit_image"] -= 1
|
| 1440 |
+
save_db(user_credits_db)
|
| 1441 |
else:
|
| 1442 |
+
await send_with_keyboard(client, chat_id, "❌ عکس ساخته شد اما خطا در ارسال به روبیکا رخ داد.", True)
|
| 1443 |
|
| 1444 |
if os.path.exists(file_name): os.remove(file_name)
|
| 1445 |
except Exception as e:
|
|
|
|
| 1970 |
await asyncio.sleep(1800) # هر ۳۰ دقیقه یکبار بررسی میکند
|
| 1971 |
now = time.time()
|
| 1972 |
try:
|
| 1973 |
+
# پاکسازی یوزراستیتها
|
| 1974 |
for uid in list(user_states.keys()):
|
|
|
|
| 1975 |
if now - user_states[uid].get("last_time", 0) > 3600:
|
|
|
|
| 1976 |
if user_states[uid].get("file_bytes") is not None:
|
| 1977 |
user_states[uid]["file_bytes"] = None
|
| 1978 |
if user_states[uid].get("ref_bytes") is not None:
|
| 1979 |
user_states[uid]["ref_bytes"] = None
|
|
|
|
| 1980 |
if len(user_states[uid].get("history",[])) > 5:
|
| 1981 |
user_states[uid]["history"] = user_states[uid]["history"][-5:]
|
| 1982 |
+
|
| 1983 |
+
# پاکسازی کش زمان پیامها (ضد اسپم) که استفاده نمیشوند
|
| 1984 |
+
for uid in list(user_message_times.keys()):
|
| 1985 |
+
times = user_message_times[uid]
|
| 1986 |
+
valid_times =[t for t in times if now - t < 3.0]
|
| 1987 |
+
if not valid_times:
|
| 1988 |
+
del user_message_times[uid]
|
| 1989 |
+
else:
|
| 1990 |
+
user_message_times[uid] = valid_times
|
| 1991 |
+
|
| 1992 |
except Exception as e:
|
| 1993 |
pass
|
| 1994 |
|
|
|
|
| 2034 |
# ===================================================================
|
| 2035 |
if msg_id:
|
| 2036 |
str_msg_id = str(msg_id).strip()
|
|
|
|
| 2037 |
if is_message_processed(str_msg_id):
|
| 2038 |
return
|
|
|
|
| 2039 |
mark_message_processed(str_msg_id)
|
| 2040 |
# ===================================================================
|
| 2041 |
|
|
|
|
| 2046 |
if is_user_spamming(str_chat_id):
|
| 2047 |
return
|
| 2048 |
|
|
|
|
|
|
|
|
|
|
| 2049 |
if str_chat_id not in user_states:
|
| 2050 |
user_states[str_chat_id] = {"mode": None, "text": "", "history":[], "file_bytes": None, "file_name": None, "last_time": time.time()}
|
| 2051 |
else:
|
| 2052 |
+
user_states[str_chat_id]["last_time"] = time.time()
|
| 2053 |
|
| 2054 |
if user_text_lower.startswith(f"{ADMIN_CODE} pro=") or user_text_lower.startswith(f"{ADMIN_CODE}pro="):
|
| 2055 |
parts = user_text_str.split("=", 1)
|
|
|
|
| 2062 |
"expire_date": None,
|
| 2063 |
"last_reset": "",
|
| 2064 |
"chat": 10,
|
| 2065 |
+
"image": 0,
|
| 2066 |
+
"edit_image": 0,
|
| 2067 |
"podcast": 2,
|
| 2068 |
"tts": 5,
|
| 2069 |
"file": 1,
|
|
|
|
| 2082 |
user_credits_db[target_id]["expire_date"] = expire_time.isoformat()
|
| 2083 |
|
| 2084 |
user_credits_db[target_id]["chat"] = 999999
|
| 2085 |
+
user_credits_db[target_id]["image"] = 10
|
| 2086 |
+
user_credits_db[target_id]["edit_image"] = 5
|
| 2087 |
user_credits_db[target_id]["podcast"] = 999999
|
| 2088 |
user_credits_db[target_id]["tts"] = 999999
|
| 2089 |
user_credits_db[target_id]["file"] = 999999
|
|
|
|
| 2107 |
user_credits_db[target_id]["is_premium"] = False
|
| 2108 |
user_credits_db[target_id]["expire_date"] = None
|
| 2109 |
user_credits_db[target_id]["last_reset"] = ""
|
| 2110 |
+
user_credits_db[target_id]["image"] = 0
|
| 2111 |
+
user_credits_db[target_id]["edit_image"] = 0
|
| 2112 |
save_db(user_credits_db)
|
| 2113 |
await send_with_keyboard(client, chat_id, f"✅ اشتراک کاربر `{target_id}` لغو شد و به رایگان تبدیل گشت.", False)
|
| 2114 |
try:
|
|
|
|
| 2346 |
🎙 ساخت پادکست: نامحدود ∞
|
| 2347 |
📁 تحلیل فایل و سند: نامحدود ∞
|
| 2348 |
📝 تبدیل فایل صوتی به متن: نامحدود ∞
|
| 2349 |
+
🪄 ویرایش تصویر: 5 عدد
|
| 2350 |
+
🎨 تولید تصویر: 10 عدد
|
| 2351 |
━━━━━━━━━━━━━━━━━━━
|
| 2352 |
|
| 2353 |
💳 **هزینه اشتراک یک ماهه:** 250 هزار تومان
|
|
|
|
| 2395 |
return
|
| 2396 |
|
| 2397 |
if user_text_str in["/edit_image", "ویرایش تصاویر 🪄"]:
|
| 2398 |
+
# متوقف کردن کاربران رایگان در همین مرحله و نشان دادن پیام (بدون درخواست عکس)
|
| 2399 |
+
if not creds.get("is_premium", False):
|
| 2400 |
+
msg = """کاربر گرامی،
|
| 2401 |
+
|
| 2402 |
+
ضمن تشکر از توجه شما، به اطلاع میرساند که قابلیت ویرایش تصاویر در حال حاضر به صورت رایگان در دسترس نمیباشد. این سرویس به دلیل نیاز به منابع پردازشی بالا، جزو خدمات ویژه و نیازمند تهیه اشتراک است.
|
| 2403 |
+
|
| 2404 |
+
با این حال، شما میتوانید از تست رایگان و امکانات سایر بخشهای پلتفرم ما بهرهمند شوید.
|
| 2405 |
+
|
| 2406 |
+
ما همواره در تلاش برای افزایش منابع و اضافه کردن خدمات رایگان بیشتر به کاربران عزیز هستیم.
|
| 2407 |
+
|
| 2408 |
+
در حال حاضر، میتوانید از سایر بخشهای رایگان موجود استفاده کنید و یا برای دسترسی کامل و نامحدود به تمامی قابلیتها (از جمله ویرایش تصاویر)، اشتراک تهیه نمایید.
|
| 2409 |
+
|
| 2410 |
+
از صبوری و همراهی شما سپاسگزاریم."""
|
| 2411 |
+
await send_with_keyboard(client, chat_id, msg, False)
|
| 2412 |
+
return
|
| 2413 |
+
|
| 2414 |
user_states[str_chat_id]["mode"] = "image_edit_waiting_for_image"
|
| 2415 |
user_states[str_chat_id]["file_bytes"] = None
|
| 2416 |
await send_with_keyboard(client, chat_id, "🪄 به بخش **ویرایش عکس (Flux.2)** خوش آمدید.\n\nلطفاً ابتدا عکسی که میخواهید ویرایش کنید را بفرستید:\n(برای خروج دکمه «برگشت♻️» را بزنید)", True)
|
|
|
|
| 2426 |
await send_with_keyboard(client, chat_id, "📻 شما وارد بخش **ساخت پادکست** شدید.\n\nلطفاً موضوع پادکست خود را بفرستید.\nمثال: درباره تاریخچه پیدایش قهوه با ۳ گوینده یک پادکست جذاب بساز . همچنین این قسمت متصل به مدل زبانی است و درخواست هارو قبل از ساخت درک میکنه. میتوانید مقاله کامل یک سایت بفرستید با تبلیغات یا هرچی، هوش مصنوعی متن مقاله رو استخراج و پادکست براتون میسازه . در توضیحات امکان مشخص کردن تعداد گوینده به همراه اسم شون نیز از سمت شما امکان پذیر است.\n\n(برای خروج دکمه «برگشت♻️» را بزنید)", True)
|
| 2427 |
return
|
| 2428 |
|
|
|
|
|
|
|
|
|
|
| 2429 |
if user_text_str in["/vc", "تغییر صدا 🎙️"]:
|
| 2430 |
user_states[str_chat_id]["mode"] = "vc_waiting_for_voice"
|
| 2431 |
user_states[str_chat_id]["file_bytes"] = None
|
|
|
|
| 2452 |
*(برای خروج دکمه «برگشت♻️» را بزنید)*"""
|
| 2453 |
await send_with_keyboard(client, chat_id, clone_text, True)
|
| 2454 |
return
|
|
|
|
| 2455 |
|
| 2456 |
if user_text_str in["/file", "تحلیل فایل 📁"]:
|
| 2457 |
user_states[str_chat_id]["mode"] = "file_waiting_for_file"
|
|
|
|
| 2520 |
|
| 2521 |
inviter_data["expire_date"] = new_exp.isoformat()
|
| 2522 |
inviter_data["chat"] = 999999
|
| 2523 |
+
inviter_data["image"] = 10
|
| 2524 |
+
inviter_data["edit_image"] = 5
|
| 2525 |
inviter_data["podcast"] = 999999
|
| 2526 |
inviter_data["tts"] = 999999
|
| 2527 |
inviter_data["file"] = 999999
|
|
|
|
| 2692 |
await send_with_keyboard(client, chat_id, "⚠️ لطفاً موضوع مقاله خود را به صورت متنی بفرستید.", False)
|
| 2693 |
return
|
| 2694 |
|
|
|
|
|
|
|
|
|
|
| 2695 |
elif current_mode == "vc_waiting_for_voice":
|
| 2696 |
if not is_file: return await send_with_keyboard(client, chat_id, "⚠️ لطفاً یک فایل صوتی یا ویس ارسال کنید.", False)
|
| 2697 |
await send_with_keyboard(client, chat_id, "📥 در حال دانلود فایل صوتی شما...", False)
|
|
|
|
| 2729 |
asyncio.create_task(process_standard_vc_job(client, chat_id, src_bytes, ref_bytes, model["name"], "voice_conv"))
|
| 2730 |
|
| 2731 |
elif choice in LEGACY_MODELS:
|
|
|
|
| 2732 |
if choice != "8" and creds["voice_conv"] <= 0:
|
| 2733 |
return await send_with_keyboard(client, chat_id, "❌ سهمیه تغییر صدای شما تمام شده است. لطفاً از منوی اصلی وارد بخش «خرید اشتراک 💎» شوید.", False)
|
| 2734 |
|
|
|
|
| 2797 |
if bot_token:
|
| 2798 |
loop = asyncio.get_event_loop()
|
| 2799 |
|
|
|
|
| 2800 |
loop.set_default_executor(concurrent.futures.ThreadPoolExecutor(max_workers=256))
|
| 2801 |
|
|
|
|
| 2802 |
loop.create_task(ram_garbage_collector())
|
| 2803 |
|
| 2804 |
print("🚀 ربات آلفا پرو (نسخه صنعتی + دیتابیس هوشمند + پاکسازی رم + 256 تونل همزمان) روشن شد...")
|