Spaces:
Running
Running
add japanese
Browse files- pages/upload.py +2 -2
- powerpoint/__pycache__/xml_handling.cpython-310.pyc +0 -0
- powerpoint/xml_handling.py +0 -68
- translate/__pycache__/translator.cpython-310.pyc +0 -0
- translate/translator.py +1 -1
- utils/__pycache__/utils.cpython-310.pyc +0 -0
- utils/utils.py +3 -3
- word/__pycache__/word_helper.cpython-310.pyc +0 -0
- word/word_helper.py +1 -1
pages/upload.py
CHANGED
@@ -75,11 +75,11 @@ with st.container():
|
|
75 |
|
76 |
with col1:
|
77 |
st.markdown('<p style="font-size:16px; font-weight:bold; margin-bottom:4px;">🌐 Ngôn ngữ của tài liệu</p>', unsafe_allow_html=True)
|
78 |
-
source_lang = st.selectbox(" ", ["chinese", "english", "vietnamese"], key="source_lang")
|
79 |
|
80 |
with col2:
|
81 |
st.markdown('<p style="font-size:16px; font-weight:bold; margin-bottom:4px;">🌐 Ngôn ngữ muốn dịch sang</p>', unsafe_allow_html=True)
|
82 |
-
target_lang = st.selectbox(" ", ["chinese", "english", "vietnamese"], key="target_lang")
|
83 |
|
84 |
# Xử lý file trực tiếp
|
85 |
def process_file(file, file_type):
|
|
|
75 |
|
76 |
with col1:
|
77 |
st.markdown('<p style="font-size:16px; font-weight:bold; margin-bottom:4px;">🌐 Ngôn ngữ của tài liệu</p>', unsafe_allow_html=True)
|
78 |
+
source_lang = st.selectbox(" ", ["Để máy tự xác định", "chinese", "english", "vietnamese", "japanese"], key="source_lang")
|
79 |
|
80 |
with col2:
|
81 |
st.markdown('<p style="font-size:16px; font-weight:bold; margin-bottom:4px;">🌐 Ngôn ngữ muốn dịch sang</p>', unsafe_allow_html=True)
|
82 |
+
target_lang = st.selectbox(" ", ["chinese", "english", "vietnamese", "japanese"], key="target_lang")
|
83 |
|
84 |
# Xử lý file trực tiếp
|
85 |
def process_file(file, file_type):
|
powerpoint/__pycache__/xml_handling.cpython-310.pyc
CHANGED
Binary files a/powerpoint/__pycache__/xml_handling.cpython-310.pyc and b/powerpoint/__pycache__/xml_handling.cpython-310.pyc differ
|
|
powerpoint/xml_handling.py
CHANGED
@@ -19,16 +19,6 @@ for prefix, uri in ns.items():
|
|
19 |
|
20 |
|
21 |
def _get_paragraph_details(p_element):
|
22 |
-
"""
|
23 |
-
Helper function to extract merged text and the first rPr associated with text
|
24 |
-
from a given <a:p> element. Handles text within <a:r> and <a:fld>.
|
25 |
-
|
26 |
-
Args:
|
27 |
-
p_element (ET.Element): The <a:p> element.
|
28 |
-
|
29 |
-
Returns:
|
30 |
-
tuple | None: (merged_text, first_rPr_with_text) if text exists, else None.
|
31 |
-
"""
|
32 |
paragraph_text_parts = []
|
33 |
first_rPr_with_text = None
|
34 |
found_first_rpr = False # Cờ để chỉ tìm rPr đầu tiên một lần
|
@@ -75,23 +65,6 @@ def _get_paragraph_details(p_element):
|
|
75 |
|
76 |
# --- Hàm trích xuất chính (Trả về list các tuple chi tiết paragraph) ---
|
77 |
def extract_text_from_slide(slide_file):
|
78 |
-
"""
|
79 |
-
Trích xuất chi tiết từ từng thẻ <a:p> trong file slide XML.
|
80 |
-
|
81 |
-
Args:
|
82 |
-
slide_file (str): Đường dẫn đến file slide XML.
|
83 |
-
|
84 |
-
Returns:
|
85 |
-
list: Một list các tuple, mỗi tuple có dạng:
|
86 |
-
(paragraph_text, first_rPr_in_paragraph)
|
87 |
-
- paragraph_text (str): Toàn bộ text trong các <a:t> con cháu
|
88 |
-
của <a:p>, đã được ghép và strip().
|
89 |
-
- first_rPr_in_paragraph (ET.Element | None): Phần tử <a:rPr> của
|
90 |
-
<a:r> đầu tiên có chứa text trong <a:p> đó. Là None nếu run
|
91 |
-
đầu tiên có text không có thẻ <a:rPr>, hoặc nếu không có text
|
92 |
-
nào trong paragraph.
|
93 |
-
Trả về list rỗng nếu có lỗi hoặc không tìm thấy paragraph nào có text.
|
94 |
-
"""
|
95 |
# print(f"--- Bắt đầu trích xuất chi tiết từng <a:p> từ file: {slide_file} ---")
|
96 |
extracted_data = [] # Danh sách kết quả cuối cùng
|
97 |
|
@@ -148,20 +121,6 @@ def extract_text_from_slide(slide_file):
|
|
148 |
|
149 |
|
150 |
def replace_text_in_slide(xml_file_path, list_of_translated_paragraph_data):
|
151 |
-
"""
|
152 |
-
Thay thế văn bản trong file XML slide, ghi đè file gốc.
|
153 |
-
*** Logic mới: ***
|
154 |
-
- Giảm cỡ chữ đi 0.85 lần.
|
155 |
-
- Nếu text > 20 chars: Loại bỏ định dạng bold (giữ nguyên case).
|
156 |
-
- Nếu text <= 20 chars: Giữ nguyên định dạng bold gốc (và case).
|
157 |
-
|
158 |
-
Args:
|
159 |
-
xml_file_path (str): Đường dẫn file XML slide gốc (sẽ bị ghi đè).
|
160 |
-
list_of_translated_paragraph_data (list): List các tuple
|
161 |
-
(translated_paragraph_text, original_first_rPr_in_paragraph).
|
162 |
-
Returns:
|
163 |
-
bool: True nếu thành công (ghi file), False nếu có lỗi.
|
164 |
-
"""
|
165 |
# print(f"\n--- Bắt đầu thay thế PARAGRAPH (ghi đè, logic length/bold) trong file: {os.path.basename(xml_file_path)} ---")
|
166 |
processed_p_count = 0
|
167 |
|
@@ -331,19 +290,6 @@ def get_smartart_data_file(rels_file, base_path):
|
|
331 |
|
332 |
|
333 |
def extract_text_from_smartart(xml_file_path):
|
334 |
-
"""
|
335 |
-
Trích xuất văn bản tổng hợp từ mỗi đoạn <a:p> có chứa text
|
336 |
-
trong file XML SmartArt.
|
337 |
-
|
338 |
-
Args:
|
339 |
-
xml_file_path (str): Đường dẫn đến file XML SmartArt.
|
340 |
-
|
341 |
-
Returns:
|
342 |
-
list: Một list các tuple (paragraph_text, first_rPr_in_paragraph).
|
343 |
-
paragraph_text là toàn bộ text trong các <a:t> con cháu của <a:p>.
|
344 |
-
first_rPr_in_paragraph là element <a:rPr> của <a:r> đầu tiên
|
345 |
-
có chứa text trong <a:p> đó. Trả về list rỗng nếu lỗi.
|
346 |
-
"""
|
347 |
paragraph_data = []
|
348 |
try:
|
349 |
tree = ET.parse(xml_file_path)
|
@@ -390,20 +336,6 @@ def extract_text_from_smartart(xml_file_path):
|
|
390 |
|
391 |
# --- Hàm thay thế theo từng đoạn <a:p> ---
|
392 |
def replace_text_in_smartart(xml_file_path, list_of_translated_paragraph_data, output_xml_file_path):
|
393 |
-
"""
|
394 |
-
Thay thế văn bản trong file XML SmartArt dựa trên dữ liệu đoạn <a:p> đã dịch.
|
395 |
-
Mỗi mục dịch sẽ thay thế nội dung text của một <a:p> tương ứng,
|
396 |
-
đặt toàn bộ text dịch vào một run <a:r> duy nhất với định dạng rPr được cung cấp.
|
397 |
-
|
398 |
-
Args:
|
399 |
-
xml_file_path (str): Đường dẫn file XML gốc.
|
400 |
-
list_of_translated_paragraph_data (list): List các tuple
|
401 |
-
(translated_paragraph_text, original_first_rPr_in_paragraph).
|
402 |
-
output_xml_file_path (str): Đường dẫn file XML đầu ra.
|
403 |
-
|
404 |
-
Returns:
|
405 |
-
bool: True nếu thành công, False nếu lỗi.
|
406 |
-
"""
|
407 |
p_index_for_data = 0 # Index để lấy dữ liệu dịch
|
408 |
processed_p_count = 0 # Đếm số đoạn <a:p> đã được xử lý (thay thế)
|
409 |
if not output_xml_file_path:
|
|
|
19 |
|
20 |
|
21 |
def _get_paragraph_details(p_element):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
22 |
paragraph_text_parts = []
|
23 |
first_rPr_with_text = None
|
24 |
found_first_rpr = False # Cờ để chỉ tìm rPr đầu tiên một lần
|
|
|
65 |
|
66 |
# --- Hàm trích xuất chính (Trả về list các tuple chi tiết paragraph) ---
|
67 |
def extract_text_from_slide(slide_file):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
68 |
# print(f"--- Bắt đầu trích xuất chi tiết từng <a:p> từ file: {slide_file} ---")
|
69 |
extracted_data = [] # Danh sách kết quả cuối cùng
|
70 |
|
|
|
121 |
|
122 |
|
123 |
def replace_text_in_slide(xml_file_path, list_of_translated_paragraph_data):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
124 |
# print(f"\n--- Bắt đầu thay thế PARAGRAPH (ghi đè, logic length/bold) trong file: {os.path.basename(xml_file_path)} ---")
|
125 |
processed_p_count = 0
|
126 |
|
|
|
290 |
|
291 |
|
292 |
def extract_text_from_smartart(xml_file_path):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
293 |
paragraph_data = []
|
294 |
try:
|
295 |
tree = ET.parse(xml_file_path)
|
|
|
336 |
|
337 |
# --- Hàm thay thế theo từng đoạn <a:p> ---
|
338 |
def replace_text_in_smartart(xml_file_path, list_of_translated_paragraph_data, output_xml_file_path):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
339 |
p_index_for_data = 0 # Index để lấy dữ liệu dịch
|
340 |
processed_p_count = 0 # Đếm số đoạn <a:p> đã được xử lý (thay thế)
|
341 |
if not output_xml_file_path:
|
translate/__pycache__/translator.cpython-310.pyc
CHANGED
Binary files a/translate/__pycache__/translator.cpython-310.pyc and b/translate/__pycache__/translator.cpython-310.pyc differ
|
|
translate/translator.py
CHANGED
@@ -12,7 +12,7 @@ def translate_text_dict(text_dict: Dict[str, List[str]], source_lang: str = "vi
|
|
12 |
"""Translates a single batch of text."""
|
13 |
prompt = f"""The following python dictionary contains pieces of text that form a whole document: {json.dumps(batch_dict)}.
|
14 |
|
15 |
-
Read through the entire dictionary, then translate the texts
|
16 |
|
17 |
Specialized jargon for which there are no direct translations, or names, titles, etc. should be kept whole if possible.
|
18 |
Look at the entire dictionary as a whole for context so that the translation is as accurate as possible, and to determine if each text should be translated or not.
|
|
|
12 |
"""Translates a single batch of text."""
|
13 |
prompt = f"""The following python dictionary contains pieces of text that form a whole document: {json.dumps(batch_dict)}.
|
14 |
|
15 |
+
Read through the entire dictionary, then translate the texts to {target_lang} so that the meaning is as close to the intended context as possible.
|
16 |
|
17 |
Specialized jargon for which there are no direct translations, or names, titles, etc. should be kept whole if possible.
|
18 |
Look at the entire dictionary as a whole for context so that the translation is as accurate as possible, and to determine if each text should be translated or not.
|
utils/__pycache__/utils.cpython-310.pyc
CHANGED
Binary files a/utils/__pycache__/utils.cpython-310.pyc and b/utils/__pycache__/utils.cpython-310.pyc differ
|
|
utils/utils.py
CHANGED
@@ -37,11 +37,11 @@ def translate_single_text(text: str, source_lang: str = 'English', target_lang:
|
|
37 |
model = genai.GenerativeModel('gemini-2.0-flash') # hoặc 'gemini-1.5-flash'
|
38 |
|
39 |
system_prompt = f"""You are a translation engine.
|
40 |
-
Translate the following text accurately
|
41 |
Provide *only* the translated text as a single string.
|
42 |
Do NOT add any extra formatting, delimiters like '#', introductory phrases, or explanations."""
|
43 |
|
44 |
-
user_prompt = f"
|
45 |
full_prompt = system_prompt.strip() + "\n\n" + user_prompt.strip()
|
46 |
|
47 |
response = model.generate_content(
|
@@ -135,7 +135,7 @@ def translate_text(text_dict, source_lang='English', target_lang="Vietnamese", m
|
|
135 |
6. Your output *must* be only the translated JSON object, without any introductory text, explanations, or markdown formatting like ```json ... ```.
|
136 |
"""
|
137 |
|
138 |
-
user_prompt = f"
|
139 |
|
140 |
raw_translated_json_string = "{}"
|
141 |
retry_count = 0
|
|
|
37 |
model = genai.GenerativeModel('gemini-2.0-flash') # hoặc 'gemini-1.5-flash'
|
38 |
|
39 |
system_prompt = f"""You are a translation engine.
|
40 |
+
Translate the following text accurately to {target_lang}.
|
41 |
Provide *only* the translated text as a single string.
|
42 |
Do NOT add any extra formatting, delimiters like '#', introductory phrases, or explanations."""
|
43 |
|
44 |
+
user_prompt = f"Target language: {target_lang}. Text to translate: {text}"
|
45 |
full_prompt = system_prompt.strip() + "\n\n" + user_prompt.strip()
|
46 |
|
47 |
response = model.generate_content(
|
|
|
135 |
6. Your output *must* be only the translated JSON object, without any introductory text, explanations, or markdown formatting like ```json ... ```.
|
136 |
"""
|
137 |
|
138 |
+
user_prompt = f"Target language: {target_lang}. JSON String: {json_input_string}\n\nTranslated JSON Output:"
|
139 |
|
140 |
raw_translated_json_string = "{}"
|
141 |
retry_count = 0
|
word/__pycache__/word_helper.cpython-310.pyc
CHANGED
Binary files a/word/__pycache__/word_helper.cpython-310.pyc and b/word/__pycache__/word_helper.cpython-310.pyc differ
|
|
word/word_helper.py
CHANGED
@@ -34,7 +34,7 @@ def batch_translate(texts, source_lang = 'English', target_lang="Vietnamese"):
|
|
34 |
6. Your output *must* be only the translated JSON object, without any introductory text, explanations, or markdown formatting like ```json ... ```.
|
35 |
"""
|
36 |
json_data = json.dumps({i: t for i, t in enumerate(texts)})
|
37 |
-
user_prompt = f"
|
38 |
|
39 |
model = genai.GenerativeModel('gemini-2.0-flash')
|
40 |
response = model.generate_content(contents = system_prompt.strip() + "\n" + user_prompt.strip(), generation_config={
|
|
|
34 |
6. Your output *must* be only the translated JSON object, without any introductory text, explanations, or markdown formatting like ```json ... ```.
|
35 |
"""
|
36 |
json_data = json.dumps({i: t for i, t in enumerate(texts)})
|
37 |
+
user_prompt = f"Target language: {target_lang}. JSON file: {json_data}"
|
38 |
|
39 |
model = genai.GenerativeModel('gemini-2.0-flash')
|
40 |
response = model.generate_content(contents = system_prompt.strip() + "\n" + user_prompt.strip(), generation_config={
|