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

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +93 -143
main.py CHANGED
@@ -3,87 +3,92 @@ import threading
3
  import random
4
  import aiohttp
5
  import requests
 
 
6
  import traceback
7
  import asyncio
8
- from flask import Flask, request, Response
9
  from rubpy.bot import BotClient, filters
10
 
11
- # ====================================================================
12
- # 🌐 بخش اول: وب‌سرور تونل (Proxy) برای دور زدن قطعی اینترنت سایت
13
- # ====================================================================
14
- app = Flask(__name__)
15
 
16
  HF_PODCAST_URL = "https://ezmarynoori-podgen.hf.space"
17
- HF_SADA_URL = "https://ezmarynoori-sada.hf.space"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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':
31
- base_url = HF_SADA_URL
32
- else:
33
- return "Invalid target", 400
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",
@@ -97,28 +102,20 @@ WORKER_URLS =[
97
  ]
98
 
99
  SPEAKERS = {
100
- "1": ("شهاب (مرد)", "Charon"), "2": ("آوا (زن)", "Zephyr"), "3": ("نوید (مرد)", "Achird"),
101
- "4": ("آرمان (مرد)", "Zubenelgenubi"), "5": ("مهسا (زن)", "Vindemiatrix"), "6": ("دانا (مرد)", "Rasalgethi"),
102
- "7": ("سامان (مرد)", "Sadachbia"), "8": ("آرش (مرد)", "Sadaltager"), "9": ("شبنم (زن)", "Sulafat"),
103
- "10": ("سحر (زن)", "Laomedeia"), "11": ("مریم (زن)", "Achernar"), "12": ("بهرام (مرد)", "Alnilam"),
104
- "13": ("نیکان (مرد)", "Schedar"), "14": ("فرناز (زن)", "Gacrux"), "15": ("سارا (زن)", "Pulcherrima"),
105
- "16": ("مانی (مرد)", "Umbriel"), "17": ("آرتین (مرد)", "Algieba"), "18": ("دلنواز (زن)", "Despina"),
106
- "19": ("روژان (زن)", "Erinome"), "20": ("امید (مرد)", "Algenib"), "21": ("بردیا (مرد)", "Orus"),
107
- "22": ("ترانه (زن)", "Aoede"), "23": ("نیکو (زن)", "Callirrhoe"), "24": ("هستی (زن)", "Autonoe"),
108
- "25": ("کامیار (مرد)", "Enceladus"), "26": ("کیانوش (مرد)", "Iapetus"), "27": ("پویا (مرد)", "Puck"),
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 = "هیچ پاسخی دریافت نشد"
122
 
123
  workers = WORKER_URLS.copy()
124
  random.shuffle(workers)
@@ -128,64 +125,39 @@ async def process_tts(client, chat_id, user_text, speaker_id, speaker_name):
128
  try:
129
  async with session.post(worker_url, json=payload, timeout=60) as response:
130
  if response.status == 200:
131
- content_type = response.headers.get('Content-Type', '')
132
- if 'audio' in content_type or response.content_length > 1000:
133
- audio_bytes = await response.read()
134
- break
135
- else:
136
- last_error = "سرور به جای صدا، فایل نامعتبر داد."
137
- else:
138
- last_error = f"ارور سرور ({response.status})"
139
- except Exception as e:
140
- last_error = str(e)
141
  continue
142
 
143
  if audio_bytes:
144
- file_name = f"audio_{random.randint(1000, 999999)}.wav"
145
- with open(file_name, "wb") as f:
146
- f.write(audio_bytes)
147
-
148
- try:
149
- await client.send_voice(chat_id, file_name)
150
- except Exception:
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:
168
  bot = BotClient(bot_token)
169
-
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
176
- elif hasattr(update, "message") and hasattr(update.message, "text") and update.message.text:
177
- user_text = update.message.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:
@@ -194,35 +166,13 @@ if bot_token:
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. دانا (مرد)
211
- 7. سامان (مرد) | 8. آرش (مرد) | 9. شبنم (زن)
212
- 10. سحر (زن) | 11. مری�� (زن) | 12. بهرام (مرد)
213
- 13. نیکان (مرد)| 14. فرناز (زن) | 15. سارا (زن)
214
- 16. مانی (مرد) | 17. آرتین (مرد) | 18. دلنواز (زن)
215
- 19. روژان (زن) | 20. امید (مرد) | 21. بردیا (مرد)
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()
 
3
  import random
4
  import aiohttp
5
  import requests
6
+ import json
7
+ import time
8
  import traceback
9
  import asyncio
10
+ from flask import Flask
11
  from rubpy.bot import BotClient, filters
12
 
13
+ # 🔴🔴🔴 مسیر فایل PHP سایت خود را اینجا وارد کنید 🔴🔴🔴
14
+ SITE_URL = "https://aisada.ir/tts/proxy.php"
 
 
15
 
16
  HF_PODCAST_URL = "https://ezmarynoori-podgen.hf.space"
17
+
18
+ # =======================================================
19
+ # 🌐 ۱. موتور مکنده (Reverse Tunnel) برای زنده کردن سایت
20
+ # =======================================================
21
+ def reverse_tunnel_worker():
22
+ while True:
23
+ try:
24
+ # ۱. گرفتن درخواست‌ها از سایت ایران
25
+ pull_res = requests.get(f"{SITE_URL}?endpoint=hf-pull", timeout=10)
26
+ if pull_res.status_code == 200:
27
+ tasks = pull_res.json()
28
+ for task in tasks:
29
+ task_id = task.get('id')
30
+ endpoint = task.get('endpoint')
31
+ payload = task.get('payload', {})
32
+
33
+ # تنظیم لینک مقصد (مدل‌های هوش مصنوعی)
34
+ if endpoint == 'generate':
35
+ target_url = f"{HF_PODCAST_URL}/api/generate"
36
+ elif endpoint == 'check-tts-status':
37
+ target_url = f"{HF_PODCAST_URL}/api/check_status"
38
+ elif endpoint == 'create-full-podcast':
39
+ target_url = f"{HF_PODCAST_URL}/api/create-full-podcast"
40
+ elif endpoint == 'podcast-status':
41
+ task_id_param = task.get('get_params', {}).get('task_id', '')
42
+ target_url = f"{HF_PODCAST_URL}/api/podcast-status/{task_id_param}"
43
+ else:
44
+ continue
45
+
46
+ # ۲. ارسال به مدل هوش مصنوعی (داخل هاگینگ فیس)
47
+ headers = {'Content-Type': 'application/json'}
48
+ if endpoint == 'podcast-status':
49
+ model_res = requests.get(target_url, timeout=90)
50
+ else:
51
+ model_res = requests.post(target_url, json=payload, headers=headers, timeout=90)
52
+
53
+ # ۳. ارسال فایل/جواب آماده شده به سایت ایران
54
+ push_url = f"{SITE_URL}?endpoint=hf-push"
55
+ if model_res.status_code == 200:
56
+ content_type = model_res.headers.get('Content-Type', '')
57
+ if 'audio' in content_type or model_res.content[:4] == b'RIFF':
58
+ # ارسال فایل صدا
59
+ files = {'file': (f"{task_id}.wav", model_res.content, 'audio/wav')}
60
+ requests.post(push_url, data={'id': task_id}, files=files, timeout=30)
61
+ else:
62
+ # ارسال پاسخ‌های JSON
63
+ requests.post(push_url, data={'id': task_id, 'json_data': model_res.content}, timeout=30)
64
+ else:
65
+ err = {'error': f"خطای هوش مصنوعی ({model_res.status_code})"}
66
+ requests.post(push_url, data={'id': task_id, 'json_data': json.dumps(err)}, timeout=30)
67
+
68
+ except Exception as e:
69
+ # بی‌صدا بودن خطا برای جلوگیری از توقف حلقه
70
+ pass
71
+
72
+ time.sleep(1) # بررسی سایت هر 1 ثانیه
73
+
74
+ # =======================================================
75
+ # 🌐 ۲. سرور زنده نگه‌دارنده (Flask)
76
+ # =======================================================
77
+ app = Flask(__name__)
78
 
79
  @app.route('/')
80
  def home():
81
+ return "✅ سرور نجات سایت و ربات روبیکا با موفقیت فعال است!"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82
 
83
  def run_flask():
84
+ # شروع بکار موتور مکنده در پس‌زمینه
85
+ threading.Thread(target=reverse_tunnel_worker, daemon=True).start()
86
+ app.run(host="0.0.0.0", port=7860)
87
 
88
 
89
+ # =======================================================
90
+ # 🤖 ۳. ربات روبیکا
91
+ # =======================================================
92
  WORKER_URLS =[
93
  "https://hamed744-ttspro.hf.space/generate",
94
  "https://hamed744-ttspro2.hf.space/generate",
 
102
  ]
103
 
104
  SPEAKERS = {
105
+ "1": ("شهاب", "Charon"), "2": ("آوا", "Zephyr"), "3": ("نوید", "Achird"),
106
+ "4": ("آرمان", "Zubenelgenubi"), "5": ("مهسا", "Vindemiatrix"), "6": ("دانا", "Rasalgethi"),
107
+ "7": ("سامان", "Sadachbia"), "8": ("آرش", "Sadaltager"), "9": ("شبنم", "Sulafat"),
108
+ "10": ("سحر", "Laomedeia")
 
 
 
 
 
 
109
  }
110
 
111
  user_states = {}
112
 
113
  async def process_tts(client, chat_id, user_text, speaker_id, speaker_name):
114
  try:
115
+ await client.send_message(chat_id, f"⏳ در حال ساخت صدا...\n(گوینده: {speaker_name})")
 
116
  payload = {"text": user_text, "speaker": speaker_id, "temperature": 1.5, "prompt": "", "use_live_model": True}
117
  headers = {"User-Agent": "Mozilla/5.0", "Content-Type": "application/json"}
118
  audio_bytes = None
 
119
 
120
  workers = WORKER_URLS.copy()
121
  random.shuffle(workers)
 
125
  try:
126
  async with session.post(worker_url, json=payload, timeout=60) as response:
127
  if response.status == 200:
128
+ audio_bytes = await response.read()
129
+ break
130
+ except Exception:
 
 
 
 
 
 
 
131
  continue
132
 
133
  if audio_bytes:
134
+ file_name = f"voice_{random.randint(1000, 9999)}.wav"
135
+ with open(file_name, "wb") as f: f.write(audio_bytes)
136
+ try: await client.send_voice(chat_id, file_name)
137
+ except: await client.send_document(chat_id, file_name)
138
+ if os.path.exists(file_name): os.remove(file_name)
 
 
 
 
 
 
 
 
 
139
  else:
140
+ await client.send_message(chat_id, "❌ خطای سرور. لطفاً مجدد تلاش کنید.")
141
 
142
  except Exception as e:
 
143
  traceback.print_exc()
144
 
145
  bot_token = os.environ.get("RUBIKA_AUTH", "").strip()
146
 
147
  if bot_token:
148
  bot = BotClient(bot_token)
 
149
  @bot.on_update(filters.private)
150
  async def main_handler(client, update):
151
  try:
152
+ user_text = getattr(update, "text", "") or getattr(getattr(update, "message", None), "text", "") or getattr(getattr(update, "new_message", None), "text", "")
 
 
 
 
 
 
 
153
  if not user_text: return
154
  chat_id = getattr(update, "chat_id", None) or getattr(update, "author_guid", None) or getattr(update, "object_guid", None)
155
  if not chat_id: return
156
+
157
  user_text_str = str(user_text).strip()
158
 
159
+ if user_text_str in["/start", "سلام"]:
160
+ await update.reply("سلام! 🎙️\nهر متنی دوست داری بفرست تا با صداهای مختلف برات بخونمش.")
161
  return
162
 
163
  if chat_id in user_states:
 
166
  saved_text = user_states.pop(chat_id)
167
  asyncio.create_task(process_tts(client, chat_id, saved_text, speaker_id, speaker_name))
168
  return
 
 
 
 
 
 
 
169
 
170
  user_states[chat_id] = user_text_str
171
+ await update.reply("📝 متن شما ذخیره شد!\nیک شماره بین 1 تا 10 برای انتخاب گوینده بفرستید.")
 
 
 
 
 
 
 
 
 
 
 
 
 
172
 
173
  except Exception as e:
174
  traceback.print_exc()
175
 
176
  if __name__ == "__main__":
177
  threading.Thread(target=run_flask, daemon=True).start()
178
+ if bot_token: bot.run()