File size: 8,269 Bytes
89438fd 7ab346d 21f4d9e 4ad87f6 31cf358 89438fd 304b533 4ad87f6 d051734 7ab346d 89438fd 4ad87f6 d051734 4ad87f6 99e5c70 4ad87f6 89438fd 21f4d9e 89438fd 21f4d9e 4ad87f6 21f4d9e 89438fd 21f4d9e 4ad87f6 21f4d9e f60f5f7 89438fd 4ad87f6 89438fd 4ad87f6 89438fd 4ad87f6 89438fd 4ad87f6 89438fd 4ad87f6 89438fd 4ad87f6 89438fd 4ad87f6 89438fd 4ad87f6 89438fd 4ad87f6 89438fd 4ad87f6 89438fd 4ad87f6 89438fd 4ad87f6 89438fd 4ad87f6 89438fd 4ad87f6 89438fd 4ad87f6 89438fd 4ad87f6 89438fd 4ad87f6 89438fd 4ad87f6 89438fd 4ad87f6 89438fd 4ad87f6 89438fd 7554914 f60f5f7 d595b06 21f4d9e 89438fd 7554914 89438fd 21f4d9e 7554914 21f4d9e 7554914 21f4d9e d051734 dea829b 4ad87f6 c5ca3e4 dea829b 89438fd d051734 73e87db 89438fd d051734 89438fd 21f4d9e d051734 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 | import os, time, threading, zipfile, io, re, telebot, requests
from flask import Flask, render_template_string
from playwright.sync_api import sync_playwright
from PIL import Image
import img2pdf
from telebot import types
# --- الإعدادات ---
BOT_TOKEN = os.getenv("TELEGRAM_BOT_TOKEN")
ADMIN_HANDLE = "@svipfast"
bot = telebot.TeleBot(BOT_TOKEN, threaded=False)
app = Flask(__name__)
# مخزن مؤقت لحالات المستخدمين
user_states = {}
@app.route('/')
def home(): return "<h1>Manga Engine Professional is Running</h1>"
# --- محرك السحب (Playwright) ---
def fetch_images_engine(url):
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
context = browser.new_context(user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36")
page = context.new_page()
try:
page.goto(url, wait_until="networkidle", timeout=60000)
# التمرير لضمان تحميل الصور بالكامل
for _ in range(5):
page.mouse.wheel(0, 1200)
time.sleep(0.8)
images = page.query_selector_all("img")
img_list = []
for img in images:
src = img.get_attribute("src") or img.get_attribute("data-src") or img.get_attribute("data-lazy-src")
if src and any(ext in src.lower() for ext in ['.jpg', '.jpeg', '.png', '.webp', '.avif']):
if "logo" in src.lower() or "banner" in src.lower(): continue
try:
res = page.request.get(src)
if res.status == 200 and len(res.body()) > 25000:
img_list.append(Image.open(io.BytesIO(res.body())).convert('RGB'))
except: continue
browser.close()
return img_list
except:
browser.close()
return []
# --- لوحة التحكم والترحيب ---
@bot.message_handler(commands=['start'])
def welcome(message):
user_states[message.chat.id] = {} # تصفير حالة المستخدم
markup = types.InlineKeyboardMarkup(row_width=1)
btn_start = types.InlineKeyboardButton("📥 إرسال رابط جديد", callback_data="new_order")
btn_help = types.InlineKeyboardButton("💡 كيف أحصل على الرابط؟", callback_data="help_link")
btn_admin = types.InlineKeyboardButton("👨💻 المطور", url=f"https://t.me/{ADMIN_HANDLE.replace('@','')}")
markup.add(btn_start, btn_help, btn_admin)
bot.send_message(message.chat.id,
f"<b>مرحباً بك في بوت سحب المانجا الإحترافي 🚀</b>\n\n"
f"النظام يعمل بمحرك محاكاة لتجاوز الحمايات.\n"
f"المطور المسؤول: {ADMIN_HANDLE}",
parse_mode="HTML", reply_markup=markup)
# --- معالجة الضغط على الأزرار ---
@bot.callback_query_handler(func=lambda call: True)
def handle_query(call):
chat_id = call.message.chat.id
if call.data == "new_order":
msg = bot.send_message(chat_id, "<b>الآن، أرسل رابط المانجا (رابط أي فصل):</b>", parse_mode="HTML")
bot.register_next_step_handler(msg, process_url_step)
elif call.data == "help_link":
help_txt = (
"<b>طريقة إرسال الرابط الصحيحة:</b>\n\n"
"انسخ رابط الفصل من الموقع مباشرة، مثال:\n"
"<code>https://olympustaff.com/series/manga-name/1</code>"
)
bot.send_message(chat_id, help_txt, parse_mode="HTML")
# أزرار خيارات التحميل
elif call.data.startswith("mode_"):
mode = call.data.split("_")[1]
user_states[chat_id]['mode'] = mode
if mode == "single":
msg = bot.send_message(chat_id, "🔢 أرسل <b>رقم الفصل</b> فقط:")
elif mode == "range":
msg = bot.send_message(chat_id, "🔢 أرسل <b>المدى</b> (مثال: 1-10):")
elif mode == "auto10":
msg = bot.send_message(chat_id, "🔢 أرسل <b>رقم الفصل</b> الذي سنبدأ التحميل منه:")
bot.register_next_step_handler(msg, final_execution_step)
bot.answer_callback_query(call.id)
# --- الخطوة الثانية: استلام الرابط ---
def process_url_step(message):
url = message.text.strip()
if not url.startswith("http"):
bot.send_message(message.chat.id, "❌ الرابط غير صحيح، أرسل رابط يبدأ بـ http")
return
user_states[message.chat.id] = {'url': url}
# إظهار خيارات التحميل كأزرار
markup = types.InlineKeyboardMarkup(row_width=2)
markup.add(
types.InlineKeyboardButton("🎯 فصل واحد", callback_data="mode_single"),
types.InlineKeyboardButton("📦 حزمة فصول", callback_data="mode_range"),
types.InlineKeyboardButton("⏩ تحميل 10 فصول", callback_data="mode_auto10")
)
bot.send_message(message.chat.id, "<b>ممتاز! اختر الآن طريقة التحميل:</b>", parse_mode="HTML", reply_markup=markup)
# --- الخطوة الأخيرة: التنفيذ ---
def final_execution_step(message):
chat_id = message.chat.id
state = user_states.get(chat_id)
if not state or 'url' not in state:
bot.send_message(chat_id, "⚠️ حدث خطأ، يرجى البدء من جديد عبر /start")
return
text = message.text.strip()
mode = state['mode']
url = state['url']
try:
if mode == "single":
start, end = int(text), int(text)
elif mode == "range":
start, end = map(int, text.split('-'))
elif mode == "auto10":
start = int(text)
end = start + 9
status_msg = bot.send_message(chat_id, f"<b>🔄 جاري تشغيل المحرك الذكي...</b>\n📦 سحب الفصول: {start} ⬅️ {end}", parse_mode="HTML")
# تشغيل السحب
zip_path = run_manga_engine(url, start, end)
if zip_path:
with open(zip_path, 'rb') as f:
caption = (
f"<b>✅ اكتملت عملية السحب بنجاح</b>\n\n"
f"📂 <b>النطاق:</b> {start} إلى {end}\n"
f"👨💻 <b>بواسطة:</b> {ADMIN_HANDLE}"
)
bot.send_document(chat_id, f, caption=caption, parse_mode="HTML")
os.remove(zip_path)
bot.delete_message(chat_id, status_msg.message_id)
else:
bot.edit_message_text(f"❌ لم ينجح المحرك في سحب الصور.\nتواصل مع الإدارة: {ADMIN_HANDLE}", chat_id, status_msg.message_id)
except Exception as e:
bot.send_message(chat_id, "⚠️ خطأ في إدخال الأرقام. يرجى التأكد من كتابتها بشكل صحيح (مثال: 1-5).")
# --- منطق بناء الروابط وضغط الملفات ---
def run_manga_engine(sample_url, start, end):
base_part = re.sub(r'/(?:chapter-)?\d+$', '', sample_url.strip().rstrip('/'))
is_azora = "azoramoon" in sample_url
pdf_files = []
for i in range(start, end + 1):
target_url = f"{base_part}/chapter-{i}" if is_azora else f"{base_part}/{i}"
imgs = fetch_images_engine(target_url)
if imgs:
fname = f"Chapter_{i}.pdf"
imgs[0].save(fname, save_all=True, append_images=imgs[1:], format='PDF')
pdf_files.append(fname)
if not pdf_files: return None
zip_name = f"Manga_Pack_{int(time.time())}.zip"
with zipfile.ZipFile(zip_name, 'w') as zipf:
for f in pdf_files:
zipf.write(f)
os.remove(f)
return zip_name
# --- التشغيل ---
if __name__ == "__main__":
# تنصيب متصفح Playwright
os.system("playwright install chromium")
threading.Thread(target=lambda: bot.infinity_polling(), daemon=True).start()
app.run(host="0.0.0.0", port=7860) |