hangokvillage commited on
Commit
713d093
·
verified ·
1 Parent(s): df89f6d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +112 -121
app.py CHANGED
@@ -1,122 +1,113 @@
1
- import os
2
- import re
3
- import gradio as gr
4
- from deep_translator import GoogleTranslator
5
- from sentence_transformers import SentenceTransformer, util
6
-
7
- embed_model = SentenceTransformer("sentence-transformers/paraphrase-MiniLM-L6-v2")
8
-
9
- def clean(s):
10
- if not s:
11
- return ""
12
- return re.sub(r"\s+", " ", s).strip()
13
-
14
- def ko2en(text):
15
- return GoogleTranslator(source="ko", target="en").translate(text)
16
-
17
- def en2ko(text):
18
- return GoogleTranslator(source="en", target="ko").translate(text)
19
-
20
- def sim_ko(a, b):
21
- if not a or not b:
22
- return 0.0
23
- v = embed_model.encode([a, b], convert_to_tensor=True)
24
- return float(util.cos_sim(v[0], v[1]).item()) * 100.0
25
-
26
- def tone_en(text, tone):
27
- t = clean(text)
28
- if tone == "����":
29
- t = re.sub(r"\b(very|really|so|truly)\b\s*", "", t, flags=re.I)
30
- t = re.sub(r"\b(Thank you so much|Thanks a lot)\b", "Thank you", t, flags=re.I)
31
- elif tone == "����":
32
- if re.search(r"\b(Thank you|Thanks)\b", t, re.I) and not re.search(r"\bappreciat(e|ion)\b", t, re.I):
33
- t += " I sincerely appreciate your support."
34
- if not re.search(r"\bplease\b", t, re.I) and t:
35
- t = "Please " + t[0].lower() + t[1:]
36
- elif tone == "����Ͻ���":
37
- if not t.endswith("."):
38
- t += "."
39
- if not re.search(r"\b(Please let me know|I look forward to)\b", t, re.I):
40
- t += " Please let me know if you need any further information."
41
- return t
42
-
43
- def tone_ko(text, tone):
44
- t = clean(text)
45
- if tone == "����":
46
- t = re.sub(r"(����|��������|�ʹ�|�ſ�)\s*", "", t)
47
- t = re.sub(r"(��Ź�帳�ϴ�|����帳�ϴ�)", "�����մϴ�", t)
48
- elif tone == "����":
49
- if "����" in t and "����" not in t:
50
- t = t.replace("�����մϴ�", "�������� �����մϴ�")
51
- if not re.search(r"(��Ź�帳�ϴ�|�����ֽø� �����ϰڽ��ϴ�)", t):
52
- t += " �����ֽø� �����ϰڽ��ϴ�."
53
- elif tone == "����Ͻ���":
54
- t = re.sub(r"(��������|������|�����ؿ�)", "�����մϴ�", t)
55
- if not (t.endswith("���ϴ�.") or t.endswith("�帳�ϴ�.") or t.endswith("��.")):
56
- t += " �����մϴ�."
57
- return t
58
-
59
- def td_translate(ko_text, tone, target=98.2):
60
- ko_text = clean(ko_text)
61
- if not ko_text:
62
- return "������ �Է��ϼ���.", "", "", "", "", 0.0, ""
63
- try:
64
- en = ko2en(ko_text)
65
- back = en2ko(en)
66
- except Exception as e:
67
- return f"[���� ����] {e}", "", "", "", "", 0.0, ""
68
-
69
- sim = sim_ko(ko_text, back)
70
- en_tuned = tone_en(en, tone)
71
- ko_tuned = tone_ko(back, tone)
72
- ok = sim >= float(target)
73
- flag = "���� ���� ✅" if ok else "���� �̴� ⚠️ (ǥ���� ��üȭ�� ������)"
74
- final = f"{en_tuned}\n\n{flag} (���絵: {sim:.2f}%, ����: {float(target):.1f}%)"
75
- guide = f"��: {tone} | KO��EN��KO ����� ��� �ǹ� ������ ����"
76
- return "", en, back, en_tuned, ko_tuned, sim, final + "\n" + guide
77
-
78
- with gr.Blocks(title="Tha Deeply Translator — �溰 ������") as app:
79
- gr.Markdown(
80
- "## Tha Deeply — �� ����ġ / ����� / ���絵 �м���\n"
81
- "- �⺻��: ����Ͻ���, ���絵 98.2%, ���� ���� ������\n"
82
- "- ���� �ٲ㰡�� �������� ��� ������ ���� ������."
83
- )
84
-
85
- default_tone = "����Ͻ���"
86
- default_threshold = 98.2
87
- default_text = "���� �������ϴ�. ���� �������� ȸ�� ��Ź�帳�ϴ�."
88
-
89
- with gr.Row():
90
- tone = gr.Radio(["����", "����", "����Ͻ���"], value=default_tone, label="�� ����")
91
- thres = gr.Slider(0, 100, value=default_threshold, step=0.1, label="���絵 ����(%)")
92
- ko_in = gr.Textbox(lines=4, label="����(�ѱ���)", value=default_text, placeholder="�ѱ��� ������ �Է��ϼ���")
93
- run = gr.Button("����")
94
-
95
- en_out = gr.Textbox(lines=4, label="�� ���� ����(EN)")
96
- ko_back = gr.Textbox(lines=4, label="�� �����(KO)")
97
- en_tone = gr.Textbox(lines=4, label="�� �� ���� ����(EN)")
98
- ko_tone = gr.Textbox(lines=4, label="�� �� ���� �ѱ�(KO)")
99
- sim = gr.Number(label="�ǹ� ���絵(%)", precision=2)
100
- final = gr.Textbox(lines=6, label="�� ������ ���� ���� + ����")
101
-
102
- examples = gr.Examples(
103
- examples=[
104
- ["���� �ּż� �����մϴ�. ���� �� �����ϱ��� ȸ�� ��Ź�帳�ϴ�.", "����Ͻ���", 98.2],
105
- ["�˼��մϴ�. ���� ������ �ʿ��մϴ�. ������ �ð��� �˷��ּ���.", "����", 97.0],
106
- ["���� �����ؿ�! �̹� ������Ʈ �Բ��� �� �־� ��޴ϴ�.", "����", 98.5],
107
- ],
108
- inputs=[ko_in, tone, thres],
109
- label="���� �ҷ�����"
110
- )
111
-
112
- def _run(ko_text, t, thr):
113
- msg, en, back, en_tuned, ko_tuned, simv, fin = td_translate(ko_text, t, thr)
114
- if msg:
115
- return "", "", "", "", 0.0, msg
116
- return en, back, en_tuned, ko_tuned, simv, fin
117
-
118
- run.click(_run, [ko_in, tone, thres], [en_out, ko_back, en_tone, ko_tone, sim, final])
119
-
120
- if __name__ == "__main__":
121
- port = int(os.getenv("PORT", "7860"))
122
  app.launch(server_name="0.0.0.0", server_port=port)
 
