Opera8 commited on
Commit
c070efd
·
verified ·
1 Parent(s): 2e8b054

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +93 -126
main.py CHANGED
@@ -5,70 +5,39 @@ import threading
5
  import uuid
6
  import urllib.parse
7
  import traceback
8
- import math
9
- import subprocess
10
- import glob
11
- import json
12
  from flask import Flask
 
13
 
14
  # ==============================================================================
15
- # 🟢 تنظیمات و ایمپورتها (مشابه نسخه آلفا پرو شما)
16
  # ==============================================================================
17
- from rubpy.bot import BotClient, filters
18
-
19
  app = Flask(__name__)
20
 
21
  @app.route('/')
22
  def home():
23
- return "🚀 ربات دانلودر هوشمند (پشتیبانی از دراپ‌باکس و برش ویدیو) روشن است!"
24
 
25
  def run_flask():
26
  app.run(host="0.0.0.0", port=7860, threaded=True)
27
 
28
  bot_token = os.environ.get("RUBIKA_AUTH", "").strip()
 
 
 
29
  if not bot_token:
30
- print("❌ توکن ربات وارد نشده است!")
 
 
 
31
  exit()
32
 
33
  bot = BotClient(bot_token)
34
  BOT_GUID = None
35
 
36
  # ==============================================================================
