Hamed744 commited on
Commit
bc0e481
·
verified ·
1 Parent(s): 9eceae2

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +38 -42
app.py CHANGED
@@ -9,16 +9,16 @@ import time
9
  import threading
10
  import sys
11
 
12
- # --- NEW: Import free_translate instead of googletrans ---
13
- from free_translate import Translator
14
 
15
  # --- START: پیکربندی لاگینگ ---
16
  logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s', datefmt='%Y-%m-%d %H:%M:%S')
17
  # --- END: پیکربندی لاگینگ ---
18
 
19
- # --- START: تابع ری‌استارت خودکار ---
20
  def auto_restart_service():
21
- RESTART_INTERVAL_SECONDS = 24 * 60 * 60 # 24 hours
22
  logging.info(f"سرویس برای ری‌استارت خودکار پس از {RESTART_INTERVAL_SECONDS / 3600:.0f} ساعت زمان‌بندی شده است.")
23
  time.sleep(RESTART_INTERVAL_SECONDS)
24
  logging.info(f"زمان ری‌استارت خودکار فرا رسیده است. برنامه برای ری‌استارت خارج می‌شود...")
@@ -41,46 +41,42 @@ language_dict_persian_keys = {
41
  'انگلیسی (آفریقای جنوبی) - لیا (زن)': 'en-ZA-LeahNeural', 'انگلیسی (آفریقای جنوبی) - لوک (مرد)': 'en-ZA-LukeNeural',
42
  }
43
 
44
- # --- تابع جدید برای ترجمه با free-translate ---
45
- async def translate_text_free_translate(text_to_translate, target_language="English"):
 
 
 
 
 
46
  if not text_to_translate or not text_to_translate.strip():
47
  return "خطا: متنی برای ترجمه وارد نشده است.", None
48
 
49
- # 'English' maps to 'en'. Assuming target is always English for this app.
50
- target_lang_code = "en"
51
-
52
- logging.info(f"شروع ترجمه با Free Translate: '{text_to_translate[:50]}...' به '{target_lang_code}'")
 
 
 
 
 
 
 
53
 
54
  try:
55
- # Instantiate Translator from free_translate
56
- translator = Translator()
57
-
58
- # Run the synchronous translate method in a thread pool executor.
59
- # This is crucial because `translator.translate` is a blocking (synchronous) call,
60
- # and running it directly in an `async` function would block the entire
61
- # asyncio event loop, making the Gradio app unresponsive.
62
- loop = asyncio.get_event_loop()
63
- translated_text = await loop.run_in_executor(
64
- None, # Use the default ThreadPoolExecutor
65
- translator.translate,
66
- text_to_translate,
67
- target_language_code=target_lang_code,
68
- source_language_code='fa' # Explicitly set source to Persian (Farsi)
69
- )
70
-
71
- # The free_translate library directly returns the translated string
72
- translated_text = translated_text.strip() # Ensure it's clean
73
 
74
  if translated_text:
75
- logging.info(f"ترجمه موفق با Free Translate: '{translated_text[:50]}...'")
76
  return "ترجمه موفق", translated_text
77
  else:
78
- logging.error("ترجمه با Free Translate پاسخ خالی برگرداند.")
79
- return "خطا: ترجمه خالی برگردانده شد.", None
80
  except Exception as e:
81
- error_type = type(e).__name__
82
- logging.error(f"خطای Free Translate ({error_type}): {e}\n{traceback.format_exc()}")
83
- return f"خطا در ترجمه با Free Translate ({error_type}): مشکلی در اتصال یا ترجمه پیش آمد.", None
 
84
 
85
  # --- تابع تولید صدا (بدون تغییر) ---
86
  async def text_to_speech_edge_async(text_to_speak, tts_voice_key, rate, volume, pitch):
