Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -40,12 +40,11 @@ class AIService:
|
|
| 40 |
|
| 41 |
@staticmethod
|
| 42 |
def call_api(engine, prompt):
|
| 43 |
-
|
|
|
|
| 44 |
if "Gemini" in engine:
|
| 45 |
keys = AIService.get_all_keys("GEMINI_API_KEY")
|
| 46 |
-
# αααααΈ Model αααααααΆα (α α
ααΆαααααΆαα ααααΈαα
α
αΆαα)
|
| 47 |
models = ["gemini-3-flash", "gemini-2.5-flash", "gemini-1.5-flash"]
|
| 48 |
-
|
| 49 |
for key in keys:
|
| 50 |
for model_name in models:
|
| 51 |
try:
|
|
@@ -54,15 +53,10 @@ class AIService:
|
|
| 54 |
"contents": [{"parts": [{"text": prompt}]}],
|
| 55 |
"generationConfig": {"temperature": temp}
|
| 56 |
}, timeout=30)
|
| 57 |
-
|
| 58 |
if res.status_code == 200:
|
| 59 |
key_status_registry[key] = "ready"
|
| 60 |
return res.json()['candidates'][0]['content']['parts'][0]['text'].strip()
|
| 61 |
-
|
| 62 |
-
# ααΎ Model α αααΉααα·αααΆααα²ααααααΎ ααΆααΉαααΆα Model αααααΆαα
|
| 63 |
-
print(f"Skipping {model_name}... (Status: {res.status_code})")
|
| 64 |
-
except:
|
| 65 |
-
continue
|
| 66 |
key_status_registry[key] = "dead"
|
| 67 |
|
| 68 |
elif "Llama" in engine:
|
|
@@ -75,7 +69,6 @@ class AIService:
|
|
| 75 |
if res.status_code == 200:
|
| 76 |
key_status_registry[key] = "ready"
|
| 77 |
return res.json()['choices'][0]['message']['content'].strip()
|
| 78 |
-
key_status_registry[key] = "dead"
|
| 79 |
except: continue
|
| 80 |
|
| 81 |
else: # SEA-LION
|
|
@@ -88,38 +81,54 @@ class AIService:
|
|
| 88 |
if res.status_code == 200:
|
| 89 |
key_status_registry[key] = "ready"
|
| 90 |
return res.json()['choices'][0]['message']['content'].strip()
|
| 91 |
-
key_status_registry[key] = "dead"
|
| 92 |
except: continue
|
| 93 |
return None
|
| 94 |
|
| 95 |
def translator_hub(text, target_lang, engine):
|
| 96 |
if not text.strip(): return "", AIService.get_status_html(engine)
|
| 97 |
lang_name = re.sub(r'[^\w\s]', '', target_lang).strip()
|
| 98 |
-
|
| 99 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 100 |
result = AIService.call_api(engine, prompt)
|
|
|
|
| 101 |
if result:
|
| 102 |
return re.sub(r'```[a-zA-Z]*\n?|```', '', result).strip(), AIService.get_status_html(engine)
|
| 103 |
return "β Error: API Key α¬ Model αα·αααααΎαααΆα", AIService.get_status_html(engine)
|
| 104 |
|
| 105 |
-
custom_css = "body { background: #0f172a !important; } .btn-trans { background: #10b981 !important; color: white !important; }"
|
| 106 |
|
| 107 |
-
with gr.Blocks(title="SRT Pro (
|
| 108 |
gr.Markdown("<h1 style='text-align: center; color: #60a5fa;'>π¬ SMART TRANSLATOR PRO</h1>")
|
| 109 |
with gr.Row():
|
| 110 |
with gr.Column():
|
| 111 |
lang_opt = gr.Dropdown(["π°π Khmer", "πΊπΈ English", "π¨π³ Chinese", "πΉπ Thai"], value="π°π Khmer", label="Language")
|
| 112 |
engine_opt = gr.Radio(["π Gemini", "π¦ Llama", "π¦ SEA-LION"], value="π Gemini", label="Model Engine")
|
| 113 |
status_ui = gr.HTML(AIService.get_status_html("π Gemini"))
|
| 114 |
-
input_box = gr.Textbox(label="Original", lines=10)
|
| 115 |
-
|
|
|
|
|
|
|
| 116 |
with gr.Column():
|
| 117 |
output_box = gr.Textbox(label="Result", lines=20, interactive=False)
|
| 118 |
btn_copy = gr.Button("π Copy Result")
|
| 119 |
|
|
|
|
| 120 |
engine_opt.change(AIService.get_status_html, inputs=[engine_opt], outputs=[status_ui])
|
| 121 |
btn_trans.click(translator_hub, [input_box, lang_opt, engine_opt], [output_box, status_ui])
|
| 122 |
btn_copy.click(None, output_box, js="(v) => { navigator.clipboard.writeText(v); alert('β
α
αααααα½α
ααΆαα!'); }")
|
|
|
|
| 123 |
|
| 124 |
if __name__ == "__main__":
|
| 125 |
demo.launch(server_name="0.0.0.0", server_port=7860, css=custom_css, ssr_mode=False)
|
|
|
|
| 40 |
|
| 41 |
@staticmethod
|
| 42 |
def call_api(engine, prompt):
|
| 43 |
+
# αααααΎα Temperature ααααα·α
ααΎααααΈα±ααα
α»α
ααααααα ααΆααααΆααααααΌαααΆαααααααΈααα’ααΆααα»α
|
| 44 |
+
temp = 0.85
|
| 45 |
if "Gemini" in engine:
|
| 46 |
keys = AIService.get_all_keys("GEMINI_API_KEY")
|
|
|
|
| 47 |
models = ["gemini-3-flash", "gemini-2.5-flash", "gemini-1.5-flash"]
|
|
|
|
| 48 |
for key in keys:
|
| 49 |
for model_name in models:
|
| 50 |
try:
|
|
|
|
| 53 |
"contents": [{"parts": [{"text": prompt}]}],
|
| 54 |
"generationConfig": {"temperature": temp}
|
| 55 |
}, timeout=30)
|
|
|
|
| 56 |
if res.status_code == 200:
|
| 57 |
key_status_registry[key] = "ready"
|
| 58 |
return res.json()['candidates'][0]['content']['parts'][0]['text'].strip()
|
| 59 |
+
except: continue
|
|
|
|
|
|
|
|
|
|
|
|
|
| 60 |
key_status_registry[key] = "dead"
|
| 61 |
|
| 62 |
elif "Llama" in engine:
|
|
|
|
| 69 |
if res.status_code == 200:
|
| 70 |
key_status_registry[key] = "ready"
|
| 71 |
return res.json()['choices'][0]['message']['content'].strip()
|
|
|
|
| 72 |
except: continue
|
| 73 |
|
| 74 |
else: # SEA-LION
|
|
|
|
| 81 |
if res.status_code == 200:
|
| 82 |
key_status_registry[key] = "ready"
|
| 83 |
return res.json()['choices'][0]['message']['content'].strip()
|
|
|
|
| 84 |
except: continue
|
| 85 |
return None
|
| 86 |
|
| 87 |
def translator_hub(text, target_lang, engine):
|
| 88 |
if not text.strip(): return "", AIService.get_status_html(engine)
|
| 89 |
lang_name = re.sub(r'[^\w\s]', '', target_lang).strip()
|
| 90 |
+
|
| 91 |
+
# ααααα½α Instruction α±αααααααΈααα·αααααααα
ααααΆα (Slang, Emotion, Pronouns, Swear words)
|
| 92 |
+
instruction = f"""Translate the content into {lang_name} naturally.
|
| 93 |
+
STRICT RULES:
|
| 94 |
+
1. OUTPUT ONLY the translated text. NO explanations or notes.
|
| 95 |
+
2. If the input is SRT format, strictly preserve the timing and numbering.
|
| 96 |
+
3. CONTEXT & EMOTION: Understand the scene. Use natural slang and idioms (Modern/Classic).
|
| 97 |
+
4. PRONOUNS:
|
| 98 |
+
- Family: αα, ααα’αΌα, αα, α’αΌα, αααΆαα/ααα, αααΆ/αα»α, ααΌα, ααΌ, ααΈα...
|
| 99 |
+
- Couples/Home: ααααΈ, ααααααα, αα, α’αΌα...
|
| 100 |
+
- Conflict/Enemies: ααΎα, α’α, α’αα αα, α―α... (Allow swear words and insults if in context).
|
| 101 |
+
5. VARIATION: If asked again, try to find better synonyms or more natural flow."""
|
| 102 |
+
|
| 103 |
+
prompt = f"{instruction}\n\nCONTENT TO TRANSLATE:\n{text}"
|
| 104 |
result = AIService.call_api(engine, prompt)
|
| 105 |
+
|
| 106 |
if result:
|
| 107 |
return re.sub(r'```[a-zA-Z]*\n?|```', '', result).strip(), AIService.get_status_html(engine)
|
| 108 |
return "β Error: API Key α¬ Model αα·αααααΎαααΆα", AIService.get_status_html(engine)
|
| 109 |
|
| 110 |
+
custom_css = "body { background: #0f172a !important; } .btn-trans { background: #10b981 !important; color: white !important; } .btn-clear { background: #475569 !important; color: white !important; }"
|
| 111 |
|
| 112 |
+
with gr.Blocks(title="SRT Pro (Triple Model)") as demo:
|
| 113 |
gr.Markdown("<h1 style='text-align: center; color: #60a5fa;'>π¬ SMART TRANSLATOR PRO</h1>")
|
| 114 |
with gr.Row():
|
| 115 |
with gr.Column():
|
| 116 |
lang_opt = gr.Dropdown(["π°π Khmer", "πΊπΈ English", "π¨π³ Chinese", "πΉπ Thai"], value="π°π Khmer", label="Language")
|
| 117 |
engine_opt = gr.Radio(["π Gemini", "π¦ Llama", "π¦ SEA-LION"], value="π Gemini", label="Model Engine")
|
| 118 |
status_ui = gr.HTML(AIService.get_status_html("π Gemini"))
|
| 119 |
+
input_box = gr.Textbox(label="Original Content", lines=10, placeholder="αααα
αΌαα’ααααα α¬ SRT αα
ααΈααα...")
|
| 120 |
+
with gr.Row():
|
| 121 |
+
btn_clear = gr.Button("ποΈ Clear", elem_classes="btn-clear")
|
| 122 |
+
btn_trans = gr.Button("β‘ Translate", variant="primary", elem_classes="btn-trans")
|
| 123 |
with gr.Column():
|
| 124 |
output_box = gr.Textbox(label="Result", lines=20, interactive=False)
|
| 125 |
btn_copy = gr.Button("π Copy Result")
|
| 126 |
|
| 127 |
+
# Events
|
| 128 |
engine_opt.change(AIService.get_status_html, inputs=[engine_opt], outputs=[status_ui])
|
| 129 |
btn_trans.click(translator_hub, [input_box, lang_opt, engine_opt], [output_box, status_ui])
|
| 130 |
btn_copy.click(None, output_box, js="(v) => { navigator.clipboard.writeText(v); alert('β
α
αααααα½α
ααΆαα!'); }")
|
| 131 |
+
btn_clear.click(lambda: ("", ""), None, [input_box, output_box])
|
| 132 |
|
| 133 |
if __name__ == "__main__":
|
| 134 |
demo.launch(server_name="0.0.0.0", server_port=7860, css=custom_css, ssr_mode=False)
|