Opera8 commited on
Commit
c0715d7
·
verified ·
1 Parent(s): 2292154

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +38 -73
main.py CHANGED
@@ -9,7 +9,7 @@ from flask import Flask, request, Response
9
  from rubpy.bot import BotClient, filters
10
 
11
  # ====================================================================
12
- # 🌐 بخش اول: تنظیمات وب‌سرور FLASK و تونل (پروکسی) برای دور زدن فیلترینگ
13
  # ====================================================================
14
  app = Flask(__name__)
15
 
@@ -18,12 +18,13 @@ HF_SADA_URL = "https://ezmarynoori-sada.hf.space"
18
 
19
  @app.route('/')
20
  def home():
21
- return "ربات روبیکا و سرور پراکسی Ai Sada روشن و فعال است! 🚀"
22
 
23
- # این روت تمام درخواست‌های سایت شما را می‌گیرد و به هاگینگ فیس می‌فرستد
24
- @app.route('/proxy/<target>/<path:subpath>', methods=['GET', 'POST'])
25
  def proxy_hub(target, subpath):
26
- # تشخیص سرور هدف
 
 
27
  if target == 'podcast':
28
  base_url = HF_PODCAST_URL
29
  elif target == 'sada':
@@ -33,52 +34,56 @@ def proxy_hub(target, subpath):
33
 
34
  url = f"{base_url}/{subpath}"
35
 
36
- # انتقال هدرهای امنیتی (فقط هدرهایی که خودمان برای امنیت تعریف کردیم)
37
  headers = {
 
 
38
  'X-App-Auth': request.headers.get('X-App-Auth', ''),
39
- 'X-CSRF-Token': request.headers.get('X-CSRF-Token', ''),
40
  }
41
 
42
- # اگر درخواست JSON بود، هدر Content-Type را تنظیم می‌کنیم
43
  if request.is_json:
44
  headers['Content-Type'] = 'application/json'
 
 
45
 
46
  # حذف هدرهای خالی
47
  headers = {k: v for k, v in headers.items() if v}
48
 
49
  try:
50
  if request.method == 'POST':
51
- # بررسی اینکه آیا فایل صوتی در درخواست آپلود شده است (مثل بخش کلون صدا)
52
  if request.files:
53
- files = {k: (v.filename, v.stream, v.mimetype) for k, v in request.files.items()}
54
- res = requests.post(url, data=request.form, files=files, headers=headers)
 
 
 
 
 
55
  else:
56
- # درخواست های معمولی (JSON)
57
- res = requests.post(url, data=request.get_data(), headers=headers)
58
  else:
59
- # درخواست های GET (مثل دانلود فایل)
60
- res = requests.get(url, params=request.args, headers=headers)
61
 
62
- # برگرداندن پاسخ هاگینگ فیس مستقیما به سایت (بدون تغییر)
63
  return Response(
64
  res.content,
65
  status=res.status_code,
66
  content_type=res.headers.get('Content-Type', 'application/json')
67
  )
 
 
68
  except Exception as e:
69
- print(f"Proxy Error: {e}")
70
- return str(e), 500
71
 
72
  def run_flask():
73
- # اجرای وب سرور در پس‌زمینه
74
  app.run(host="0.0.0.0", port=7860, threaded=True)
75
 
76
 
77
  # ====================================================================
78
- # 🤖 بخش دوم: تنظیمات ربات روبیکا (تولید صدای مستقیم برای کاربران داخلی)
79
  # ====================================================================
