kosnanat / app.py
barnamemaker's picture
Create app.py
c9c5e42 verified
Raw
History Blame Contribute Delete
9.33 kB
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()