Opera8 commited on
Commit
7ed6519
·
verified ·
1 Parent(s): 1b50641

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +51 -123
main.py CHANGED
@@ -32,19 +32,16 @@ def custom_input(prompt):
32
  print(f"[سیستم لاگین] درخواست از سرور: {prompt}")
33
  prompt_lower = prompt.lower()
34
 
35
- # مرحله اول: گرفتن شماره موبایل
36
  if "شماره" in prompt_lower or "phone" in prompt_lower or "number" in prompt_lower:
37
  login_state["step"] = "phone"
38
  while login_state["step"] != "processing_phone":
39
  time.sleep(1)
40
  return login_state["phone"]
41
 
42
- # 🟢 مرحله مهم (حل مشکل کرش): تایید کردن اتوماتیک صحت شماره موبایل
43
  elif "correct" in prompt_lower or "y or n" in prompt_lower or "y/n" in prompt_lower:
44
  print("[سیستم لاگین] تایید خودکار شماره (y)")
45
  return "y"
46
 
47
- # مرحله دوم: گرفتن کد تایید پیامک شده
48
  elif "کد" in prompt_lower or "code" in prompt_lower or "verify" in prompt_lower:
49
  login_state["step"] = "code"
50
  while login_state["step"] != "processing_code":
@@ -52,11 +49,10 @@ def custom_input(prompt):
52
  threading.Thread(target=wait_and_success).start()
53
  return login_state["code"]
54
 
55
- # بستن راه کرش برای پسورد دو مرحله‌ای یا هر سوال پیش‌بینی نشده‌ی دیگر
56
  return ""
57
 
58
  def wait_and_success():
59
- time.sleep(6) # صبر برای ساخت فایل سشن توسط روبیکا
60
  if os.path.exists("my_userbot.sqlite"):
61
  try:
62
  with open("my_userbot.sqlite", "rb") as f:
@@ -68,7 +64,7 @@ def wait_and_success():
68
  builtins.input = custom_input
69
 
70
  # ==============================================================================
71
- # 🟢 رابط کاربری وب (پنل مدیریت شیک در هاگینگ فیس)
72
  # ==============================================================================
73
  app = Flask(__name__)
74
 
