Update main.py
Browse files
main.py
CHANGED
|
@@ -12,6 +12,7 @@ import json
|
|
| 12 |
import datetime
|
| 13 |
import string
|
| 14 |
import uuid
|
|
|
|
| 15 |
from flask import Flask
|
| 16 |
from rubpy.bot import BotClient, filters
|
| 17 |
|
|
@@ -212,7 +213,28 @@ def home():
|
|
| 212 |
return "ربات یکپارچه آلفا (نسخه پرو + مدیریت اشتراک نامحدود + دعوت دوستان + سیستم ضد باگ) روشن است! 🚀"
|
| 213 |
|
| 214 |
def run_flask():
|
| 215 |
-
app.run(host="0.0.0.0", port=7860)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 216 |
|
| 217 |
|
| 218 |
# --- ساختار کیبورد آپدیت شده ---
|
|
@@ -368,7 +390,7 @@ async def helper_download_file(client, msg_obj):
|
|
| 368 |
try:
|
| 369 |
await client.download_file(msg_obj, temp_name)
|
| 370 |
if os.path.exists(temp_name):
|
| 371 |
-
|
| 372 |
os.remove(temp_name)
|
| 373 |
return data
|
| 374 |
except Exception as e: errors.append(f"تلاش ۱: {e}")
|
|
@@ -377,7 +399,7 @@ async def helper_download_file(client, msg_obj):
|
|
| 377 |
try:
|
| 378 |
await client.download_file(file_obj, temp_name)
|
| 379 |
if os.path.exists(temp_name):
|
| 380 |
-
|
| 381 |
os.remove(temp_name)
|
| 382 |
return data
|
| 383 |
except Exception as e: errors.append(f"تلاش ۲: {e}")
|
|
@@ -386,7 +408,7 @@ async def helper_download_file(client, msg_obj):
|
|
| 386 |
try:
|
| 387 |
await client.download_file(file_id, file_name=temp_name)
|
| 388 |
if os.path.exists(temp_name):
|
| 389 |
-
|
| 390 |
os.remove(temp_name)
|
| 391 |
return data
|
| 392 |
except Exception as e: errors.append(f"تلاش ۳: {e}")
|
|
@@ -394,7 +416,7 @@ async def helper_download_file(client, msg_obj):
|
|
| 394 |
try:
|
| 395 |
await client.download_file(file_id, save_as=temp_name)
|
| 396 |
if os.path.exists(temp_name):
|
| 397 |
-
|
| 398 |
os.remove(temp_name)
|
| 399 |
return data
|
| 400 |
except Exception as e: errors.append(f"تلاش ۴: {e}")
|
|
@@ -572,6 +594,9 @@ async def process_gemini(client, chat_id, prompt, file_bytes=None, file_name=Non
|
|
| 572 |
history = user_states[chat_id].get("history",[])
|
| 573 |
new_parts =[]
|
| 574 |
|
|
|
|
|
|
|
|
|
|
| 575 |
if prompt: new_parts.append({"text": prompt})
|
| 576 |
elif file_bytes: new_parts.append({"text": "لطفاً این فایل را به دقت بررسی کن."})
|
| 577 |
|
|
@@ -587,6 +612,11 @@ async def process_gemini(client, chat_id, prompt, file_bytes=None, file_name=Non
|
|
| 587 |
elif file_name.endswith(('.ogg', '.oga')): mime_type = "audio/ogg"
|
| 588 |
elif file_name.endswith('.wav'): mime_type = "audio/wav"
|
| 589 |
else: mime_type = "image/jpeg"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 590 |
new_parts.append({"inlineData": {"mimeType": mime_type, "data": base64_data}})
|
| 591 |
|
| 592 |
if history and history[-1]["role"] == "user": history[-1]["parts"].extend(new_parts)
|
|
@@ -613,43 +643,60 @@ async def process_gemini(client, chat_id, prompt, file_bytes=None, file_name=Non
|
|
| 613 |
except (KeyError, IndexError): continue
|
| 614 |
except Exception: continue
|
| 615 |
|
| 616 |
-
|
| 617 |
-
|
| 618 |
-
|
| 619 |
-
|
| 620 |
-
|
| 621 |
-
|
| 622 |
-
if
|
| 623 |
-
|
| 624 |
-
|
| 625 |
-
|
| 626 |
-
|
| 627 |
-
|
| 628 |
-
|
| 629 |
-
|
| 630 |
-
|
| 631 |
-
|
| 632 |
-
|
| 633 |
-
|
| 634 |
-
|
| 635 |
-
|
| 636 |
-
|
| 637 |
-
|
| 638 |
-
|
| 639 |
-
|
| 640 |
-
|
| 641 |
-
|
| 642 |
-
|
| 643 |
-
|
| 644 |
-
|
| 645 |
-
|
| 646 |
-
|
| 647 |
-
|
| 648 |
-
|
| 649 |
-
|
| 650 |
-
|
| 651 |
-
|
| 652 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 653 |
|
| 654 |
try:
|
| 655 |
if proc_msg:
|
|
@@ -660,7 +707,7 @@ async def process_gemini(client, chat_id, prompt, file_bytes=None, file_name=Non
|
|
| 660 |
|
| 661 |
if not final_answer:
|
| 662 |
if history and history[-1]["role"] == "user": history.pop()
|
| 663 |
-
await send_with_keyboard(client, chat_id, "❌ سرور شلوغ
|
| 664 |
return
|
| 665 |
|
| 666 |
if not creds.get("is_premium"):
|
|
@@ -693,7 +740,7 @@ async def process_gemini(client, chat_id, prompt, file_bytes=None, file_name=Non
|
|
| 693 |
await send_with_keyboard(client, chat_id, "❌ خطایی در ارسال پیام رخ داد.", False)
|
| 694 |
|
| 695 |
|
| 696 |
-
async def process_image(client, chat_id, prompt):
|
| 697 |
str_chat_id = str(chat_id).replace("`", "").replace("'", "").replace('"', "").strip()
|
| 698 |
creds = get_user_credits(str_chat_id)
|
| 699 |
if creds["image"] <= 0:
|
|
@@ -747,8 +794,21 @@ async def process_image(client, chat_id, prompt):
|
|
| 747 |
if msg_id: await client.delete_messages(chat_id,[msg_id])
|
| 748 |
except Exception: pass
|
| 749 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 750 |
short_preview = enhanced_prompt[:150] + "..." if len(enhanced_prompt) > 150 else enhanced_prompt
|
| 751 |
-
proc_msg = await send_with_keyboard(client, chat_id, f"🎨 در حال طراحی عکس...\n\n📝 پرامپت ساخته شده:\n`{short_preview}`\n\n(ممکن است چند ثانیه زمان ببرد)", False)
|
| 752 |
|
| 753 |
keys_to_try = HF_TOKENS.copy()
|
| 754 |
random.shuffle(keys_to_try)
|
|
@@ -758,7 +818,12 @@ async def process_image(client, chat_id, prompt):
|
|
| 758 |
for token in keys_to_try:
|
| 759 |
try:
|
| 760 |
hf_client = AsyncInferenceClient(provider="fal-ai", api_key=token)
|
| 761 |
-
generated_image = await hf_client.text_to_image(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 762 |
break
|
| 763 |
except Exception as e:
|
| 764 |
last_error_log = str(e)
|
|
@@ -778,10 +843,10 @@ async def process_image(client, chat_id, prompt):
|
|
| 778 |
|
| 779 |
try:
|
| 780 |
file_name = f"image_{uuid.uuid4().hex}.jpg"
|
| 781 |
-
|
| 782 |
-
|
| 783 |
await asyncio.sleep(1)
|
| 784 |
-
caption_text = f"🎨 تصویر شما با پرامپت هوشمند آماده شد!\n\n✨ ایده اولیه: {prompt}"
|
| 785 |
upload_result = await helper_upload_file(client, chat_id, file_name, "Image", caption_text)
|
| 786 |
if upload_result is not True: await send_with_keyboard(client, chat_id, f"❌ خطا در آپلود روبیکا:\n`{str(upload_result)[:800]}`", True)
|
| 787 |
if os.path.exists(file_name): os.remove(file_name)
|
|
@@ -870,8 +935,8 @@ async def process_image_edit(client, chat_id, image_bytes, prompt):
|
|
| 870 |
|
| 871 |
try:
|
| 872 |
file_name = f"edited_flux_{uuid.uuid4().hex}.jpg"
|
| 873 |
-
|
| 874 |
-
|
| 875 |
await asyncio.sleep(1)
|
| 876 |
caption_text = f"🪄 ویرایش عکس با هوش مصنوعی Flux.2 انجام شد!\n\n✨ تغییرات خواسته شده: {prompt}\n🔤 متن ارسال شده به هوش: {translated_prompt}"
|
| 877 |
upload_result = await helper_upload_file(client, chat_id, file_name, "Image", caption_text)
|
|
@@ -924,7 +989,8 @@ async def process_tts(client, chat_id, user_text, speaker_id, speaker_name):
|
|
| 924 |
|
| 925 |
file_name_mp3 = f"audio_{uuid.uuid4().hex}.mp3"
|
| 926 |
|
| 927 |
-
|
|
|
|
| 928 |
|
| 929 |
await asyncio.sleep(1)
|
| 930 |
upload_result_file = await helper_upload_file(client, chat_id, file_name_mp3, "File", "✅ صدای شما با موفقیت آماده شد (فایل MP3):")
|
|
@@ -1002,8 +1068,8 @@ async def process_podcast(client, chat_id, prompt):
|
|
| 1002 |
if not chunk_audio_bytes: return await send_with_keyboard(client, chat_id, f"❌ خطا در تولید صدای بخش {index+1} از سرور. عملیات متوقف شد.", True)
|
| 1003 |
|
| 1004 |
try:
|
| 1005 |
-
|
| 1006 |
-
combined_audio
|
| 1007 |
except Exception as e: return await send_with_keyboard(client, chat_id, f"❌ خطا در پردازش صدا (آیا pydub و ffmpeg نصب است؟):\n{str(e)}", True)
|
| 1008 |
|
| 1009 |
if not creds.get("is_premium"):
|
|
@@ -1011,7 +1077,8 @@ async def process_podcast(client, chat_id, prompt):
|
|
| 1011 |
save_db(user_credits_db)
|
| 1012 |
|
| 1013 |
file_name_mp3 = f"final_podcast_{uuid.uuid4().hex}.mp3"
|
| 1014 |
-
|
|
|
|
| 1015 |
|
| 1016 |
try:
|
| 1017 |
if proc_msg:
|
|
@@ -1085,7 +1152,17 @@ async def process_file_analysis(client, chat_id, file_bytes, file_name, prompt):
|
|
| 1085 |
proc_msg = await send_with_keyboard(client, chat_id, "👁️ در حال تحلیل فایل...", False)
|
| 1086 |
base64_data = base64.b64encode(file_bytes).decode('utf-8')
|
| 1087 |
mime_type, _ = mimetypes.guess_type(file_name)
|
| 1088 |
-
if not mime_type:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1089 |
|
| 1090 |
keys_to_try = get_next_gemini_keys(100)
|
| 1091 |
final_answer = None
|
|
@@ -1102,6 +1179,43 @@ async def process_file_analysis(client, chat_id, file_bytes, file_name, prompt):
|
|
| 1102 |
break
|
| 1103 |
except Exception: continue
|
| 1104 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1105 |
try:
|
| 1106 |
if proc_msg:
|
| 1107 |
msg_id = getattr(proc_msg, 'message_id', None)
|
|
@@ -1115,7 +1229,10 @@ async def process_file_analysis(client, chat_id, file_bytes, file_name, prompt):
|
|
| 1115 |
save_db(user_credits_db)
|
| 1116 |
await send_with_keyboard(client, chat_id, f"💡 **نتیجه تحلیل:**\n\n{final_answer}", True)
|
| 1117 |
else:
|
| 1118 |
-
|
|
|
|
|
|
|
|
|
|
| 1119 |
|
| 1120 |
|
| 1121 |
async def process_create_file(client, chat_id, topic):
|
|
@@ -1136,7 +1253,7 @@ async def process_create_file(client, chat_id, topic):
|
|
| 1136 |
async with aiohttp.ClientSession() as session:
|
| 1137 |
for key in keys_to_try:
|
| 1138 |
url = f"https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent?key={key}"
|
| 1139 |
-
payload = {"contents":
|
| 1140 |
try:
|
| 1141 |
async with session.post(url, json=payload, timeout=60) as response:
|
| 1142 |
if response.status == 200:
|
|
@@ -1175,31 +1292,37 @@ async def process_create_file(client, chat_id, topic):
|
|
| 1175 |
if msg_id: await client.delete_messages(chat_id,[msg_id])
|
| 1176 |
except Exception: pass
|
| 1177 |
|
| 1178 |
-
proc_msg = await send_with_keyboard(client, chat_id, "📄 مقاله با موفقیت نوشته شد! در حال ارتباط با سرور و تبدیل به فایلهای PDF و Word...\n(لطفا صبور باشید)", False)
|
| 1179 |
-
|
| 1180 |
-
pdf_bytes = None
|
| 1181 |
-
docx_bytes = None
|
| 1182 |
converter_url = "https://opera8-texttopdf.hf.space/"
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1183 |
|
| 1184 |
-
|
| 1185 |
-
|
| 1186 |
-
|
| 1187 |
-
|
| 1188 |
-
|
| 1189 |
-
|
| 1190 |
-
|
| 1191 |
-
|
| 1192 |
-
|
| 1193 |
-
|
| 1194 |
-
|
| 1195 |
-
|
| 1196 |
-
|
| 1197 |
-
|
| 1198 |
-
|
| 1199 |
-
|
| 1200 |
-
|
| 1201 |
-
|
| 1202 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1203 |
try:
|
| 1204 |
if proc_msg:
|
| 1205 |
msg_id = getattr(proc_msg, 'message_id', None)
|
|
@@ -1207,38 +1330,40 @@ async def process_create_file(client, chat_id, topic):
|
|
| 1207 |
if msg_id: await client.delete_messages(chat_id, [msg_id])
|
| 1208 |
except Exception: pass
|
| 1209 |
|
| 1210 |
-
|
| 1211 |
-
|
| 1212 |
-
|
| 1213 |
-
if not creds.get("is_premium"):
|
| 1214 |
-
user_credits_db[str_chat_id]["chat"] -= 1
|
| 1215 |
-
save_db(user_credits_db)
|
| 1216 |
-
|
| 1217 |
-
uid = uuid.uuid4().hex
|
| 1218 |
-
pdf_filename = f"Article_{uid}.pdf"
|
| 1219 |
-
docx_filename = f"Article_{uid}.docx"
|
| 1220 |
-
|
| 1221 |
-
uploaded_any = False
|
| 1222 |
|
| 1223 |
if pdf_bytes:
|
| 1224 |
-
|
| 1225 |
-
|
| 1226 |
res = await helper_upload_file(client, chat_id, pdf_filename, "File", f"📄 فایل PDF مقاله شما:\n\n💡 موضوع: {topic}")
|
| 1227 |
-
if res is True:
|
| 1228 |
-
|
| 1229 |
-
|
|
|
|
|
|
|
|
|
|
| 1230 |
|
| 1231 |
if docx_bytes:
|
| 1232 |
-
|
| 1233 |
-
|
| 1234 |
res = await helper_upload_file(client, chat_id, docx_filename, "File", f"📝 فایل Word (DOCX) مقاله ��ما:\n\n💡 موضوع: {topic}")
|
| 1235 |
-
if res is True:
|
| 1236 |
-
|
|
|
|
|
|
|
| 1237 |
|
| 1238 |
-
if
|
| 1239 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1240 |
else:
|
| 1241 |
-
await send_with_keyboard(client, chat_id, "❌ فایلها ساخته شدند اما روبیکا در ارسال آنها دچار مشکل شد.", True)
|
| 1242 |
|
| 1243 |
|
| 1244 |
if not bot_token:
|
|
@@ -1382,7 +1507,7 @@ else:
|
|
| 1382 |
expire_txt = f"{jy:04d}/{jm:02d}/{jd:02d}"
|
| 1383 |
status_text = f"🌟 نسخه پرو (ویژه)\n📅 انقضا: {expire_txt}\n⏳ باقیمانده: {days_left} روز"
|
| 1384 |
else:
|
| 1385 |
-
status_text = "🥉 نسخه رایگان (آزمایشی)\n⏳ سهمیه روزانه"
|
| 1386 |
|
| 1387 |
chat_rem = "نامحدود ∞" if is_prem else t_creds.get('chat', 0)
|
| 1388 |
podcast_rem = "نامحدود ∞" if is_prem else t_creds.get('podcast', 0)
|
|
@@ -1392,23 +1517,27 @@ else:
|
|
| 1392 |
image_rem = t_creds.get('image', 0)
|
| 1393 |
edit_image_rem = t_creds.get('edit_image', 0)
|
| 1394 |
invs = t_creds.get('invited_count', 0)
|
|
|
|
| 1395 |
|
| 1396 |
-
info_msg = f"""🔍 **اطلاعات کاربر
|
|
|
|
|
|
|
| 1397 |
|
| 1398 |
-
🔹 **وضعیت:**
|
|
|
|
| 1399 |
🎁 **تعداد افراد دعوت شده:** {invs} نفر
|
| 1400 |
|
| 1401 |
-
📊 **سهمیه:**
|
| 1402 |
-
|
| 1403 |
-
|
| 1404 |
-
|
| 1405 |
-
|
| 1406 |
-
|
| 1407 |
-
|
| 1408 |
-
|
| 1409 |
await send_with_keyboard(client, chat_id, info_msg, False)
|
| 1410 |
else:
|
| 1411 |
-
await send_with_keyboard(client, chat_id, f"❌ کاربری با شناسه `{target_id}` در دیتابیس یافت نشد.", False)
|
| 1412 |
return
|
| 1413 |
|
| 1414 |
is_file = False
|
|
@@ -1594,7 +1723,7 @@ else:
|
|
| 1594 |
🔑 **شناسه یکتای شما:** `{chat_id}`
|
| 1595 |
|
| 1596 |
👨💻 **ارتباط با پشتیبانی:**
|
| 1597 |
-
🆔 @
|
| 1598 |
await send_with_keyboard(client, chat_id, buy_text, True)
|
| 1599 |
return
|
| 1600 |
|
|
@@ -1608,7 +1737,7 @@ else:
|
|
| 1608 |
🔑 **شناسه یکتای ربات شما:** `{chat_id}`
|
| 1609 |
|
| 1610 |
👨💻 **دقت کنید شناسه ربات رو به پشتیبانی داخل خود برنامه هوش مصنوعی آلفا ارسال کنید:**
|
| 1611 |
-
|
| 1612 |
await send_with_keyboard(client, chat_id, transfer_text, True)
|
| 1613 |
return
|
| 1614 |
|
|
@@ -1620,7 +1749,7 @@ else:
|
|
| 1620 |
|
| 1621 |
if user_text_str in["/image", "🎨 عکس", "ساخت تصاویر🎨"]:
|
| 1622 |
user_states[str_chat_id]["mode"] = "image_waiting_for_text"
|
| 1623 |
-
await send_with_keyboard(client, chat_id, "🎨 شما وارد بخش **ساخت عکس پیشرفته** شدید.\n\nمتن خود را ارسال کنید:\n(برای خروج دکمه «برگشت♻️» را بزنید)", True)
|
| 1624 |
return
|
| 1625 |
|
| 1626 |
if user_text_str in["/edit_image", "ویرایش تصاویر 🪄"]:
|
|
@@ -1745,8 +1874,35 @@ else:
|
|
| 1745 |
elif user_text_str: asyncio.create_task(process_gemini(client, chat_id, user_text_str))
|
| 1746 |
return
|
| 1747 |
|
|
|
|
|
|
|
|
|
|
| 1748 |
elif current_mode == "image_waiting_for_text":
|
| 1749 |
-
if user_text_str:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1750 |
return
|
| 1751 |
|
| 1752 |
elif current_mode == "image_edit_waiting_for_image":
|
|
@@ -1824,7 +1980,7 @@ else:
|
|
| 1824 |
user_states[str_chat_id]["file_bytes"] = file_bytes
|
| 1825 |
user_states[str_chat_id]["file_name"] = file_name
|
| 1826 |
user_states[str_chat_id]["mode"] = "file_waiting_for_prompt"
|
| 1827 |
-
await send_with_keyboard(client, chat_id, "✅ فایل با موفقیت دریافت شد.\n\nحالا لطفاً متنی بگویید **چگونه تحلیل شود؟**", False)
|
| 1828 |
except Exception as dl_err: await send_with_keyboard(client, chat_id, f"❌ خطا در دریافت فایل!\n{str(dl_err)}", False)
|
| 1829 |
return
|
| 1830 |
|
|
@@ -1848,6 +2004,12 @@ else:
|
|
| 1848 |
|
| 1849 |
if __name__ == "__main__":
|
| 1850 |
threading.Thread(target=run_flask, daemon=True).start()
|
|
|
|
| 1851 |
if bot_token:
|
| 1852 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1853 |
bot.run()
|
|
|
|
| 12 |
import datetime
|
| 13 |
import string
|
| 14 |
import uuid
|
| 15 |
+
import concurrent.futures
|
| 16 |
from flask import Flask
|
| 17 |
from rubpy.bot import BotClient, filters
|
| 18 |
|
|
|
|
| 213 |
return "ربات یکپارچه آلفا (نسخه پرو + مدیریت اشتراک نامحدود + دعوت دوستان + سیستم ضد باگ) روشن است! 🚀"
|
| 214 |
|
| 215 |
def run_flask():
|
| 216 |
+
app.run(host="0.0.0.0", port=7860, threaded=True)
|
| 217 |
+
|
| 218 |
+
|
| 219 |
+
# --- توابع کمکی برای جلوگیری از بلاک شدن Event Loop ---
|
| 220 |
+
def sync_save_image(image, file_name):
|
| 221 |
+
rgb_im = image.convert('RGB')
|
| 222 |
+
rgb_im.save(file_name, format="JPEG", quality=100)
|
| 223 |
+
|
| 224 |
+
def sync_write_file(file_name, data):
|
| 225 |
+
with open(file_name, "wb") as f:
|
| 226 |
+
f.write(data)
|
| 227 |
+
|
| 228 |
+
def sync_read_file(file_name):
|
| 229 |
+
with open(file_name, 'rb') as f:
|
| 230 |
+
return f.read()
|
| 231 |
+
|
| 232 |
+
def sync_combine_audio(current_audio, new_bytes):
|
| 233 |
+
audio_segment = AudioSegment.from_file(io.BytesIO(new_bytes))
|
| 234 |
+
return current_audio + audio_segment
|
| 235 |
+
|
| 236 |
+
def sync_export_audio(audio_obj, file_name):
|
| 237 |
+
audio_obj.export(file_name, format="mp3")
|
| 238 |
|
| 239 |
|
| 240 |
# --- ساختار کیبورد آپدیت شده ---
|
|
|
|
| 390 |
try:
|
| 391 |
await client.download_file(msg_obj, temp_name)
|
| 392 |
if os.path.exists(temp_name):
|
| 393 |
+
data = await asyncio.to_thread(sync_read_file, temp_name)
|
| 394 |
os.remove(temp_name)
|
| 395 |
return data
|
| 396 |
except Exception as e: errors.append(f"تلاش ۱: {e}")
|
|
|
|
| 399 |
try:
|
| 400 |
await client.download_file(file_obj, temp_name)
|
| 401 |
if os.path.exists(temp_name):
|
| 402 |
+
data = await asyncio.to_thread(sync_read_file, temp_name)
|
| 403 |
os.remove(temp_name)
|
| 404 |
return data
|
| 405 |
except Exception as e: errors.append(f"تلاش ۲: {e}")
|
|
|
|
| 408 |
try:
|
| 409 |
await client.download_file(file_id, file_name=temp_name)
|
| 410 |
if os.path.exists(temp_name):
|
| 411 |
+
data = await asyncio.to_thread(sync_read_file, temp_name)
|
| 412 |
os.remove(temp_name)
|
| 413 |
return data
|
| 414 |
except Exception as e: errors.append(f"تلاش ۳: {e}")
|
|
|
|
| 416 |
try:
|
| 417 |
await client.download_file(file_id, save_as=temp_name)
|
| 418 |
if os.path.exists(temp_name):
|
| 419 |
+
data = await asyncio.to_thread(sync_read_file, temp_name)
|
| 420 |
os.remove(temp_name)
|
| 421 |
return data
|
| 422 |
except Exception as e: errors.append(f"تلاش ۴: {e}")
|
|
|
|
| 594 |
history = user_states[chat_id].get("history",[])
|
| 595 |
new_parts =[]
|
| 596 |
|
| 597 |
+
is_image = True
|
| 598 |
+
has_non_image_file = False
|
| 599 |
+
|
| 600 |
if prompt: new_parts.append({"text": prompt})
|
| 601 |
elif file_bytes: new_parts.append({"text": "لطفاً این فایل را به دقت بررسی کن."})
|
| 602 |
|
|
|
|
| 612 |
elif file_name.endswith(('.ogg', '.oga')): mime_type = "audio/ogg"
|
| 613 |
elif file_name.endswith('.wav'): mime_type = "audio/wav"
|
| 614 |
else: mime_type = "image/jpeg"
|
| 615 |
+
|
| 616 |
+
is_image = mime_type.startswith('image/')
|
| 617 |
+
if not is_image:
|
| 618 |
+
has_non_image_file = True
|
| 619 |
+
|
| 620 |
new_parts.append({"inlineData": {"mimeType": mime_type, "data": base64_data}})
|
| 621 |
|
| 622 |
if history and history[-1]["role"] == "user": history[-1]["parts"].extend(new_parts)
|
|
|
|
| 643 |
except (KeyError, IndexError): continue
|
| 644 |
except Exception: continue
|
| 645 |
|
| 646 |
+
# اگر جیمینای جواب نداد
|
| 647 |
+
if not final_answer:
|
| 648 |
+
# اگر فایل ارسال شده عکس نبود، خطای اختصاصی میدهیم
|
| 649 |
+
if has_non_image_file:
|
| 650 |
+
if history and history[-1]["role"] == "user": history.pop()
|
| 651 |
+
try:
|
| 652 |
+
if proc_msg:
|
| 653 |
+
msg_id = getattr(proc_msg, 'message_id', None)
|
| 654 |
+
if isinstance(proc_msg, dict): msg_id = proc_msg.get('message_update', {}).get('message_id') or proc_msg.get('message_id')
|
| 655 |
+
if msg_id: await client.delete_messages(chat_id,[msg_id])
|
| 656 |
+
except Exception: pass
|
| 657 |
+
await send_with_keyboard(client, chat_id, "❌ متأسفانه سرور اصلی در حال حاضر شلوغ است و در این شرایط **فعلاً تنها امکان تحلیل تصاویر** توسط سرور جایگزین در دسترس است.", False)
|
| 658 |
+
return
|
| 659 |
+
|
| 660 |
+
# اگر فایل عکس بود یا فقط متن بود، میرویم سراغ مدل جایگزین (هاگینگ فیس)
|
| 661 |
+
if HF_TOKENS:
|
| 662 |
+
hf_messages =[]
|
| 663 |
+
for msg in history:
|
| 664 |
+
role = "assistant" if msg["role"] == "model" else "user"
|
| 665 |
+
content_parts =[]
|
| 666 |
+
for part in msg["parts"]:
|
| 667 |
+
if "text" in part:
|
| 668 |
+
content_parts.append({"type": "text", "text": part["text"]})
|
| 669 |
+
elif "inlineData" in part:
|
| 670 |
+
mime_t = part["inlineData"]["mimeType"]
|
| 671 |
+
b64_d = part["inlineData"]["data"]
|
| 672 |
+
if mime_t.startswith('image/'):
|
| 673 |
+
content_parts.append({
|
| 674 |
+
"type": "image_url",
|
| 675 |
+
"image_url": {"url": f"data:{mime_t};base64,{b64_d}"}
|
| 676 |
+
})
|
| 677 |
+
if content_parts:
|
| 678 |
+
hf_messages.append({"role": role, "content": content_parts})
|
| 679 |
+
|
| 680 |
+
keys_to_try_hf = HF_TOKENS.copy()
|
| 681 |
+
random.shuffle(keys_to_try_hf)
|
| 682 |
+
|
| 683 |
+
async with aiohttp.ClientSession() as session:
|
| 684 |
+
for hf_key in keys_to_try_hf:
|
| 685 |
+
url = "https://router.huggingface.co/v1/chat/completions"
|
| 686 |
+
headers = {"Authorization": f"Bearer {hf_key}", "Content-Type": "application/json"}
|
| 687 |
+
payload = {
|
| 688 |
+
"model": "google/gemma-4-31B-it:novita",
|
| 689 |
+
"messages": hf_messages,
|
| 690 |
+
"max_tokens": 4096
|
| 691 |
+
}
|
| 692 |
+
try:
|
| 693 |
+
async with session.post(url, headers=headers, json=payload, timeout=60) as response:
|
| 694 |
+
if response.status == 200:
|
| 695 |
+
data = await response.json()
|
| 696 |
+
final_answer = data["choices"][0]["message"]["content"]
|
| 697 |
+
break
|
| 698 |
+
except Exception:
|
| 699 |
+
continue
|
| 700 |
|
| 701 |
try:
|
| 702 |
if proc_msg:
|
|
|
|
| 707 |
|
| 708 |
if not final_answer:
|
| 709 |
if history and history[-1]["role"] == "user": history.pop()
|
| 710 |
+
await send_with_keyboard(client, chat_id, "❌ تمامی سرورها شلوغ هستند. لطفاً بعداً امتحان کنید.", False)
|
| 711 |
return
|
| 712 |
|
| 713 |
if not creds.get("is_premium"):
|
|
|
|
| 740 |
await send_with_keyboard(client, chat_id, "❌ خطایی در ارسال پیام رخ داد.", False)
|
| 741 |
|
| 742 |
|
| 743 |
+
async def process_image(client, chat_id, prompt, size_choice="1"):
|
| 744 |
str_chat_id = str(chat_id).replace("`", "").replace("'", "").replace('"', "").strip()
|
| 745 |
creds = get_user_credits(str_chat_id)
|
| 746 |
if creds["image"] <= 0:
|
|
|
|
| 794 |
if msg_id: await client.delete_messages(chat_id,[msg_id])
|
| 795 |
except Exception: pass
|
| 796 |
|
| 797 |
+
# تنظیم ابعاد انتخابی کاربر
|
| 798 |
+
w, h = 1024, 1024
|
| 799 |
+
size_name = "مربع (1:1) ⬛"
|
| 800 |
+
if size_choice == "2":
|
| 801 |
+
w, h = 768, 1344
|
| 802 |
+
size_name = "عمودی (9:16) 📱"
|
| 803 |
+
elif size_choice == "3":
|
| 804 |
+
w, h = 1344, 768
|
| 805 |
+
size_name = "افقی (16:9) 🖥️"
|
| 806 |
+
elif size_choice == "4":
|
| 807 |
+
w, h = 1024, 768
|
| 808 |
+
size_name = "استاندارد (4:3) 📸"
|
| 809 |
+
|
| 810 |
short_preview = enhanced_prompt[:150] + "..." if len(enhanced_prompt) > 150 else enhanced_prompt
|
| 811 |
+
proc_msg = await send_with_keyboard(client, chat_id, f"🎨 در حال طراحی عکس...\n\n📏 **ابعاد:** {size_name}\n📝 **پرامپت ساخته شده:**\n`{short_preview}`\n\n(ممکن است چند ثانیه زمان ببرد)", False)
|
| 812 |
|
| 813 |
keys_to_try = HF_TOKENS.copy()
|
| 814 |
random.shuffle(keys_to_try)
|
|
|
|
| 818 |
for token in keys_to_try:
|
| 819 |
try:
|
| 820 |
hf_client = AsyncInferenceClient(provider="fal-ai", api_key=token)
|
| 821 |
+
generated_image = await hf_client.text_to_image(
|
| 822 |
+
enhanced_prompt,
|
| 823 |
+
model="Tongyi-MAI/Z-Image-Turbo",
|
| 824 |
+
width=w,
|
| 825 |
+
height=h
|
| 826 |
+
)
|
| 827 |
break
|
| 828 |
except Exception as e:
|
| 829 |
last_error_log = str(e)
|
|
|
|
| 843 |
|
| 844 |
try:
|
| 845 |
file_name = f"image_{uuid.uuid4().hex}.jpg"
|
| 846 |
+
# استفاده از ترد برای جلوگیری از مسدود شدن برنامه حین کار با PIL
|
| 847 |
+
await asyncio.to_thread(sync_save_image, generated_image, file_name)
|
| 848 |
await asyncio.sleep(1)
|
| 849 |
+
caption_text = f"🎨 تصویر شما با پرامپت هوشمند آماده شد!\n\n📏 ابعاد تصویر: {size_name}\n✨ ایده اولیه: {prompt}"
|
| 850 |
upload_result = await helper_upload_file(client, chat_id, file_name, "Image", caption_text)
|
| 851 |
if upload_result is not True: await send_with_keyboard(client, chat_id, f"❌ خطا در آپلود روبیکا:\n`{str(upload_result)[:800]}`", True)
|
| 852 |
if os.path.exists(file_name): os.remove(file_name)
|
|
|
|
| 935 |
|
| 936 |
try:
|
| 937 |
file_name = f"edited_flux_{uuid.uuid4().hex}.jpg"
|
| 938 |
+
# استفاده از ترد برای ذخیره عکس
|
| 939 |
+
await asyncio.to_thread(sync_save_image, generated_image, file_name)
|
| 940 |
await asyncio.sleep(1)
|
| 941 |
caption_text = f"🪄 ویرایش عکس با هوش مصنوعی Flux.2 انجام شد!\n\n✨ تغییرات خواسته شده: {prompt}\n🔤 متن ارسال شده به هوش: {translated_prompt}"
|
| 942 |
upload_result = await helper_upload_file(client, chat_id, file_name, "Image", caption_text)
|
|
|
|
| 989 |
|
| 990 |
file_name_mp3 = f"audio_{uuid.uuid4().hex}.mp3"
|
| 991 |
|
| 992 |
+
# ذخیره فایل در ترد جداگانه
|
| 993 |
+
await asyncio.to_thread(sync_write_file, file_name_mp3, audio_bytes)
|
| 994 |
|
| 995 |
await asyncio.sleep(1)
|
| 996 |
upload_result_file = await helper_upload_file(client, chat_id, file_name_mp3, "File", "✅ صدای شما با موفقیت آماده شد (فایل MP3):")
|
|
|
|
| 1068 |
if not chunk_audio_bytes: return await send_with_keyboard(client, chat_id, f"❌ خطا در تولید صدای بخش {index+1} از سرور. عملیات متوقف شد.", True)
|
| 1069 |
|
| 1070 |
try:
|
| 1071 |
+
# جلوگیری از گیر کردن لوپ در هنگام ترکیب فایلهای صوتی سنگین
|
| 1072 |
+
combined_audio = await asyncio.to_thread(sync_combine_audio, combined_audio, chunk_audio_bytes)
|
| 1073 |
except Exception as e: return await send_with_keyboard(client, chat_id, f"❌ خطا در پردازش صدا (آیا pydub و ffmpeg نصب است؟):\n{str(e)}", True)
|
| 1074 |
|
| 1075 |
if not creds.get("is_premium"):
|
|
|
|
| 1077 |
save_db(user_credits_db)
|
| 1078 |
|
| 1079 |
file_name_mp3 = f"final_podcast_{uuid.uuid4().hex}.mp3"
|
| 1080 |
+
# اکسپورت فایل صوتی در ترد جدا
|
| 1081 |
+
await asyncio.to_thread(sync_export_audio, combined_audio, file_name_mp3)
|
| 1082 |
|
| 1083 |
try:
|
| 1084 |
if proc_msg:
|
|
|
|
| 1152 |
proc_msg = await send_with_keyboard(client, chat_id, "👁️ در حال تحلیل فایل...", False)
|
| 1153 |
base64_data = base64.b64encode(file_bytes).decode('utf-8')
|
| 1154 |
mime_type, _ = mimetypes.guess_type(file_name)
|
| 1155 |
+
if not mime_type:
|
| 1156 |
+
if file_name.endswith(('.jpg', '.jpeg')): mime_type = "image/jpeg"
|
| 1157 |
+
elif file_name.endswith('.png'): mime_type = "image/png"
|
| 1158 |
+
elif file_name.endswith('.pdf'): mime_type = "application/pdf"
|
| 1159 |
+
elif file_name.endswith('.mp4'): mime_type = "video/mp4"
|
| 1160 |
+
elif file_name.endswith('.mp3'): mime_type = "audio/mp3"
|
| 1161 |
+
elif file_name.endswith(('.ogg', '.oga')): mime_type = "audio/ogg"
|
| 1162 |
+
elif file_name.endswith('.wav'): mime_type = "audio/wav"
|
| 1163 |
+
else: mime_type = "image/jpeg"
|
| 1164 |
+
|
| 1165 |
+
is_image = mime_type.startswith('image/')
|
| 1166 |
|
| 1167 |
keys_to_try = get_next_gemini_keys(100)
|
| 1168 |
final_answer = None
|
|
|
|
| 1179 |
break
|
| 1180 |
except Exception: continue
|
| 1181 |
|
| 1182 |
+
# جایگزین تصویر اگر جیمینای جواب نداد
|
| 1183 |
+
if not final_answer:
|
| 1184 |
+
if is_image and HF_TOKENS:
|
| 1185 |
+
keys_to_try_hf = HF_TOKENS.copy()
|
| 1186 |
+
random.shuffle(keys_to_try_hf)
|
| 1187 |
+
|
| 1188 |
+
hf_messages =[
|
| 1189 |
+
{
|
| 1190 |
+
"role": "user",
|
| 1191 |
+
"content":[
|
| 1192 |
+
{"type": "text", "text": prompt},
|
| 1193 |
+
{
|
| 1194 |
+
"type": "image_url",
|
| 1195 |
+
"image_url": {"url": f"data:{mime_type};base64,{base64_data}"}
|
| 1196 |
+
}
|
| 1197 |
+
]
|
| 1198 |
+
}
|
| 1199 |
+
]
|
| 1200 |
+
|
| 1201 |
+
async with aiohttp.ClientSession() as session:
|
| 1202 |
+
for hf_key in keys_to_try_hf:
|
| 1203 |
+
url = "https://router.huggingface.co/v1/chat/completions"
|
| 1204 |
+
headers = {"Authorization": f"Bearer {hf_key}", "Content-Type": "application/json"}
|
| 1205 |
+
payload = {
|
| 1206 |
+
"model": "google/gemma-4-31B-it:novita",
|
| 1207 |
+
"messages": hf_messages,
|
| 1208 |
+
"max_tokens": 4096
|
| 1209 |
+
}
|
| 1210 |
+
try:
|
| 1211 |
+
async with session.post(url, headers=headers, json=payload, timeout=60) as response:
|
| 1212 |
+
if response.status == 200:
|
| 1213 |
+
data = await response.json()
|
| 1214 |
+
final_answer = data["choices"][0]["message"]["content"]
|
| 1215 |
+
break
|
| 1216 |
+
except Exception:
|
| 1217 |
+
continue
|
| 1218 |
+
|
| 1219 |
try:
|
| 1220 |
if proc_msg:
|
| 1221 |
msg_id = getattr(proc_msg, 'message_id', None)
|
|
|
|
| 1229 |
save_db(user_credits_db)
|
| 1230 |
await send_with_keyboard(client, chat_id, f"💡 **نتیجه تحلیل:**\n\n{final_answer}", True)
|
| 1231 |
else:
|
| 1232 |
+
if not is_image:
|
| 1233 |
+
await send_with_keyboard(client, chat_id, "❌ متأسفانه سرور اصلی در حال حاضر شلوغ است و در این شرایط **فعلاً تنها امکان تحلیل تصاویر** توسط سرور جایگزین در دسترس است.", True)
|
| 1234 |
+
else:
|
| 1235 |
+
await send_with_keyboard(client, chat_id, "❌ تمامی سرورها شلوغ هستند. لطفاً بعداً امتحان کنید.", True)
|
| 1236 |
|
| 1237 |
|
| 1238 |
async def process_create_file(client, chat_id, topic):
|
|
|
|
| 1253 |
async with aiohttp.ClientSession() as session:
|
| 1254 |
for key in keys_to_try:
|
| 1255 |
url = f"https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent?key={key}"
|
| 1256 |
+
payload = {"contents":[{"parts":[{"text": ai_prompt}]}], "generationConfig": {"temperature": 0.7, "maxOutputTokens": 8192}}
|
| 1257 |
try:
|
| 1258 |
async with session.post(url, json=payload, timeout=60) as response:
|
| 1259 |
if response.status == 200:
|
|
|
|
| 1292 |
if msg_id: await client.delete_messages(chat_id,[msg_id])
|
| 1293 |
except Exception: pass
|
| 1294 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1295 |
converter_url = "https://opera8-texttopdf.hf.space/"
|
| 1296 |
+
uid = uuid.uuid4().hex
|
| 1297 |
+
|
| 1298 |
+
# پیام اطلاع رسانی قبل از ساخت فایلها
|
| 1299 |
+
proc_msg = await send_with_keyboard(client, chat_id, "📄 مقاله با موفقیت نوشته شد!\n\n⏳ در حال ارتباط همزمان با هوش مصنوعی برای دریافت فایلهای PDF و Word...\n", False)
|
| 1300 |
|
| 1301 |
+
# تابع کمکی برای درخواست همزمان به سرور
|
| 1302 |
+
async def fetch_document(fmt):
|
| 1303 |
+
for attempt in range(3):
|
| 1304 |
+
try:
|
| 1305 |
+
async with aiohttp.ClientSession() as session:
|
| 1306 |
+
form_data = aiohttp.FormData()
|
| 1307 |
+
form_data.add_field('content', article_text)
|
| 1308 |
+
form_data.add_field('format', fmt)
|
| 1309 |
+
# تایماوت 180 ثانیه برای فرصت کافی به Weasyprint
|
| 1310 |
+
async with session.post(converter_url, data=form_data, timeout=180) as resp:
|
| 1311 |
+
if resp.status == 200:
|
| 1312 |
+
data = await resp.read()
|
| 1313 |
+
if data and len(data) > 0:
|
| 1314 |
+
return data
|
| 1315 |
+
except Exception:
|
| 1316 |
+
pass
|
| 1317 |
+
await asyncio.sleep(2)
|
| 1318 |
+
return None
|
| 1319 |
+
|
| 1320 |
+
# اجرای همزمان هر دو درخواست برای سرعت بیشتر و جلوگیری از تایماوت متوالی
|
| 1321 |
+
pdf_bytes, docx_bytes = await asyncio.gather(
|
| 1322 |
+
fetch_document('pdf'),
|
| 1323 |
+
fetch_document('docx')
|
| 1324 |
+
)
|
| 1325 |
+
|
| 1326 |
try:
|
| 1327 |
if proc_msg:
|
| 1328 |
msg_id = getattr(proc_msg, 'message_id', None)
|
|
|
|
| 1330 |
if msg_id: await client.delete_messages(chat_id, [msg_id])
|
| 1331 |
except Exception: pass
|
| 1332 |
|
| 1333 |
+
# --- آپلود فایلها در روبیکا ---
|
| 1334 |
+
uploaded_pdf = False
|
| 1335 |
+
uploaded_docx = False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1336 |
|
| 1337 |
if pdf_bytes:
|
| 1338 |
+
pdf_filename = f"Article_{uid}.pdf"
|
| 1339 |
+
await asyncio.to_thread(sync_write_file, pdf_filename, pdf_bytes)
|
| 1340 |
res = await helper_upload_file(client, chat_id, pdf_filename, "File", f"📄 فایل PDF مقاله شما:\n\n💡 موضوع: {topic}")
|
| 1341 |
+
if res is True:
|
| 1342 |
+
uploaded_pdf = True
|
| 1343 |
+
if os.path.exists(pdf_filename):
|
| 1344 |
+
os.remove(pdf_filename)
|
| 1345 |
+
|
| 1346 |
+
await asyncio.sleep(1.5)
|
| 1347 |
|
| 1348 |
if docx_bytes:
|
| 1349 |
+
docx_filename = f"Article_{uid}.docx"
|
| 1350 |
+
await asyncio.to_thread(sync_write_file, docx_filename, docx_bytes)
|
| 1351 |
res = await helper_upload_file(client, chat_id, docx_filename, "File", f"📝 فایل Word (DOCX) مقاله ��ما:\n\n💡 موضوع: {topic}")
|
| 1352 |
+
if res is True:
|
| 1353 |
+
uploaded_docx = True
|
| 1354 |
+
if os.path.exists(docx_filename):
|
| 1355 |
+
os.remove(docx_filename)
|
| 1356 |
|
| 1357 |
+
if not creds.get("is_premium"):
|
| 1358 |
+
user_credits_db[str_chat_id]["chat"] -= 1
|
| 1359 |
+
save_db(user_credits_db)
|
| 1360 |
+
|
| 1361 |
+
if uploaded_pdf and uploaded_docx:
|
| 1362 |
+
await send_with_keyboard(client, chat_id, "✅ هر دو فایل (PDF و Word) مقاله شما با موفقیت تحویل داده شد!", True)
|
| 1363 |
+
elif uploaded_pdf or uploaded_docx:
|
| 1364 |
+
await send_with_keyboard(client, chat_id, "⚠️ یکی از فایلها با موفقیت ارسال شد، اما در ساخت یا ارسال فایل دیگر مشکلی از سمت سرور پیش آمد.", True)
|
| 1365 |
else:
|
| 1366 |
+
await send_with_keyboard(client, chat_id, "❌ فایلها ساخته شدند اما متأسفانه روبیکا در ارسال آنها دچار مشکل شد.", True)
|
| 1367 |
|
| 1368 |
|
| 1369 |
if not bot_token:
|
|
|
|
| 1507 |
expire_txt = f"{jy:04d}/{jm:02d}/{jd:02d}"
|
| 1508 |
status_text = f"🌟 نسخه پرو (ویژه)\n📅 انقضا: {expire_txt}\n⏳ باقیمانده: {days_left} روز"
|
| 1509 |
else:
|
| 1510 |
+
status_text = "🥉 نسخه رایگان (آزمایشی)\n⏳ وضعیت: سهمیه روزانه محدود"
|
| 1511 |
|
| 1512 |
chat_rem = "نامحدود ∞" if is_prem else t_creds.get('chat', 0)
|
| 1513 |
podcast_rem = "نامحدود ∞" if is_prem else t_creds.get('podcast', 0)
|
|
|
|
| 1517 |
image_rem = t_creds.get('image', 0)
|
| 1518 |
edit_image_rem = t_creds.get('edit_image', 0)
|
| 1519 |
invs = t_creds.get('invited_count', 0)
|
| 1520 |
+
joined_status = "بله ✅" if t_creds.get('has_joined') else "خیر ❌"
|
| 1521 |
|
| 1522 |
+
info_msg = f"""🔍 **اطلاعات اختصاصی کاربر:**
|
| 1523 |
+
👤 شناسه: `{target_id}`
|
| 1524 |
+
عضو کانال: {joined_status}
|
| 1525 |
|
| 1526 |
+
🔹 **وضعیت اشتراک:**
|
| 1527 |
+
{status_text}
|
| 1528 |
🎁 **تعداد افراد دعوت شده:** {invs} نفر
|
| 1529 |
|
| 1530 |
+
📊 **سهمیه باقیمانده فعلی:**
|
| 1531 |
+
💬 چت: {chat_rem}
|
| 1532 |
+
🎨 تولید عکس: {image_rem}
|
| 1533 |
+
🪄 ویرایش عکس: {edit_image_rem}
|
| 1534 |
+
🎙 پادکست: {podcast_rem}
|
| 1535 |
+
🗣 متن به صدا: {tts_rem}
|
| 1536 |
+
📁 تحلیل فایل: {file_rem}
|
| 1537 |
+
📝 صدا به متن: {stt_rem}"""
|
| 1538 |
await send_with_keyboard(client, chat_id, info_msg, False)
|
| 1539 |
else:
|
| 1540 |
+
await send_with_keyboard(client, chat_id, f"❌ کاربری با شناسه `{target_id}` در دیتابیس ربات یافت نشد.", False)
|
| 1541 |
return
|
| 1542 |
|
| 1543 |
is_file = False
|
|
|
|
| 1723 |
🔑 **شناسه یکتای شما:** `{chat_id}`
|
| 1724 |
|
| 1725 |
👨💻 **ارتباط با پشتیبانی:**
|
| 1726 |
+
🆔 @aialpha_admin"""
|
| 1727 |
await send_with_keyboard(client, chat_id, buy_text, True)
|
| 1728 |
return
|
| 1729 |
|
|
|
|
| 1737 |
🔑 **شناسه یکتای ربات شما:** `{chat_id}`
|
| 1738 |
|
| 1739 |
👨💻 **دقت کنید شناسه ربات رو به پشتیبانی داخل خود برنامه هوش مصنوعی آلفا ارسال کنید:**
|
| 1740 |
+
🤖"""
|
| 1741 |
await send_with_keyboard(client, chat_id, transfer_text, True)
|
| 1742 |
return
|
| 1743 |
|
|
|
|
| 1749 |
|
| 1750 |
if user_text_str in["/image", "🎨 عکس", "ساخت تصاویر🎨"]:
|
| 1751 |
user_states[str_chat_id]["mode"] = "image_waiting_for_text"
|
| 1752 |
+
await send_with_keyboard(client, chat_id, "🎨 شما وارد بخش **ساخت عکس پیشرفته** شدید.\n\nمتن (ایده) خود را به صورت کامل ارسال کنید:\n(برای خروج دکمه «برگشت♻️» را بزنید)", True)
|
| 1753 |
return
|
| 1754 |
|
| 1755 |
if user_text_str in["/edit_image", "ویرایش تصاویر 🪄"]:
|
|
|
|
| 1874 |
elif user_text_str: asyncio.create_task(process_gemini(client, chat_id, user_text_str))
|
| 1875 |
return
|
| 1876 |
|
| 1877 |
+
# ===============================================
|
| 1878 |
+
# آپدیت جدید: دریافت سایز قبل از ساخت عکس
|
| 1879 |
+
# ===============================================
|
| 1880 |
elif current_mode == "image_waiting_for_text":
|
| 1881 |
+
if user_text_str:
|
| 1882 |
+
user_states[str_chat_id]["text"] = user_text_str
|
| 1883 |
+
user_states[str_chat_id]["mode"] = "image_waiting_for_size"
|
| 1884 |
+
|
| 1885 |
+
size_menu = """🖼 **لطفاً ابعاد تصویر خود را انتخاب کنید:**
|
| 1886 |
+
|
| 1887 |
+
1️⃣ `1:1` (مربع) - مناسب پروفایل ⬛
|
| 1888 |
+
2️⃣ `9:16` (عمودی) - مناسب استوری و پسزمینه گوشی 📱
|
| 1889 |
+
3️⃣ `16:9` (افقی) - مناسب دسکتاپ و ویدیو 🖥️
|
| 1890 |
+
4️⃣ `4:3` (استاندارد) - مناسب چاپ و پست 📸
|
| 1891 |
+
|
| 1892 |
+
(لطفاً فقط عدد 1 تا 4 را بفرستید)"""
|
| 1893 |
+
await send_with_keyboard(client, chat_id, size_menu, False)
|
| 1894 |
+
else:
|
| 1895 |
+
await send_with_keyboard(client, chat_id, "⚠️ لطفاً ایده عکس خود را به صورت متنی بفرستید.", False)
|
| 1896 |
+
return
|
| 1897 |
+
|
| 1898 |
+
elif current_mode == "image_waiting_for_size":
|
| 1899 |
+
normalized_choice = to_english_digits(user_text_str).strip()
|
| 1900 |
+
if normalized_choice in["1", "2", "3", "4"]:
|
| 1901 |
+
saved_text = user_states[str_chat_id].get("text", "")
|
| 1902 |
+
user_states[str_chat_id]["mode"] = None
|
| 1903 |
+
asyncio.create_task(process_image(client, chat_id, saved_text, normalized_choice))
|
| 1904 |
+
else:
|
| 1905 |
+
await send_with_keyboard(client, chat_id, "❌ عدد وارد شده نامعتبر است! لطفاً فقط یکی از اعداد 1 تا 4 را بفرستید.", False)
|
| 1906 |
return
|
| 1907 |
|
| 1908 |
elif current_mode == "image_edit_waiting_for_image":
|
|
|
|
| 1980 |
user_states[str_chat_id]["file_bytes"] = file_bytes
|
| 1981 |
user_states[str_chat_id]["file_name"] = file_name
|
| 1982 |
user_states[str_chat_id]["mode"] = "file_waiting_for_prompt"
|
| 1983 |
+
await send_with_keyboard(client, chat_id, "✅ فایل با موفقیت دریافت شد.\n\nحالا لطفاً متنی بگویید **چگونه تحلیل شود؟**\n(میتوانید سوال خاصی بپرسید یا فقط بخواهید فایل را توضیح دهد)", False)
|
| 1984 |
except Exception as dl_err: await send_with_keyboard(client, chat_id, f"❌ خطا در دریافت فایل!\n{str(dl_err)}", False)
|
| 1985 |
return
|
| 1986 |
|
|
|
|
| 2004 |
|
| 2005 |
if __name__ == "__main__":
|
| 2006 |
threading.Thread(target=run_flask, daemon=True).start()
|
| 2007 |
+
|
| 2008 |
if bot_token:
|
| 2009 |
+
# افزایش ظرفیت کارگرهای (Workers) پسزمینه در Asyncio برای افزایش شدید سرعت پاسخگویی
|
| 2010 |
+
loop = asyncio.get_event_loop()
|
| 2011 |
+
# تنظیم ترد پول روی 16 کارگر به جای 1 پیشفرض که باعث کندی میشد
|
| 2012 |
+
loop.set_default_executor(concurrent.futures.ThreadPoolExecutor(max_workers=16))
|
| 2013 |
+
|
| 2014 |
+
print("ربات آلفا پرو با سیستم اشتراک نامحدود + سپر امنیتی + 16 Worker پسزمینه روشن شد...")
|
| 2015 |
bot.run()
|