| import os |
| import time |
| import re |
| import asyncio |
| import requests |
| import threading |
| from http.server import HTTPServer, BaseHTTPRequestHandler |
| from pyrogram import Client, filters, idle |
| from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton, CallbackQuery |
|
|
| |
| |
| |
| class DummyHandler(BaseHTTPRequestHandler): |
| def do_GET(self): |
| self.send_response(200) |
| self.end_headers() |
| self.wfile.write(b"Lecture Bot is alive and running on Hugging Face!") |
|
|
| def keep_alive(): |
| server = HTTPServer(('0.0.0.0', 7860), DummyHandler) |
| server.serve_forever() |
|
|
| threading.Thread(target=keep_alive, daemon=True).start() |
|
|
| |
| |
| |
| TOKEN = "8476068831:AAG9mEiMYhlIOEBYSy2P11V88NePwrJh06w" |
| API_ID = 2040 |
| API_HASH = "b18441a1ff607e10a989891a5462e627" |
|
|
| BANNER_URL = "https://img.freepik.com/free-vector/laptop-with-program-code-isometric-icon-software-development-programming-applications-dark-neon_39422-971.jpg" |
|
|
| app = Client("LectureBot", api_id=API_ID, api_hash=API_HASH, bot_token=TOKEN) |
| user_states = {} |
|
|
| print("๐ LECTURE BOT STARTED...") |
|
|
| |
| |
| |
| def upload_to_gofile(filepath): |
| print("Initiating Gofile Upload...") |
| with open(filepath, 'rb') as f: |
| files = {'file': f} |
| |
| res = requests.post('https://upload.gofile.io/uploadfile', files=files) |
| data = res.json() |
| if data.get('status') == 'ok': |
| return data['data']['downloadPage'] |
| else: |
| raise Exception(f"Gofile API Error: {data.get('status')}") |
|
|
| |
| |
| |
| @app.on_message(filters.command("start")) |
| async def start_cmd(client, message): |
| user_states[message.chat.id] = None |
| |
| keyboard = InlineKeyboardMarkup([ |
| [InlineKeyboardButton("๐ Start Extraction", callback_data="btn_extract")] |
| ]) |
| |
| await message.reply_photo( |
| photo=BANNER_URL, |
| caption=f"๐ **Welcome, {message.from_user.first_name}**\n\nI am your **Lecture Downloader**.\n\n๐น **Modes:**\nโข < 50MB: Direct Telegram File\nโข > 50MB: High-Speed Gofile Link\n\n_Click below to start:_".replace(".", "\\."), |
| reply_markup=keyboard |
| ) |
|
|
| @app.on_callback_query() |
| async def callback_handler(client, query: CallbackQuery): |
| chat_id = query.message.chat.id |
| |
| if query.data == "btn_extract": |
| user_states[chat_id] = "WAITING_URL" |
| keyboard = InlineKeyboardMarkup([[InlineKeyboardButton("โ Cancel", callback_data="btn_cancel")]]) |
| await query.message.reply_text("๐ **Send the Lecture Link now.**", reply_markup=keyboard) |
| await query.answer() |
| |
| elif query.data == "btn_cancel": |
| user_states[chat_id] = None |
| await query.message.delete() |
| await query.answer("Cancelled.") |
|
|
| @app.on_message(filters.text & ~filters.command("start")) |
| async def message_handler(client, message): |
| chat_id = message.chat.id |
| text = message.text |
|
|
| if user_states.get(chat_id) != "WAITING_URL": |
| return |
|
|
| user_states[chat_id] = None |
|
|
| if not text.startswith("http"): |
| return await message.reply_text("โ ๏ธ Invalid Link.") |
|
|
| process_msg = await message.reply_text("๐ต๏ธโโ๏ธ **Starting Process...**\n_Analyzing..._") |
|
|
| try: |
| |
| print(f"STEP 1: Analyzing URL: {text}") |
| stream_url = text |
| cookie_string = "" |
| user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64)" |
|
|
| try: |
| res = requests.get(text, headers={'User-Agent': user_agent}, timeout=15) |
| |
| |
| if 'set-cookie' in res.headers: |
| raw_cookies = res.headers['set-cookie'].split(',') |
| cookie_string = "; ".join([c.split(';')[0] for c in raw_cookies]) |
|
|
| |
| match = re.search(r"src:\s*'(/Stream/Index/[^']+)'", res.text) |
| if match: |
| stream_url = f"https://vss-v2-app.techsol360.com{match.group(1)}" |
| print("โ
Found HIDDEN Stream URL") |
| except Exception as e: |
| print(f"โ ๏ธ Scrape Error: {str(e)} (Using original link)") |
|
|
| |
| print("STEP 2: Starting FFmpeg Download...") |
| await process_msg.edit_text("โฌ๏ธ **Downloading...**\n_Please wait..._") |
| |
| timestamp = int(time.time()) |
| filepath = f"Lecture_{timestamp}.mp4" |
|
|
| cmd = f'ffmpeg -user_agent "{user_agent}" -headers "Cookie: {cookie_string}" -i "{stream_url}" -c copy -bsf:a aac_adtstoasc "{filepath}" -y' |
| |
| |
| process = await asyncio.create_subprocess_shell( |
| cmd, |
| stdout=asyncio.subprocess.PIPE, |
| stderr=asyncio.subprocess.PIPE |
| ) |
| await process.communicate() |
|
|
| if not os.path.exists(filepath): |
| raise Exception("File missing after FFmpeg download.") |
|
|
| |
| size_bytes = os.path.getsize(filepath) |
| size_mb = size_bytes / (1024 * 1024) |
| print(f"โ
Download Success. Size: {size_mb:.2f} MB") |
|
|
| |
| if size_mb < 49.0: |
| print("STEP 3: Uploading to Telegram...") |
| await process_msg.edit_text("๐ค **Uploading to Telegram...**") |
| await message.reply_document( |
| document=filepath, |
| caption=f"๐ฆ {size_mb:.2f} MB" |
| ) |
| else: |
| print("STEP 3: Uploading to Gofile...") |
| await process_msg.edit_text("๐ **Uploading to Gofile Cloud...**") |
| link = await asyncio.to_thread(upload_to_gofile, filepath) |
| print(f"โ
Gofile Success: {link}") |
| |
| await message.reply_text( |
| f"โ
**Done!**\n\n๐ [Download Link]({link})\n๐ฆ Size: {size_mb:.2f} MB", |
| disable_web_page_preview=True |
| ) |
|
|
| |
| if os.path.exists(filepath): |
| os.remove(filepath) |
|
|
| except Exception as e: |
| print(f"โ CRITICAL ERROR: {str(e)}") |
| await process_msg.edit_text(f"โ **Process Failed.**\n`{str(e)}`") |
| if 'filepath' in locals() and os.path.exists(filepath): |
| os.remove(filepath) |
|
|
| if __name__ == "__main__": |
| app.run() |