@@ -87,52 +83,40 @@ HTML_TEMPLATE = """
87
  .card { background: white; padding: 40px; border-radius: 15px; box-shadow: 0 10px 20px rgba(0,0,0,0.1); width: 100%; max-width: 450px; text-align: center; }
88
  h2 { color: #2c3e50; margin-bottom: 15px; }
89
  p { color: #555; font-size: 14px; margin-bottom: 25px; line-height: 1.6; }
90
- input[type="text"] { width: 85%; padding: 12px; margin-bottom: 20px; border: 2px solid #ddd; border-radius: 8px; font-size: 16px; text-align: center; direction: ltr; transition: border 0.3s; }
91
- input[type="text"]:focus { border-color: #007bff; outline: none; }
92
- button { background-color: #007bff; color: white; border: none; padding: 12px 20px; width: 95%; border-radius: 8px; font-size: 16px; font-weight: bold; cursor: pointer; transition: background 0.3s; }
93
- button:hover { background-color: #0056b3; }
94
  .loader { border: 4px solid #f3f3f3; border-top: 4px solid #007bff; border-radius: 50%; width: 40px; height: 40px; animation: spin 1s linear infinite; margin: 0 auto 20px auto; }
95
  @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }
96
- textarea { width: 90%; height: 120px; border: 2px solid #ddd; border-radius: 8px; padding: 10px; font-size: 12px; direction: ltr; text-align: left; resize: none; margin-bottom: 20px; background: #f8f9fa; cursor: pointer;}
97
- .success { color: #28a745; font-weight: bold; font-size: 20px; margin-bottom: 15px;}
98
- .warning { color: #dc3545; font-size: 12px; font-weight: bold; }
99
  </style>
100
  </head>
101
  <body>
102
  <div class="card">
103
  <h2>🚀 پنل اتصال ربات ۲ گیگابایتی</h2>
104
-
105
  {% if state.step == 'phone' %}
106
- <p>برای فعال‌سازی ربات، <b>شماره موبایل</b> اکانت روبیکای خود را وارد کنید.</p>
107
  <form action="/submit_phone" method="POST">
108
- <input type="text" name="phone" placeholder="989123456789" required autocomplete="off">
109
  <button type="submit">دریافت کد تایید</button>
110
  </form>
111
-
112
  {% elif state.step == 'processing_phone' %}
113
- <div class="loader"></div>
114
- <p>در حال برقراری ارتباط با سرورهای روبیکا...</p>
115
-
116
  {% elif state.step == 'code' %}
117
- <p><b>کد ۵ رقمی</b> ارسال شده به پیام‌های روبیکا را وارد کنید.</p>
118
  <form action="/submit_code" method="POST">
119
- <input type="text" name="code" placeholder="12345" required autocomplete="off">
120
  <button type="submit">تایید و ورود</button>
121
  </form>
122
-
123
  {% elif state.step == 'processing_code' %}
124
- <div class="loader"></div>
125
- <p>در حال تایید کد و ساخت نشست (Session)...</p>
126
-
127
  {% elif state.step == 'success' %}
128
- <div class="success">✅ ربات با موفقیت متصل شد!</div>
129
- <p>متن زیر را کپی کنید و در تنظیمات اسپیس (Variables)، در متغیری به نام <b>SESSION_STRING</b> قرار دهید تا با ری‌استارت شدن سرور، ربات خاموش نشود:</p>
130
- <textarea readonly onclick="this.select()">{{ state.session_string }}</textarea>
131
- <p class="warning">⚠️ این متن محرمانه است، آن را به هیچکس ندهید.</p>
132
-
133
  {% elif state.step == 'logged_in' %}
134
- <div class="success">✅ ربات روشن و آماده کار است!</div>
135
- <p>اکنون می‌توانید لینک‌های خود را در روبیکا (پیام‌های ذخیره شده) ارسال کنید تا فایل تا حجم ۲ گیگابایت مستقیماً آپلود شود.</p>
136
  {% endif %}
137
  </div>
138
  </body>
@@ -163,116 +147,60 @@ def run_flask():
163
  app.run(host="0.0.0.0", port=7860, threaded=True)
164
 
165
  # ==============================================================================
166
- # 🟢 سیستم لود کردن نشست (در صورت وجود)
167
- # ==============================================================================
168
- session_string = os.environ.get("SESSION_STRING", "")
169
- session_filename = "my_userbot.sqlite"
170
-
171
- if session_string:
172
- with open(session_filename, "wb") as f:
173
- f.write(base64.b64decode(session_string))
174
- login_state["step"] = "logged_in"
175
- print("✅ فایل سشن با موفقیت از متغیر محیطی بارگذاری شد.")
176
- elif os.path.exists(session_filename) and os.path.getsize(session_filename) > 0:
177
- login_state["step"] = "logged_in"
178
- else:
179
- login_state["step"] = "phone"
180
-
181
- bot = Client("my_userbot")
182
-
183
- # ==============================================================================
184
- # 🟢 توابع دانلود و آپلود 2 گیگابایتی
185
  # ==============================================================================
186
  async def download_large_file(url, chat_id, message_id, client):
187
  if "dropbox.com" in url:
188
  url = url.replace("dl=0", "dl=1") if "dl=0" in url else (url + "&dl=1" if "?" in url else url + "?dl=1")
189
-
190
  temp_dir = "/app/downloads"
191
  os.makedirs(temp_dir, exist_ok=True)
192
-
193
- parsed_url = urllib.parse.urlparse(url)
194
- filename = os.path.basename(parsed_url.path) or f"file_{uuid.uuid4().hex[:6]}.dat"
195
- file_path = os.path.join(temp_dir, f"{uuid.uuid4().hex[:4]}_{filename}")
196
-
197
- status_msg_id = None
198
  try:
199
- status_msg = await client.send_message(chat_id, "⏳ در حال دانلود فایل از اینترنت آزاد...\n(محدودیت آپلود در این اکانت: تا 2 گیگابایت)", reply_to_message_id=message_id)
200
- status_msg_id = getattr(status_msg, 'message_id', None) or (status_msg.get('message_update', {}).get('message_id') if isinstance(status_msg, dict) else None)
201
- except: pass
202
-
203
- try:
204
- headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"}
205
- async with aiohttp.ClientSession(headers=headers) as session:
206
  async with session.get(url, timeout=0) as response:
207
- if response.status != 200:
208
- if status_msg_id: await client.edit_message_text(chat_id, status_msg_id, f"❌ خطا در دانلود! کد: {response.status}")
209
- return None, status_msg_id
210
-
211
  with open(file_path, 'wb') as f:
212
  async for chunk in response.content.iter_chunked(2 * 1024 * 1024):
213
  if chunk: f.write(chunk)
214
-
215
- if status_msg_id: await client.edit_message_text(chat_id, status_msg_id, "✅ دانلود کامل شد. در حال آپلود فایل حجیم در روبیکا...")
216
- return file_path, status_msg_id
217
- except Exception as e:
218
- if status_msg_id: await client.edit_message_text(chat_id, status_msg_id, f"❌ خطای شبکه: {str(e)[:100]}")
219
- return None, status_msg_id
220
 
221
  async def process_url_and_upload(client, chat_id, message_id, url):
222
- file_path, status_msg_id = await download_large_file(url, chat_id, message_id, client)
223
-
224
- if file_path and os.path.exists(file_path):
225
  try:
226
- caption_text = f"📥 دانلود مستقیم:\n🔗 {url}"
227
- upload_success = False
228
- for attempt in range(5):
229
- try:
230
- try: await client.send_document(chat_id, document=file_path, caption=caption_text)
231
- except TypeError: await client.send_document(chat_id, file=file_path, caption=caption_text)
232
- except: await client.send_document(chat_id, file_path, caption=caption_text)
233
- upload_success = True
234
- break
235
- except Exception:
236
- await asyncio.sleep(4)
237
-
238
- if not upload_success: raise Exception("سرور روبیکا فایل را پس از ۵ بار تلاش نپذیرفت.")
239
-
240
- if status_msg_id:
241
- try: await client.delete_messages(chat_id, [status_msg_id])
242
- except: pass
243
-
244
- except Exception as e:
245
- error_txt = f"❌ خطا در عملیات آپلود:\n{str(e)[:150]}"
246
- if status_msg_id: await client.edit_message_text(chat_id, status_msg_id, error_txt)
247
- else: await client.send_message(chat_id, error_txt)
248
  finally:
249
- try: os.remove(file_path)
250
- except: pass
251
 
252
  # ==============================================================================
253
- # 🟢 هندلر دریافت پیام (مخصوص یوزربات)
254
  # ==============================================================================
 
 
 
 
 
 
 
 
 
 
255
  @bot.on_message_updates(filters.private)
256
  async def main_handler(client, update):
257
  try:
258
- msg_obj = getattr(update, "message", None) or getattr(update, "new_message", None) or update
259
- chat_id = getattr(update, 'object_guid', None) or getattr(update, 'author_guid', None) or getattr(update, "chat_id", None)
260
- msg_id = getattr(update, "message_id", None) or (msg_obj.get("message_id") if isinstance(msg_obj, dict) else getattr(msg_obj, "message_id", None))
261
- user_text_str = str(getattr(update, "text", "") or getattr(msg_obj, "text", "")).strip()
262
-
263
- if not user_text_str: return
264
-
265
- if user_text_str.lower() in ["/start", "سلام"]:
266
- await client.send_message(chat_id, "👋 سلام مدیر! لینک فایلت رو بفرست تا با اکانت خودت تا حجم ۲ گیگ برات آپلودش کنم.")
267
- return
268
-
269
- if user_text_str.lower().startswith("http"):
270
- asyncio.create_task(process_url_and_upload(client, chat_id, msg_id, user_text_str))
271
-
272
- except Exception: traceback.print_exc()
273
 
274
- # ==============================================================================
275
- # 🟢 نقطه شروع
276
- # ==============================================================================
277
  if __name__ == "__main__":
278
- # بالا آوردن وب‌سرور پن
 
 
 
32
  print(f"[سیستم لاگین] درخواست از سرور: {prompt}")
33
  prompt_lower = prompt.lower()
34
 
 
35
  if "شماره" in prompt_lower or "phone" in prompt_lower or "number" in prompt_lower:
36
  login_state["step"] = "phone"
37
  while login_state["step"] != "processing_phone":
38
  time.sleep(1)
39
  return login_state["phone"]
40
 
 
41
  elif "correct" in prompt_lower or "y or n" in prompt_lower or "y/n" in prompt_lower:
42
  print("[سیستم لاگین] تایید خودکار شماره (y)")
43
  return "y"
44
 
 
45
  elif "کد" in prompt_lower or "code" in prompt_lower or "verify" in prompt_lower:
46
  login_state["step"] = "code"
47
  while login_state["step"] != "processing_code":
 
49
  threading.Thread(target=wait_and_success).start()
50
  return login_state["code"]
51
 
 
52
  return ""
53
 
54
  def wait_and_success():
55
+ time.sleep(6)
56
  if os.path.exists("my_userbot.sqlite"):
57
  try:
58
  with open("my_userbot.sqlite", "rb") as f:
 
64
  builtins.input = custom_input
65
 
66
  # ==============================================================================
67
+ # 🟢 رابط کاربری وب
68
  # ==============================================================================
69
  app = Flask(__name__)
70
 
 
83
  .card { background: white; padding: 40px; border-radius: 15px; box-shadow: 0 10px 20px rgba(0,0,0,0.1); width: 100%; max-width: 450px; text-align: center; }
84
  h2 { color: #2c3e50; margin-bottom: 15px; }
85
  p { color: #555; font-size: 14px; margin-bottom: 25px; line-height: 1.6; }
86
+ input[type="text"] { width: 85%; padding: 12px; margin-bottom: 20px; border: 2px solid #ddd; border-radius: 8px; font-size: 16px; text-align: center; direction: ltr; }
87
+ button { background-color: #007bff; color: white; border: none; padding: 12px 20px; width: 95%; border-radius: 8px; font-size: 16px; font-weight: bold; cursor: pointer; }
 
 
88
  .loader { border: 4px solid #f3f3f3; border-top: 4px solid #007bff; border-radius: 50%; width: 40px; height: 40px; animation: spin 1s linear infinite; margin: 0 auto 20px auto; }
89
  @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }
90
+ textarea { width: 90%; height: 120px; border: 2px solid #ddd; border-radius: 8px; padding: 10px; font-size: 12px; direction: ltr; }
91
+ .success { color: #28a745; font-weight: bold; font-size: 20px; }
 
92
  </style>
93
  </head>
94
  <body>
95
  <div class="card">
96
  <h2>🚀 پنل اتصال ربات ۲ گیگابایتی</h2>
 
97
  {% if state.step == 'phone' %}
98
+ <p>شماره موبایل اکانت روبیکای خود را وارد کنید.</p>
99
  <form action="/submit_phone" method="POST">
100
+ <input type="text" name="phone" placeholder="989123456789" required>
101
  <button type="submit">دریافت کد تایید</button>
102
  </form>
 
103
  {% elif state.step == 'processing_phone' %}
104
+ <div class="loader"></div><p>در حال ارتباط با روبیکا...</p>
 
 
105
  {% elif state.step == 'code' %}
106
+ <p>کد ۵ رقمی روبیکا را وارد کنید.</p>
107
  <form action="/submit_code" method="POST">
108
+ <input type="text" name="code" placeholder="12345" required>
109
  <button type="submit">تایید و ورود</button>
110
  </form>
 
111
  {% elif state.step == 'processing_code' %}
112
+ <div class="loader"></div><p>در حال تایید کد...</p>
 
 
113
  {% elif state.step == 'success' %}
114
+ <div class="success">✅ متصل شد!</div>
115
+ <p>این متن را در متغیر <b>SESSION_STRING</b> قرار دهید:</p>
116
+ <textarea readonly>{{ state.session_string }}</textarea>
 
 
117
  {% elif state.step == 'logged_in' %}
118
+ <div class="success">✅ ربات فعال است!</div>
119
+ <p>اکنون لینک‌های خود را در روبیکا ارسال کنید.</p>
120
  {% endif %}
121
  </div>
122
  </body>
 
147
  app.run(host="0.0.0.0", port=7860, threaded=True)
148
 
149
  # ==============================================================================
150
+ # 🟢 توابع دانلود و آپلود (Userbot)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
151
  # ==============================================================================
152
  async def download_large_file(url, chat_id, message_id, client):
153
  if "dropbox.com" in url:
154
  url = url.replace("dl=0", "dl=1") if "dl=0" in url else (url + "&dl=1" if "?" in url else url + "?dl=1")
 
155
  temp_dir = "/app/downloads"
156
  os.makedirs(temp_dir, exist_ok=True)
157
+ filename = f"file_{uuid.uuid4().hex[:6]}.dat"
158
+ file_path = os.path.join(temp_dir, filename)
 
 
 
 
159
  try:
160
+ status_msg = await client.send_message(chat_id, "⏳ در حال دانلود فایل (تا 2 گیگ)...", reply_to_message_id=message_id)
161
+ status_id = status_msg.message_id if hasattr(status_msg, 'message_id') else status_msg.get('message_id')
162
+ async with aiohttp.ClientSession() as session:
 
 
 
 
163
  async with session.get(url, timeout=0) as response:
 
 
 
 
164
  with open(file_path, 'wb') as f:
165
  async for chunk in response.content.iter_chunked(2 * 1024 * 1024):
166
  if chunk: f.write(chunk)
167
+ await client.edit_message_text(chat_id, status_id, "✅ دانلود کامل شد. در حال آپلود در روبیکا...")
168
+ return file_path, status_id
169
+ except: return None, None
 
 
 
170
 
171
  async def process_url_and_upload(client, chat_id, message_id, url):
172
+ file_path, status_id = await download_large_file(url, chat_id, message_id, client)
173
+ if file_path:
 
174
  try:
175
+ await client.send_document(chat_id, file_path, caption=f"📥 دانلود مستقیم:\n🔗 {url}")
176
+ if status_id: await client.delete_messages(chat_id, [status_id])
177
+ except: pass
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
178
  finally:
179
+ if os.path.exists(file_path): os.remove(file_path)
 
180
 
181
  # ==============================================================================
182
+ # 🟢 سیستم لود و اجرای اصلی
183
  # ==============================================================================
184
+ session_string = os.environ.get("SESSION_STRING", "")
185
+ if session_string:
186
+ with open("my_userbot.sqlite", "wb") as f:
187
+ f.write(base64.b64decode(session_string))
188
+ login_state["step"] = "logged_in"
189
+ else:
190
+ login_state["step"] = "phone"
191
+
192
+ bot = Client("my_userbot")
193
+
194
  @bot.on_message_updates(filters.private)
195
  async def main_handler(client, update):
196
  try:
197
+ msg = update.message if hasattr(update, 'message') else update
198
+ text = msg.text
199
+ if text and text.startswith("http"):
200
+ asyncio.create_task(process_url_and_upload(client, msg.object_guid, msg.message_id, text))
201
+ except: pass
 
 
 
 
 
 
 
 
 
 
202
 
 
 
 
203
  if __name__ == "__main__":
204
+ threading.Thread(target=run_flask, daemon=True).start()
205
+ print("🚀 پنل وب روشن شد...")
206
+ bot.run()