import os import threading import time import telebot from telebot.types import InlineKeyboardMarkup, InlineKeyboardButton import fitz # PyMuPDF import subprocess import shutil import gradio as gr from concurrent.futures import ThreadPoolExecutor TOKEN = os.environ.get("BOT_TOKEN") GEMINI_API_KEY = os.environ.get("GEMINI_API_KEY") if not TOKEN: raise ValueError("لطفاً BOT_TOKEN را در بخش Secrets تنظیم کنید.") bot = telebot.TeleBot(TOKEN) user_target_langs = {} # استفاده از ThreadPool برای اینکه بات بتواند همزمان پاسخگوی چند کاربر باشد executor = ThreadPoolExecutor(max_workers=3) LANGUAGES = { "فارسی 🇮🇷": "fa", "انگلیسی 🇬🇧": "eng", "اسپانیایی 🇪🇸": "spa", "عربی 🇸🇦": "ara", "فرانسوی 🇫🇷": "fra", "روسی 🇷🇺": "rus" } def process_manga_page(image_bytes, page_num, target_lang, chat_id): input_filename = f"temp_in_{chat_id}_{page_num}.png" output_dir = f"temp_out_{chat_id}_{page_num}" with open(input_filename, "wb") as f: f.write(image_bytes) try: custom_env = os.environ.copy() command = [ "manga_translator", "--mode", "batch", "--use-cpu", "-i", input_filename, "-d", output_dir, "--target-lang", target_lang ] if GEMINI_API_KEY: custom_env["OPENAI_API_KEY"] = GEMINI_API_KEY custom_env["OPENAI_API_BASE"] = "https://generativelanguage.googleapis.com/v1beta/openai/" command.extend(["--translator", "chatgpt"]) else: command.extend(["--translator", "google"]) subprocess.run(command, env=custom_env, check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) translated_file_path = os.path.join(output_dir, input_filename) with open(translated_file_path, "rb") as f: translated_bytes = f.read() return translated_bytes except Exception as e: print(f"Error on page {page_num}: {e}") return image_bytes # در صورت خطا عکس اورجینال را حفظ کن finally: if os.path.exists(input_filename): os.remove(input_filename) if os.path.exists(output_dir): shutil.rmtree(output_dir) def translate_task(input_path, output_path, chat_id, target_lang, message_id_to_edit): try: doc = fitz.open(input_path) new_doc = fitz.open() total_pages = len(doc) for page_num in range(total_pages): # آپدیت کردن پیام وضعیت به جای ارسال پیام جدید bot.edit_message_text( chat_id=chat_id, message_id=message_id_to_edit, text=f"🔄 **در حال پردازش مانگا...**\n\n" f"📄 صفحه: {page_num + 1} از {total_pages}\n" f"⚙️ عملیات: تشخیص زبان، ترجمه مفهومی با AI و جایگذاری متن...", parse_mode="Markdown" ) page = doc[page_num] image_list = page.get_images(full=True) if image_list: xref = image_list[0][0] base_image = doc.extract_image(xref) image_bytes = base_image["image"] processed_bytes = process_manga_page(image_bytes, page_num, target_lang, chat_id) rect = page.rect new_page = new_doc.new_page(width=rect.width, height=rect.height) new_page.insert_image(rect, stream=processed_bytes) else: new_page = new_doc.new_page(width=page.rect.width, height=page.rect.height) new_page.show_pdf_page(new_page.rect, doc, page_num) # بهینه‌سازی و فشرده‌سازی PDF نهایی new_doc.save(output_path, garbage=4, deflate=True) new_doc.close() doc.close() bot.edit_message_text( chat_id=chat_id, message_id=message_id_to_edit, text="✅ **پردازش تمام شد! در حال آپلود فایل...**", parse_mode="Markdown" ) with open(output_path, 'rb') as final_doc: bot.send_document(chat_id, final_doc, caption="🎉 این هم از مانگای ترجمه‌شده شما!\nامیدوارم از خواندنش لذت ببرید.") except Exception as e: bot.send_message(chat_id, f"❌ متأسفانه در حین پردازش خطایی رخ داد: {str(e)}") finally: if os.path.exists(input_path): os.remove(input_path) if os.path.exists(output_path): os.remove(output_path) def language_keyboard(): markup = InlineKeyboardMarkup() markup.row_width = 2 buttons = [InlineKeyboardButton(text, callback_data=f"lang_{code}") for text, code in LANGUAGES.items()] markup.add(*buttons) return markup @bot.message_handler(commands=['start', 'help', 'language']) def send_welcome(message): user_target_langs[message.chat.id] = "fa" bot.reply_to( message, "به ربات فوق‌پیشرفته مترجم مانگا خوش آمدید! 📚✨\n\n" "فرقی نمی‌کند یک داستان عاشقانه لطیف باشد یا یک ایسکای تاریک و روان‌شناختی با اصطلاحات پیچیده؛ من زبان اصلی را کاملاً خودکار تشخیص داده و با هوش مصنوعی (Gemini/ChatGPT) به بهترین شکل ترجمه و تایپ می‌کنم.\n\n" "👇 ابتدا از منوی زیر زبان مقصد را انتخاب کنید و سپس فایل PDF را بفرستید:", reply_markup=language_keyboard() ) @bot.callback_query_handler(func=lambda call: call.data.startswith('lang_')) def handle_language_selection(call): lang_code = call.data.split('_')[1] user_target_langs[call.message.chat.id] = lang_code bot.answer_callback_query(call.id, "زبان با موفقیت تغییر کرد!") bot.edit_message_text( chat_id=call.message.chat.id, message_id=call.message.message_id, text=f"✅ زبان مقصد روی **{lang_code}** تنظیم شد.\n\nاکنون منتظر دریافت فایل PDF شما هستم.", parse_mode="Markdown" ) @bot.message_handler(content_types=['document']) def handle_docs(message): chat_id = message.chat.id target_lang = user_target_langs.get(chat_id, "fa") if message.document.mime_type != 'application/pdf': bot.reply_to(message, "لطفاً فقط فایل با فرمت PDF ارسال کنید. 🚫") return # بررسی حجم فایل (تلگرام محدودیت ۲۰ مگابایتی برای ربات‌ها دارد) if message.document.file_size > 20 * 1024 * 1024: bot.reply_to(message, "⚠️ حجم فایل شما بیشتر از ۲۰ مگابایت است. ربات‌های تلگرام به صورت پیش‌فرض نمی‌توانند فایل‌های بزرگتر را دانلود کنند. لطفاً فایل را به بخش‌های کوچکتر تقسیم کنید.") return status_message = bot.reply_to(message, "📥 در حال دانلود فایل از سرورهای تلگرام...") try: file_info = bot.get_file(message.document.file_id) downloaded_file = bot.download_file(file_info.file_path) input_pdf = f"input_{chat_id}_{message.message_id}.pdf" output_pdf = f"output_{chat_id}_{message.message_id}.pdf" with open(input_pdf, 'wb') as new_file: new_file.write(downloaded_file) bot.edit_message_text( chat_id=chat_id, message_id=status_message.message_id, text="✅ فایل دریافت شد. فایل به صف پردازش اضافه شد..." ) # ارسال کار به پس‌زمینه تا ربات هنگ نکند executor.submit(translate_task, input_pdf, output_pdf, chat_id, target_lang, status_message.message_id) except Exception as e: bot.edit_message_text( chat_id=chat_id, message_id=status_message.message_id, text=f"❌ خطایی در دریافت فایل رخ داد: {str(e)}" ) def run_bot(): bot.infinity_polling(timeout=60, long_polling_timeout=60) thread = threading.Thread(target=run_bot) thread.start() with gr.Blocks() as demo: gr.Markdown("# 🚀 نسخه نهایی و بهینه‌شده مترجم مانگا در حال اجراست!") gr.Markdown("این نسخه مجهز به **Threading**، **فشرده‌سازی PDF** و **سیستم ویرایش پیام زنده** است.") if GEMINI_API_KEY: gr.Markdown("✅ موتور هوش مصنوعی Gemini به عنوان مترجم مفهومی **متصل است**.") demo.launch()