80
-
81
- # سرورهای تولید صدای ربات
82
  WORKER_URLS =[
83
  "https://hamed744-ttspro.hf.space/generate",
84
  "https://hamed744-ttspro2.hf.space/generate",
@@ -91,7 +96,6 @@ WORKER_URLS =[
91
  "https://hamed744-ttspro9.hf.space/generate",
92
  ]
93
 
94
- # لیست گویندگان
95
  SPEAKERS = {
96
  "1": ("شهاب (مرد)", "Charon"), "2": ("آوا (زن)", "Zephyr"), "3": ("نوید (مرد)", "Achird"),
97
  "4": ("آرمان (مرد)", "Zubenelgenubi"), "5": ("مهسا (زن)", "Vindemiatrix"), "6": ("دانا (مرد)", "Rasalgethi"),
@@ -105,22 +109,13 @@ SPEAKERS = {
105
  "28": ("مهتاب (زن)", "Kore"), "29": ("سام (مرد)", "Fenrir"), "30": ("لیدا (زن)", "Leda")
106
  }
107
 
108
- # دیکشنری برای ذخیره موقت متن کاربر
109
  user_states = {}
110
 
111
- # پردازش و ساخت صدا در پس‌زمینه (برای ربات)
112
  async def process_tts(client, chat_id, user_text, speaker_id, speaker_name):
113
  try:
114
  await client.send_message(chat_id, f"⏳ در حال ساخت صدا با گوینده «{speaker_name}»...\n(لطفاً چند ثانیه صبور باشید)")
115
 
116
- payload = {
117
- "text": user_text,
118
- "speaker": speaker_id,
119
- "temperature": 1.5,
120
- "prompt": "",
121
- "use_live_model": True
122
- }
123
-
124
  headers = {"User-Agent": "Mozilla/5.0", "Content-Type": "application/json"}
125
  audio_bytes = None
126
  last_error = "هیچ پاسخی دریافت نشد"
@@ -129,7 +124,7 @@ async def process_tts(client, chat_id, user_text, speaker_id, speaker_name):
129
  random.shuffle(workers)
130
 
131
  async with aiohttp.ClientSession(headers=headers) as session:
132
- for worker_url in workers[:3]: # حداکثر ۳ تلاش در سرورهای مختلف
133
  try:
134
  async with session.post(worker_url, json=payload, timeout=60) as response:
135
  if response.status == 200:
@@ -156,20 +151,17 @@ async def process_tts(client, chat_id, user_text, speaker_id, speaker_name):
156
  try:
157
  await client.send_document(chat_id, file_name)
158
  except Exception:
159
- await client.send_message(chat_id, "✅ صدا ساخته شد اما ربات محدودیت ارسال فایل دارد.")
160
 
161
  if os.path.exists(file_name):
162
  os.remove(file_name)
163
  else:
164
- error_msg = f"❌ سرورها در حال حاضر خواب یا درگیر هستند.\n\n🔴 دلیل فنی:\n{last_error}\n\nلطفا چند ثانیه دیگر دوباره تلاش کنید."
165
- await client.send_message(chat_id, error_msg)
166
 
167
  except Exception as e:
168
  print(f"خطای پردازش صدا: {e}")
169
  traceback.print_exc()
170
 
171
-
172
- # راه‌اندازی ربات روبیکا
173
  bot_token = os.environ.get("RUBIKA_AUTH", "").strip()
174
 
175
  if bot_token:
@@ -178,7 +170,6 @@ if bot_token:
178
  @bot.on_update(filters.private)
179
  async def main_handler(client, update):
180
  try:
181
- # استخراج متن پیام
182
  user_text = ""
183
  if hasattr(update, "text") and update.text:
184
  user_text = update.text
@@ -187,48 +178,33 @@ if bot_token:
187
  elif hasattr(update, "new_message") and hasattr(update.new_message, "text") and update.new_message.text:
188
  user_text = update.new_message.text
189
 
190
- if not user_text:
191
- return
192
-
193
  chat_id = getattr(update, "chat_id", None) or getattr(update, "author_guid", None) or getattr(update, "object_guid", None)
194
- if not chat_id:
195
- return
196
 
197
  user_text_str = str(user_text).strip()
198
 
199
- # پیام خوشامدگویی
200
- if user_text_str in["/start", "سلام"]:
201
- welcome_text = "سلام! 🎙️\nمن ربات هوش مصنوعی تبدیل متن به صدا هستم.\n\nهر متنی که دوست داری رو برام بفرست تا با ده‌ها گوینده مختلف برات بخونمش!"
202
- await update.reply(welcome_text)
203
  return
204
 
205
- # بررسی اینکه آیا کاربر در حال انتخاب گوینده است (ارسال عدد)
206
  if chat_id in user_states:
207
  if user_text_str.isdigit() and user_text_str in SPEAKERS:
208
  speaker_name, speaker_id = SPEAKERS[user_text_str]
209
- saved_text = user_states[chat_id]
210
-
211
- # پاک کردن متن از حافظه پس از انتخاب گوینده
212
- del user_states[chat_id]
213
-
214
- # ارسال پروسه ساخت صدا به پس‌زمینه
215
  asyncio.create_task(process_tts(client, chat_id, saved_text, speaker_id, speaker_name))
216
  return
217
  elif user_text_str.isdigit():
218
  await update.reply("❌ شماره وارد شده نامعتبر است! لطفاً یک عدد بین ۱ تا ۳۰ بفرستید.")
219
  return
220
 
221
- # اگر پیام عدد نبود، یعنی کاربر یک متن جدید برای تبدیل فرستاده است
222
  if len(user_text_str) > 500:
223
  await update.reply("⚠️ کاربر گرامی، لطفاً متنی کوتاه‌تر از ۵۰۰ کاراکتر بفرستید.")
224
  return
225
 
226
- # ذخیره متن در حافظه
227
  user_states[chat_id] = user_text_str
228
 
229
- # ارسال منوی عددی گویندگان
230
- menu_text = """📝 متن شما با موفقیت ذخیره شد!
231
- لطفاً فقط **شماره** گوینده مورد نظر خود را از لیست زیر بفرستید (مثلا بفرستید: 1):
232
 
233
  1. شهاب (مرد) | 2. آوا (زن) | 3. نوید (مرد)
234
  4. آرمان (مرد) | 5. مهسا (زن) | 6. دانا (مرد)
@@ -240,24 +216,13 @@ if bot_token:
240
  22. ترانه (زن) | 23. نیکو (زن) | 24. هستی (زن)
241
  25. کامیار (مرد)| 26. کیانوش (مرد)| 27. پویا (مرد)
242
  28. مهتاب (زن) | 29. سام (مرد) | 30. لیدا (زن)"""
243
-
244
  await update.reply(menu_text)
245
 
246
  except Exception as e:
247
- print(f"خطای کلی ربات: {e}")
248
  traceback.print_exc()
249
- else:
250
- print("خطا: توکن RUBIKA_AUTH تنظیم نشده است!")
251
-
252
 
253
- # ====================================================================
254
- # 🚀 اجرای همزمان Flask و Rubika Bot
255
- # ====================================================================
256
  if __name__ == "__main__":
257
- # اجرای Flask در یک Thread مجزا
258
  threading.Thread(target=run_flask, daemon=True).start()
259
-
260
- # اجرای ربات روبیکا در Thread اصلی
261
  if bot_token:
262
- print("سیستم کامل شد! تونل Flask و ربات روبیکا همزمان روشن شدند...")
263
  bot.run()
 
9
  from rubpy.bot import BotClient, filters
10
 
11
  # ====================================================================
12
+ # 🌐 بخش اول: وب‌سرور تونل (Proxy) برای دور زدن قطعی اینترنت سایت
13
  # ====================================================================
14
  app = Flask(__name__)
15
 
 
18
 
19
  @app.route('/')
20
  def home():
21
+ return "ربات روبیکا و سرور تونل Ai Sada فعال است! 🚀"
22
 
23
+ @app.route('/proxy/<target>/<path:subpath>', methods=['GET', 'POST', 'OPTIONS'])
 
24
  def proxy_hub(target, subpath):
25
+ if request.method == 'OPTIONS':
26
+ return Response("", status=200)
27
+
28
  if target == 'podcast':
29
  base_url = HF_PODCAST_URL
30
  elif target == 'sada':
 
34
 
35
  url = f"{base_url}/{subpath}"
36
 
37
+ # هدرهای دور زدن فیلترینگ و کلودفلر
38
  headers = {
39
+ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
40
+ 'Accept': '*/*',
41
  'X-App-Auth': request.headers.get('X-App-Auth', ''),
42
+ 'X-CSRF-Token': request.headers.get('X-CSRF-Token', '')
43
  }
44
 
 
45
  if request.is_json:
46
  headers['Content-Type'] = 'application/json'
47
+ elif request.content_type and not request.files:
48
+ headers['Content-Type'] = request.content_type
49
 
50
  # حذف هدرهای خالی
51
  headers = {k: v for k, v in headers.items() if v}
52
 
53
  try:
54
  if request.method == 'POST':
 
55
  if request.files:
56
+ # تبدیل امن فایل‌های صوتی برای آپلود بدون قطعی استریم
57
+ files_dict = {}
58
+ for k, v in request.files.items():
59
+ files_dict[k] = (v.filename, v.read(), v.content_type)
60
+
61
+ form_data = dict(request.form)
62
+ res = requests.post(url, data=form_data, files=files_dict, headers=headers, timeout=120)
63
  else:
64
+ data = request.get_data()
65
+ res = requests.post(url, data=data, headers=headers, timeout=120)
66
  else:
67
+ res = requests.get(url, params=request.args, headers=headers, timeout=120)
 
68
 
 
69
  return Response(
70
  res.content,
71
  status=res.status_code,
72
  content_type=res.headers.get('Content-Type', 'application/json')
73
  )
74
+ except requests.exceptions.Timeout:
75
+ return Response('{"message": "ارتباط با سرور هوش مصنوعی قطع شد (تایم‌اوت)"}', status=504, mimetype='application/json')
76
  except Exception as e:
77
+ print(f"Proxy Error: {str(e)}")
78
+ return Response(f'{{"message": "ارور تونل پایتون: {str(e)}"}}', status=500, mimetype='application/json')
79
 
80
  def run_flask():
 
81
  app.run(host="0.0.0.0", port=7860, threaded=True)
82
 
83
 
84
  # ====================================================================
85
+ # 🤖 بخش دوم: ربات روبیکا (تولید صدای مستقیم)
86
  # ====================================================================
 
 
87
  WORKER_URLS =[
88
  "https://hamed744-ttspro.hf.space/generate",
89
  "https://hamed744-ttspro2.hf.space/generate",
 
96
  "https://hamed744-ttspro9.hf.space/generate",
97
  ]
98
 
 
99
  SPEAKERS = {
100
  "1": ("شهاب (مرد)", "Charon"), "2": ("آوا (زن)", "Zephyr"), "3": ("نوید (مرد)", "Achird"),
101
  "4": ("آرمان (مرد)", "Zubenelgenubi"), "5": ("مهسا (زن)", "Vindemiatrix"), "6": ("دانا (مرد)", "Rasalgethi"),
 
109
  "28": ("مهتاب (زن)", "Kore"), "29": ("سام (مرد)", "Fenrir"), "30": ("لیدا (زن)", "Leda")
110
  }
111
 
 
112
  user_states = {}
113
 
 
114
  async def process_tts(client, chat_id, user_text, speaker_id, speaker_name):
115
  try:
116
  await client.send_message(chat_id, f"⏳ در حال ساخت صدا با گوینده «{speaker_name}»...\n(لطفاً چند ثانیه صبور باشید)")
117
 
118
+ payload = {"text": user_text, "speaker": speaker_id, "temperature": 1.5, "prompt": "", "use_live_model": True}
 
 
 
 
 
 
 
119
  headers = {"User-Agent": "Mozilla/5.0", "Content-Type": "application/json"}
120
  audio_bytes = None
121
  last_error = "هیچ پاسخی دریافت نشد"
 
124
  random.shuffle(workers)
125
 
126
  async with aiohttp.ClientSession(headers=headers) as session:
127
+ for worker_url in workers[:3]:
128
  try:
129
  async with session.post(worker_url, json=payload, timeout=60) as response:
130
  if response.status == 200:
 
151
  try:
152
  await client.send_document(chat_id, file_name)
153
  except Exception:
154
+ await client.send_message(chat_id, "✅ صدا ساخته شد اما محدودیت ارسال فایل در روبیکا وجود دارد.")
155
 
156
  if os.path.exists(file_name):
157
  os.remove(file_name)
158
  else:
159
+ await client.send_message(chat_id, f"❌ خطای سرور:\n{last_error}\n\nلطفا چند ثانیه دیگر دوباره تلاش کنید.")
 
160
 
161
  except Exception as e:
162
  print(f"خطای پردازش صدا: {e}")
163
  traceback.print_exc()
164
 
 
 
165
  bot_token = os.environ.get("RUBIKA_AUTH", "").strip()
166
 
167
  if bot_token:
 
170
  @bot.on_update(filters.private)
171
  async def main_handler(client, update):
172
  try:
 
173
  user_text = ""
174
  if hasattr(update, "text") and update.text:
175
  user_text = update.text
 
178
  elif hasattr(update, "new_message") and hasattr(update.new_message, "text") and update.new_message.text:
179
  user_text = update.new_message.text
180
 
181
+ if not user_text: return
 
 
182
  chat_id = getattr(update, "chat_id", None) or getattr(update, "author_guid", None) or getattr(update, "object_guid", None)
183
+ if not chat_id: return
 
184
 
185
  user_text_str = str(user_text).strip()
186
 
187
+ if user_text_str in ["/start", "سلام"]:
188
+ await update.reply("سلام! 🎙️\nمن ربات هوش مصنوعی تبدیل متن به صدا هستم.\nهر متنی دوست داری بفرست تا با ده‌ها گوینده مختلف برات بخونمش!")
 
 
189
  return
190
 
 
191
  if chat_id in user_states:
192
  if user_text_str.isdigit() and user_text_str in SPEAKERS:
193
  speaker_name, speaker_id = SPEAKERS[user_text_str]
194
+ saved_text = user_states.pop(chat_id)
 
 
 
 
 
195
  asyncio.create_task(process_tts(client, chat_id, saved_text, speaker_id, speaker_name))
196
  return
197
  elif user_text_str.isdigit():
198
  await update.reply("❌ شماره وارد شده نامعتبر است! لطفاً یک عدد بین ۱ تا ۳۰ بفرستید.")
199
  return
200
 
 
201
  if len(user_text_str) > 500:
202
  await update.reply("⚠️ کاربر گرامی، لطفاً متنی کوتاه‌تر از ۵۰۰ کاراکتر بفرستید.")
203
  return
204
 
 
205
  user_states[chat_id] = user_text_str
206
 
207
+ menu_text = """📝 متن ذخیره شد! فقط **شماره** گوینده را از لیست زیر بفرستید:
 
 
208
 
209
  1. شهاب (مرد) | 2. آوا (زن) | 3. نوید (مرد)
210
  4. آرمان (مرد) | 5. مهسا (زن) | 6. دانا (مرد)
 
216
  22. ترانه (زن) | 23. نیکو (زن) | 24. هستی (زن)
217
  25. کامیار (مرد)| 26. کیانوش (مرد)| 27. پویا (مرد)
218
  28. مهتاب (زن) | 29. سام (مرد) | 30. لیدا (زن)"""
 
219
  await update.reply(menu_text)
220
 
221
  except Exception as e:
 
222
  traceback.print_exc()
 
 
 
223
 
 
 
 
224
  if __name__ == "__main__":
 
225
  threading.Thread(target=run_flask, daemon=True).start()
 
 
226
  if bot_token:
227
+ print("ربات روبیکا و سرور تونل روشن شد...")
228
  bot.run()