37
- # 🟢 توابع کمکی FFmpeg برای تشخیص و برش ویدیو
38
- # ==============================================================================
39
- def get_video_info(file_path):
40
- try:
41
- cmd = ['ffprobe', '-v', 'quiet', '-print_format', 'json', '-show_format', '-show_streams', file_path]
42
- result = subprocess.check_output(cmd).decode('utf-8')
43
- data = json.loads(result)
44
- duration = float(data.get('format', {}).get('duration', 0.0))
45
- has_video = any(stream.get('codec_type') == 'video' for stream in data.get('streams', []))
46
- return duration, has_video
47
- except Exception:
48
- return 0.0, False
49
-
50
- def split_video(file_path, segment_time):
51
- output_pattern = f"{file_path}_part%03d.mp4"
52
- cmd = [
53
- 'ffmpeg', '-i', file_path,
54
- '-c', 'copy',
55
- '-map', '0',
56
- '-segment_time', str(segment_time),
57
- '-f', 'segment',
58
- '-reset_timestamps', '1',
59
- output_pattern
60
- ]
61
- try:
62
- subprocess.run(cmd, check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
63
- return sorted(glob.glob(f"{file_path}_part*.mp4"))
64
- except Exception:
65
- return []
66
-
67
- # ==============================================================================
68
- # 🟢 تابع دانلود (با قابلیت تبدیل خودکار لینک دراپ‌باکس به لینک مستقیم)
69
  # ==============================================================================
70
  async def download_large_file(url, chat_id, message_id, client):
71
- # 🛑 تبدیل خودکار لینک دراپ‌باکس به لینک مستقیم
72
  if "dropbox.com" in url:
73
  if "dl=0" in url:
74
  url = url.replace("dl=0", "dl=1")
@@ -87,126 +56,124 @@ async def download_large_file(url, chat_id, message_id, client):
87
  status_msg_id = None
88
 
89
  try:
90
- status_msg = await client.send_message(chat_id, "⏳ در حال دانلود فایل از اینترنت آزاد (Dropbox/Global) به سرور...\n(این مرحله بسته به حجم ممکن است طول بکشد)", reply_to_message_id=message_id)
 
 
 
 
91
  status_msg_id = getattr(status_msg, 'message_id', None)
92
  if not status_msg_id and isinstance(status_msg, dict):
93
  status_msg_id = status_msg.get('message_update', {}).get('message_id') or status_msg.get('message_id')
94
  except Exception: pass
95
 
96
  try:
97
- headers = {"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"}
98
-
99
  async with aiohttp.ClientSession(headers=headers) as session:
100
  async with session.get(url, timeout=0) as response:
101
  if response.status != 200:
102
  if status_msg_id:
103
  try: await client.edit_message_text(chat_id, status_msg_id, f"❌ خطا در دسترسی به لینک! کد وضعیت: {response.status}")
104
  except: pass
105
- return None, status_msg_id
106
 
107
  with open(file_path, 'wb') as f:
108
  async for chunk in response.content.iter_chunked(2 * 1024 * 1024):
109
  if chunk: f.write(chunk)
110
 
111
  if status_msg_id:
112
- try: await client.edit_message_text(chat_id, status_msg_id, "✅ دانلود در سرور تکمیل شد.\n📤 در حال بررسی و آپلود در روبیکا...")
113
  except: pass
114
 
115
- return file_path, status_msg_id
116
  except Exception as e:
117
  if status_msg_id:
118
  try: await client.edit_message_text(chat_id, status_msg_id, f"❌ خطای شبکه هنگام دانلود:\n{str(e)[:100]}")
119
  except: pass
120
- return None, status_msg_id
121
 
122
  # ==============================================================================
123
- # 🟢 تابع آپلود و پارت‌بندی (هوشمند)
124
  # ==============================================================================
125
- async def process_url_and_upload(client, chat_id, message_id, url):
126
- file_path, status_msg_id = await download_large_file(url, chat_id, message_id, client)
 
127
 
128
- if file_path and os.path.exists(file_path):
129
- try:
130
- file_size_bytes = os.path.getsize(file_path)
131
- file_size_mb = file_size_bytes / (1024 * 1024)
132
- caption_text = f"📥 فایل شما آماده شد!\n🔗 لینک منبع: {url}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
133
 
134
- if file_size_mb > 49:
135
- duration, has_video = get_video_info(file_path)
136
-
137
- # حالت اول: ویدیو است -> برش زمانی
138
- if has_video and duration > 0:
139
- await client.send_message(chat_id, f"🎬 ویدیوی حجیم ({file_size_mb:.1f} مگابایت) شناسایی شد.\n✂️ در حال برش به پارت‌های MP4 قابل پخش...")
140
- parts_needed = math.ceil(file_size_mb / 40.0)
141
- segment_time = math.ceil(duration / parts_needed)
142
- segments = split_video(file_path, segment_time)
 
143
 
144
- if segments:
145
- for i, seg_path in enumerate(segments):
146
- part_caption = f"{caption_text}\n\n🎬 قسمت {i+1} از {len(segments)}"
147
- upload_success = False
148
- for attempt in range(5):
149
- try:
150
- try: await client.send_file(chat_id, file=seg_path, text=part_caption)
151
- except: await client.send_file(chat_id, seg_path, text=part_caption)
152
- upload_success = True
153
- break
154
- except Exception: await asyncio.sleep(4)
155
- try: os.remove(seg_path)
156
- except: pass
157
- else: raise Exception("خطا در برش ویدیو")
158
-
159
- # حالت دوم: غیر ویدیویی است -> پارت‌بندی دیتایی
160
- else:
161
- await client.send_message(chat_id, f"⚠️ فایل حجیم ({file_size_mb:.1f} مگابایت) تشخیص داده شد.\n📦 در حال تقسیم به پارت‌های ۴۹ مگابایتی...")
162
- chunk_size = 49 * 1024 * 1024
163
- total_parts = math.ceil(file_size_bytes / chunk_size)
164
- with open(file_path, 'rb') as f:
165
- for i in range(1, total_parts + 1):
166
- chunk = f.read(chunk_size)
167
- if not chunk: break
168
- part_path = f"{file_path}.part{i}"
169
- with open(part_path, 'wb') as chunk_file: chunk_file.write(chunk)
170
- part_caption = f"{caption_text}\n\n📦 پارت {i} از {total_parts}"
171
- upload_success = False
172
- for attempt in range(5):
173
- try:
174
- try: await client.send_file(chat_id, file=part_path, text=part_caption)
175
- except: await client.send_file(chat_id, part_path, text=part_caption)
176
- upload_success = True
177
- break
178
- except Exception: await asyncio.sleep(4)
179
- try: os.remove(part_path)
180
- except: pass
181
 
182
- # حالت عادی: زیر 50 مگابایت
 
 
183
  else:
184
- upload_success = False
185
- for attempt in range(5):
186
- try:
187
- try: await client.send_file(chat_id, file=file_path, text=caption_text)
188
- except: await client.send_file(chat_id, file_path, text=caption_text)
189
- upload_success = True
190
- break
191
- except Exception: await asyncio.sleep(4)
192
- if not upload_success: raise Exception("روبیکا فایل را نپذیرفت")
193
 
194
- if status_msg_id:
195
- try: await client.delete_messages(chat_id, [status_msg_id])
196
- except: pass
197
-
198
- except Exception as e:
199
- error_txt = f"❌ خطا در عملیات آپلود:\n{str(e)[:150]}"
200
- if status_msg_id:
201
- try: await client.edit_message_text(chat_id, status_msg_id, error_txt)
202
- except: await client.send_message(chat_id, error_txt)
203
- else: await client.send_message(chat_id, error_txt)
 
 
 
 
 
 
 
204
  finally:
 
205
  try: os.remove(file_path)
206
  except: pass
207
 
208
  # ==============================================================================
209
- # 🟢 هندلر اصلی
210
  # ==============================================================================
211
  @bot.on_update(filters.private)
212
  async def main_handler(client, update):
@@ -231,7 +198,7 @@ async def main_handler(client, update):
231
  if not user_text_str: return
232
 
233
  if user_text_str.lower() in ["/start", "سلام"]:
234
- await client.send_message(chat_id, "👋 سلام! لینک مستقیم هر فایلی (حتی Dropbox) رو بفرست تا برات تو روبیکا آپلود کنم.")
235
  return
236
 
237
  if user_text_str.lower().startswith("http"):
@@ -243,5 +210,5 @@ async def main_handler(client, update):
243
 
244
  if __name__ == "__main__":
245
  threading.Thread(target=run_flask, daemon=True).start()
246
- print("🚀 ربات با قابلیت دراپباکس روشن شد...")
247
  bot.run()
 
5
  import uuid
6
  import urllib.parse
7
  import traceback
 
 
 
 
8
  from flask import Flask
9
+ from rubpy.bot import BotClient, filters
10
 
11
  # ==============================================================================
12
+ # 🟢 تنظیمات و متغیرهای محیطی
13
  # ==============================================================================
 
 
14
  app = Flask(__name__)
15
 
16
  @app.route('/')
17
  def home():
18
+ return "🚀 ربات انتقال به گیت‌هاب (اینترنت ملی) روشن است!"
19
 
20
  def run_flask():
21
  app.run(host="0.0.0.0", port=7860, threaded=True)
22
 
23
  bot_token = os.environ.get("RUBIKA_AUTH", "").strip()
24
+ GITHUB_TOKEN = os.environ.get("GITHUB_TOKEN", "").strip()
25
+ GITHUB_REPO = "Hamed744/internet-melli"
26
+
27
  if not bot_token:
28
+ print("❌ توکن ربات روبیکا وارد نشده است!")
29
+ exit()
30
+ if not GITHUB_TOKEN:
31
+ print("❌ توکن گیت‌هاب وارد نشده است! حتماً در بخش Secrets اضافه کنید.")
32
  exit()
33
 
34
  bot = BotClient(bot_token)
35
  BOT_GUID = None
36
 
37
  # ==============================================================================
38
+ # 🟢 دانلود فایل از لینک به سرور واسط
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
  # ==============================================================================
40
  async def download_large_file(url, chat_id, message_id, client):
 
41
  if "dropbox.com" in url:
42
  if "dl=0" in url:
43
  url = url.replace("dl=0", "dl=1")
 
56
  status_msg_id = None
57
 
58
  try:
59
+ status_msg = await client.send_message(
60
+ chat_id,
61
+ "⏳ در حال دانلود فایل از اینترنت آزاد به سرور...\n(این مرحله بسته به حجم فایل زمان‌بر است)",
62
+ reply_to_message_id=message_id
63
+ )
64
  status_msg_id = getattr(status_msg, 'message_id', None)
65
  if not status_msg_id and isinstance(status_msg, dict):
66
  status_msg_id = status_msg.get('message_update', {}).get('message_id') or status_msg.get('message_id')
67
  except Exception: pass
68
 
69
  try:
70
+ headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"}
 
71
  async with aiohttp.ClientSession(headers=headers) as session:
72
  async with session.get(url, timeout=0) as response:
73
  if response.status != 200:
74
  if status_msg_id:
75
  try: await client.edit_message_text(chat_id, status_msg_id, f"❌ خطا در دسترسی به لینک! کد وضعیت: {response.status}")
76
  except: pass
77
+ return None, None, status_msg_id
78
 
79
  with open(file_path, 'wb') as f:
80
  async for chunk in response.content.iter_chunked(2 * 1024 * 1024):
81
  if chunk: f.write(chunk)
82
 
83
  if status_msg_id:
84
+ try: await client.edit_message_text(chat_id, status_msg_id, "✅ دانلود در سرور تکمیل شد.\n📤 در حال آپلود به مخزن گیت‌هاب...")
85
  except: pass
86
 
87
+ return file_path, filename, status_msg_id
88
  except Exception as e:
89
  if status_msg_id:
90
  try: await client.edit_message_text(chat_id, status_msg_id, f"❌ خطای شبکه هنگام دانلود:\n{str(e)[:100]}")
91
  except: pass
92
+ return None, None, status_msg_id
93
 
94
  # ==============================================================================
95
+ # 🟢 آپلود مستقیم فایل به عنوان GitHub Release
96
  # ==============================================================================
97
+ async def upload_to_github_release(file_path, filename, chat_id, status_msg_id, client):
98
+ tag_name = f"upload-{uuid.uuid4().hex[:8]}"
99
+ release_name = f"فایل انتقالی: {filename}"
100
 
101
+ headers = {
102
+ "Authorization": f"token {GITHUB_TOKEN}",
103
+ "Accept": "application/vnd.github.v3+json"
104
+ }
105
+
106
+ try:
107
+ async with aiohttp.ClientSession(headers=headers) as session:
108
+ # ۱. ساخت یک Release جدید در گیت‌هاب
109
+ create_release_url = f"https://api.github.com/repos/{GITHUB_REPO}/releases"
110
+ release_data = {
111
+ "tag_name": tag_name,
112
+ "name": release_name,
113
+ "body": "آپلود شده توسط ربات روبیکا."
114
+ }
115
+
116
+ async with session.post(create_release_url, json=release_data) as resp:
117
+ if resp.status != 201:
118
+ raise Exception(f"خطا در ساخت Release: {await resp.text()}")
119
+ release_info = await resp.json()
120
+ release_id = release_info.get("id")
121
+ html_url = release_info.get("html_url") # لینک صفحه ریلیز
122
+
123
+ # ۲. آپلود فایل در Release (به عنوان Asset)
124
+ if status_msg_id:
125
+ try: await client.edit_message_text(chat_id, status_msg_id, "📦 Release ساخته شد. در حال انتقال فایل به گیت‌هاب (تا 2 گیگابایت)...")
126
+ except: pass
127
 
128
+ upload_url = f"https://uploads.github.com/repos/{GITHUB_REPO}/releases/{release_id}/assets?name={urllib.parse.quote(filename)}"
129
+
130
+ # باز کردن فایل برای استریم
131
+ with open(file_path, 'rb') as f:
132
+ upload_headers = headers.copy()
133
+ upload_headers["Content-Type"] = "application/octet-stream"
134
+ async with session.post(upload_url, data=f, headers=upload_headers) as upload_resp:
135
+ if upload_resp.status != 201:
136
+ raise Exception(f"خطا در آپلود فایل: {await upload_resp.text()}")
137
+ asset_info = await upload_resp.json()
138
 
139
+ # ارسال موفقیت آمیز لینک
140
+ success_text = (
141
+ f"🎉 آپلود با موفقیت انجام شد!\n\n"
142
+ f"📁 نام فایل: {filename}\n"
143
+ f"🔗 لینک صفحه فایل:\n{html_url}\n\n"
144
+ f"⚠️ نکته: برای دانلود، کافیست در مرورگر خود وارد اکانت گیت‌هاب شوید و در صفحه بالا، روی نام فایل در بخش Assets کلیک کنید."
145
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
146
 
147
+ if status_msg_id:
148
+ try: await client.edit_message_text(chat_id, status_msg_id, success_text)
149
+ except: await client.send_message(chat_id, success_text)
150
  else:
151
+ await client.send_message(chat_id, success_text)
 
 
 
 
 
 
 
 
152
 
153
+ except Exception as e:
154
+ error_txt = f"❌ خطا در عملیات گیت‌هاب:\n{str(e)[:150]}"
155
+ if status_msg_id:
156
+ try: await client.edit_message_text(chat_id, status_msg_id, error_txt)
157
+ except: await client.send_message(chat_id, error_txt)
158
+ else:
159
+ await client.send_message(chat_id, error_txt)
160
+
161
+ # ==============================================================================
162
+ # 🟢 پردازش نهایی لینک
163
+ # ==============================================================================
164
+ async def process_url_and_upload(client, chat_id, message_id, url):
165
+ file_path, filename, status_msg_id = await download_large_file(url, chat_id, message_id, client)
166
+
167
+ if file_path and os.path.exists(file_path):
168
+ try:
169
+ await upload_to_github_release(file_path, filename, chat_id, status_msg_id, client)
170
  finally:
171
+ # پاک کردن فایل از روی سرور واسط پس از ا��مام کار
172
  try: os.remove(file_path)
173
  except: pass
174
 
175
  # ==============================================================================
176
+ # 🟢 هندلر اصلی روبیکا
177
  # ==============================================================================
178
  @bot.on_update(filters.private)
179
  async def main_handler(client, update):
 
198
  if not user_text_str: return
199
 
200
  if user_text_str.lower() in ["/start", "سلام"]:
201
+ await client.send_message(chat_id, "👋 سلام! لینک مستقیم هر فایلی رو بفرست تا برات تو مخزن شخصی گیت‌هاب آپلود کنم (تا ۲ گیگابایت).")
202
  return
203
 
204
  if user_text_str.lower().startswith("http"):
 
210
 
211
  if __name__ == "__main__":
212
  threading.Thread(target=run_flask, daemon=True).start()
213
+ print("🚀 ربات انتقال به گیت‌هاب روشن شد...")
214
  bot.run()