1
+ # -*- coding: utf-8 -*-
2
+
3
+ import os
4
+ import re
5
+ import gradio as gr
6
+ from deep_translator import GoogleTranslator
7
+ from sentence_transformers import SentenceTransformer, util
8
+
9
+ # model load (first run may take 1-2 minutes)
10
+ embed_model = SentenceTransformer("sentence-transformers/paraphrase-MiniLM-L6-v2")
11
+
12
+ def clean(s: str) -> str:
13
+ if not s:
14
+ return ""
15
+ return re.sub(r"\s+", " ", s).strip()
16
+
17
+ def ko2en(text: str) -> str:
18
+ return GoogleTranslator(source="ko", target="en").translate(text)
19
+
20
+ def en2ko(text: str) -> str:
21
+ return GoogleTranslator(source="en", target="ko").translate(text)
22
+
23
+ def sim_ko(a: str, b: str) -> float:
24
+ if not a or not b:
25
+ return 0.0
26
+ v = embed_model.encode([a, b], convert_to_tensor=True)
27
+ return float(util.cos_sim(v[0], v[1]).item()) * 100.0
28
+
29
+ # tone rules (EN / KO)
30
+ def tone_en(text: str, tone: str) -> str:
31
+ t = clean(text)
32
+ if tone == "쿨톤":
33
+ t = re.sub(r"\b(very|really|so|truly)\b\s*", "", t, flags=re.I)
34
+ t = re.sub(r"\b(Thank you so much|Thanks a lot)\b", "Thank you", t, flags=re.I)
35
+ elif tone == "웜톤":
36
+ if re.search(r"\b(Thank you|Thanks)\b", t, re.I) and not re.search(r"\bappreciat(e|ion)\b", t, re.I):
37
+ t += " I sincerely appreciate your support."
38
+ if not re.search(r"\bplease\b", t, re.I) and t:
39
+ t = "Please " + t[0].lower() + t[1:]
40
+ elif tone == "비즈니스톤":
41
+ if not t.endswith("."):
42
+ t += "."
43
+ if not re.search(r"\b(Please let me know|I look forward to)\b", t, re.I):
44
+ t += " Please let me know if you need any further information."
45
+ return t
46
+
47
+ def tone_ko(text: str, tone: str) -> str:
48
+ t = clean(text)
49
+ if tone == "쿨톤":
50
+ t = re.sub(r"(정말|진심으로|너무|매우)\s*", "", t)
51
+ t = re.sub(r"(부탁드립니다|감사드립니다)", "감사합니다", t)
52
+ elif tone == "웜톤":
53
+ if "감사" in t and "진심" not in t:
54
+ t = t.replace("감사합니다", "진심으로 감사합니다")
55
+ if not re.search(r"(부탁드립니다|도와주시면 감사하겠습니다)", t):
56
+ t += " 도와주시면 감사하겠습니다."
57
+ elif tone == "비즈니스톤":
58
+ t = re.sub(r"(고마워요|고마워|감사해요)", "감사합니다", t)
59
+ if not (t.endswith("습니다.") or t.endswith("드립니다.") or t.endswith("요.")):
60
+ t += " 감사합니다."
61
+ return t
62
+
63
+ def td_translate(ko_text: str, tone: str, target: float = 98.2):
64
+ ko_text = clean(ko_text)
65
+ if not ko_text:
66
+ return "원문을 입력하세요.", "", "", "", "", 0.0, ""
67
+ try:
68
+ en = ko2en(ko_text)
69
+ back = en2ko(en)
70
+ except Exception as e:
71
+ return f"[번역 오류] {e}", "", "", "", "", 0.0, ""
72
+
73
+ sim = sim_ko(ko_text, back)
74
+ en_tuned = tone_en(en, tone)
75
+ ko_tuned = tone_ko(back, tone)
76
+ ok = sim >= float(target)
77
+ flag = "기준 충족" if ok else "기준 미달 (표현을 구체화해 보세요)"
78
+ final = f"{en_tuned}\n\n{flag} (유사도: {sim:.2f}%, 기준: {float(target):.1f}%)"
79
+ guide = f"톤: {tone} | KO->EN->KO 재번역 기반 의미 검증"
80
+ return "", en, back, en_tuned, ko_tuned, sim, final + "\n" + guide
81
+
82
+ with gr.Blocks(title="Tha Deeply Translator") as app:
83
+ gr.Markdown("Tha Deeply — 톤 스위치 / 재번역 / 유사도 분석기")
84
+
85
+ default_tone = "비즈니스톤"
86
+ default_threshold = 98.2
87
+ default_text = "정말 고맙습니다. 내일 오전까지 회신 부탁드립니다."
88
+
89
+ with gr.Row():
90
+ tone = gr.Radio(["쿨톤", "웜톤", "비즈니스톤"], value=default_tone, label=" 선택")
91
+ thres = gr.Slider(0, 100, value=default_threshold, step=0.1, label="유사도 기준(%)")
92
+ ko_in = gr.Textbox(lines=4, label="원문(한국어)", value=default_text, placeholder="한국어 문장을 입력하세요")
93
+ run = gr.Button("실행")
94
+
95
+ en_out = gr.Textbox(lines=4, label="1) 영문 번역(EN)")
96
+ ko_back = gr.Textbox(lines=4, label="2) 재번역(KO)")
97
+ en_tone = gr.Textbox(lines=4, label="3) 보정 영문(EN)")
98
+ ko_tone = gr.Textbox(lines=4, label="4) 보정 한글(KO)")
99
+ sim = gr.Number(label="의미 유사도(%)", precision=2)
100
+ final = gr.Textbox(lines=6, label="완전한 영어 제안 + 상태")
101
+
102
+ def _run(ko_text, t, thr):
103
+ msg, en, back, en_tuned, ko_tuned, simv, fin = td_translate(ko_text, t, thr)
104
+ if msg:
105
+ return "", "", "", "", 0.0, msg
106
+ return en, back, en_tuned, ko_tuned, simv, fin
107
+
108
+ run.click(_run, [ko_in, tone, thres],
109
+ [en_out, ko_back, en_tone, ko_tone, sim, final])
110
+
111
+ if __name__ == "__main__":
112
+ port = int(os.getenv("PORT", "7860"))
 
 
 
 
 
 
 
 
 
113
  app.launch(server_name="0.0.0.0", server_port=port)