@@ -108,23 +104,23 @@ async def text_to_speech_edge_async(text_to_speak, tts_voice_key, rate, volume,
108
  logging.error(f"TTS: خطای نامشخص برای '{voice_id}': {error_type} - {e}")
109
  return f"خطای TTS ({error_type}): مشکلی در تولید صدا پیش آمد.", None
110
 
111
- # --- تابع اصلی Wrapper (با تغییر به تابع ترجمه free-translate) ---
112
  async def translate_and_speak_async_wrapper(persian_text, english_tts_voice_key, rate, volume, pitch):
113
  if not persian_text or not persian_text.strip():
114
- return "لطفاً متن فارسی را برای ترجمه وارد کنید.", None
115
 
116
- # --- MAIN CHANGE: Call the new free-translate function ---
117
- translation_status_msg, translated_text = await translate_text_free_translate(persian_text, target_language="English")
118
 
119
  if not translated_text:
120
- # If translated_text is None, translation_status_msg already contains the error message
121
- return (translation_status_msg, None)
122
 
123
  translated_text_output = translated_text
124
 
125
  if english_tts_voice_key not in language_dict_persian_keys:
126
  if language_dict_persian_keys:
127
- english_tts_voice_key = list(language_dict_persian_keys.keys())[0] # Fallback to first available voice
128
  else:
129
  return f"{translated_text_output}\n\n(خطای TTS: هیچ صدایی موجود نیست.)", None
130
 
@@ -135,7 +131,7 @@ async def translate_and_speak_async_wrapper(persian_text, english_tts_voice_key,
135
 
136
  return translated_text_output, audio_path
137
 
138
- # --- بخش UI و Gradio (کامل و بدون تغییر نسبت به نسخه زیبای قبلی) ---
139
  FLY_PRIMARY_COLOR_HEX = "#4F46E5"
140
  FLY_SECONDARY_COLOR_HEX = "#10B981"
141
  FLY_ACCENT_COLOR_HEX = "#D97706"
 
9
  import threading
10
  import sys
11
 
12
+ # --- کتابخانه جدید برای ترجمه با گوگل ---
13
+ from deep_translator import GoogleTranslator
14
 
15
  # --- START: پیکربندی لاگینگ ---
16
  logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s', datefmt='%Y-%m-%d %H:%M:%S')
17
  # --- END: پیکربندی لاگینگ ---
18
 
19
+ # --- START: تابع ری‌استارت خودکار (بدون تغییر) ---
20
  def auto_restart_service():
21
+ RESTART_INTERVAL_SECONDS = 24 * 60 * 60
22
  logging.info(f"سرویس برای ری‌استارت خودکار پس از {RESTART_INTERVAL_SECONDS / 3600:.0f} ساعت زمان‌بندی شده است.")
23
  time.sleep(RESTART_INTERVAL_SECONDS)
24
  logging.info(f"زمان ری‌استارت خودکار فرا رسیده است. برنامه برای ری‌استارت خارج می‌شود...")
 
41
  'انگلیسی (آفریقای جنوبی) - لیا (زن)': 'en-ZA-LeahNeural', 'انگلیسی (آفریقای جنوبی) - لوک (مرد)': 'en-ZA-LukeNeural',
42
  }
43
 
44
+
45
+ # --- START: تابع جدید ترجمه با Google Translate ---
46
+ async def translate_text_google_async(text_to_translate, target_language="en"):
47
+ """
48
+ متن را با استفاده از Google Translate (از طریق کتابخانه deep-translator) ترجمه می‌کند.
49
+ این تابع به صورت آسنکرون اجرا می‌شود تا برنامه اصلی را مسدود نکند.
50
+ """
51
  if not text_to_translate or not text_to_translate.strip():
52
  return "خطا: متنی برای ترجمه وارد نشده است.", None
53
 
54
+ def _translate():
55
+ # این تابع همزمان (synchronous) در یک ترد جداگانه اجرا می‌شود
56
+ try:
57
+ logging.info(f"شروع ترجمه متن: '{text_to_translate[:30]}...'")
58
+ # ترجمه از فارسی ('fa') به زبان مقصد (پیش‌فرض 'en')
59
+ translated = GoogleTranslator(source='fa', target=target_language).translate(text_to_translate)
60
+ logging.info("ترجمه با Google Translate موفق بود.")
61
+ return translated
62
+ except Exception as e:
63
+ logging.error(f"خطا در حین ترجمه با Google: {e}\n{traceback.format_exc()}")
64
+ return None
65
 
66
  try:
67
+ # اجرای تابع همزمان _translate در یک ترد جداگانه برای جلوگیری از بلاک شدن
68
+ translated_text = await asyncio.to_thread(_translate)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
69
 
70
  if translated_text:
 
71
  return "ترجمه موفق", translated_text
72
  else:
73
+ return "خطا: مشکلی در فرآیند ترجمه پیش آمد.", None
74
+
75
  except Exception as e:
76
+ logging.error(f"خطای غیرمنتظره در فراخوانی ترد ترجمه: {e}\n{traceback.format_exc()}")
77
+ return "خطای غیرمنتظره: مشکلی در سیستم ترجمه رخ داد.", None
78
+ # --- END: تابع جدید ترجمه ---
79
+
80
 
81
  # --- تابع تولید صدا (بدون تغییر) ---
82
  async def text_to_speech_edge_async(text_to_speak, tts_voice_key, rate, volume, pitch):
 
104
  logging.error(f"TTS: خطای نامشخص برای '{voice_id}': {error_type} - {e}")
105
  return f"خطای TTS ({error_type}): مشکلی در تولید صدا پیش آمد.", None
106
 
107
+ # --- تابع اصلی Wrapper (با تغییر جزئی برای فراخوانی تابع جدید) ---
108
  async def translate_and_speak_async_wrapper(persian_text, english_tts_voice_key, rate, volume, pitch):
109
  if not persian_text or not persian_text.strip():
110
+ return "لطفاً متن فارسی را برای ترجمه وارد کنید.", None, None
111
 
112
+ # --- تغییر کلیدی: فراخوانی تابع جدید ترجمه گوگل ---
113
+ translation_status_msg, translated_text = await translate_text_google_async(persian_text, target_language="en")
114
 
115
  if not translated_text:
116
+ # اگر translated_text خالی است، translation_status_msg حاوی پیام خطا است
117
+ return translation_status_msg, None
118
 
119
  translated_text_output = translated_text
120
 
121
  if english_tts_voice_key not in language_dict_persian_keys:
122
  if language_dict_persian_keys:
123
+ english_tts_voice_key = list(language_dict_persian_keys.keys())[0]
124
  else:
125
  return f"{translated_text_output}\n\n(خطای TTS: هیچ صدایی موجود نیست.)", None
126
 
 
131
 
132
  return translated_text_output, audio_path
133
 
134
+ # --- بخش UI و Gradio (کامل و بدون تغییر) ---
135
  FLY_PRIMARY_COLOR_HEX = "#4F46E5"
136
  FLY_SECONDARY_COLOR_HEX = "#10B981"
137
  FLY_ACCENT_COLOR_HEX = "#D97706"