Trung Vu commited on
Commit
b8469f7
·
verified ·
1 Parent(s): f1206cd

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +36 -24
app.py CHANGED
@@ -21,11 +21,18 @@ LANG_TARGET = 'vi'
21
  OUTPUT_SUFFIX = "_Dich_CN"
22
  BATCH_SIZE = 100
23
  SLEEP_BETWEEN_BATCHES = 0.1
24
- GEMINI_MODEL = "gemini-1.5-flash-latest"
25
  MAX_RETRIES = 5
 
 
 
 
 
 
 
 
26
  # -----------------
27
 
28
- # --- HELPER FUNCTIONS (from your original script) ---
29
 
30
  def safe_sheet_title(base: str) -> str:
31
  cleaned = re.sub(r'[:\\/?*\[\]]', '_', base)
@@ -40,7 +47,6 @@ def excel_quote_sheet(name: str) -> str:
40
  def _gemini_translate_call(model, texts: List[str], *, src: str, tgt: str, max_retries: int = MAX_RETRIES) -> List[str]:
41
  if not texts:
42
  return []
43
-
44
  system_prompt = (
45
  "You are a professional translator. "
46
  f"Translate each input string from {src} to {tgt}. "
@@ -55,7 +61,6 @@ def _gemini_translate_call(model, texts: List[str], *, src: str, tgt: str, max_r
55
  + json.dumps(payload, ensure_ascii=False)
56
  + "\n\nOUTPUT: JSON array of strings only."
57
  )
58
-
59
  for attempt in range(1, max_retries + 1):
60
  try:
61
  resp = model.generate_content(user_msg)
@@ -85,27 +90,32 @@ def update_formula_references(sheet, sheet_map):
85
  formula = pattern.sub(f"{new_q}!", formula)
86
  cell.value = formula
87
 
88
- # --- CORRECTED MAIN PROCESSING FUNCTION FOR GRADIO ---
89
- def process_translation(api_key: str, input_file, progress=gr.Progress(track_tqdm=True)):
 
 
90
  """
91
  Main function to be called by the Gradio interface.
92
- It takes the API key and uploaded file, performs translation, and returns the output file.
93
  """
94
  if not api_key or not api_key.strip():
95
  raise gr.Error("Gemini API Key is missing. Please paste your key.")
96
  if input_file is None:
97
  raise gr.Error("No Excel file uploaded. Please upload a .xlsx file.")
 
 
98
 
99
  logs = []
100
 
101
  try:
102
- # 1. Configure Gemini with the user-provided key
103
  genai.configure(api_key=api_key.strip())
104
- model = genai.GenerativeModel(GEMINI_MODEL)
105
- logs.append(f"✅ Initialized Gemini model: {GEMINI_MODEL}")
 
106
  yield "\n".join(logs), None # Update logs, no file yet
107
 
108
- # 2. Load the workbook from the temporary path of the uploaded file
109
  wb = load_workbook(input_file.name)
110
  original_sheet_names = [name for name in wb.sheetnames if OUTPUT_SUFFIX not in name]
111
  logs.append(f"✅ Loaded Excel file. Found {len(original_sheet_names)} sheet(s) to translate.")
@@ -116,10 +126,8 @@ def process_translation(api_key: str, input_file, progress=gr.Progress(track_tqd
116
  # 3. Step 1: Translate and create new sheets
117
  for sheet_name in progress.tqdm(original_sheet_names, desc="Translating Sheets"):
118
  source_sheet = wb[sheet_name]
119
- # FIX: Was using the undefined 'source_sheet_name' here
120
  new_sheet_name_raw = f"{sheet_name}{OUTPUT_SUFFIX}"
121
  new_sheet_name = safe_sheet_title(new_sheet_name_raw)
122
- # FIX: Was using 'source_sheet_name' as the key
123
  sheet_name_map[sheet_name] = new_sheet_name
124
 
125
  if new_sheet_name in wb.sheetnames:
@@ -141,7 +149,6 @@ def process_translation(api_key: str, input_file, progress=gr.Progress(track_tqd
141
  cells_to_translate.append({'text': val, 'row': cell.row, 'col': cell.column})
142
 
143
  total_cells = len(cells_to_translate)
144
- # FIX: Was using 'source_sheet_name' in the log message
145
  logs.append(f"--- Translating Sheet: {sheet_name} ({total_cells} cells) -> {new_sheet_name} ---")
146
  yield "\n".join(logs), None
147
 
@@ -176,14 +183,12 @@ def process_translation(api_key: str, input_file, progress=gr.Progress(track_tqd
176
  target_cell.value = translated
177
 
178
  processed_count = min(idx + len(chunk), total_cells)
179
- # FIX: Was using 'source_sheet_name' in the log update
180
  logs[-1] = f"--- Translating Sheet: {sheet_name} ({processed_count}/{total_cells} cells) -> {new_sheet_name} ---"
181
  yield "\n".join(logs), None
182
 
183
  idx += BATCH_SIZE
184
  time.sleep(SLEEP_BETWEEN_BATCHES)
185
 
186
- # FIX: Was using 'source_sheet_name' here
187
  logs.append(f"✅ Finished sheet: {sheet_name}")
188
  yield "\n".join(logs), None
189
 
@@ -207,7 +212,6 @@ def process_translation(api_key: str, input_file, progress=gr.Progress(track_tqd
207
  yield "\n".join(logs), output_file_path
208
 
209
  except Exception as e:
210
- # Use gr.Error to show a popup to the user
211
  raise gr.Error(f"An error occurred: {e}")
212
 
213
  # --- GRADIO INTERFACE ---
@@ -216,16 +220,17 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
216
  gr.Markdown(
217
  """
218
  # 批量Excel翻译工具 (ZH-VI) | Excel Translator (ZH-VI)
219
- 使用Google Gemini Pro进行中越翻译。
220
 
221
  **使用说明 (Instructions):**
222
  1. 在下方输入您的 Google Gemini API Key。(API Key is kept private and not stored).
223
- 2. 上传您的 `.xlsx` 格式的Excel文件。
224
- 3. 点击 "开始翻译 (Translate)" 按钮。
225
- 4. 等待处理完成,处理日志会实时显示。
226
- 5. 完成后,在右侧下载翻译好的文件。
 
227
  """
228
- )
229
  with gr.Row():
230
  with gr.Column(scale=1):
231
  api_key_input = gr.Textbox(
@@ -233,6 +238,12 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
233
  type="password",
234
  placeholder="Enter your API key here..."
235
  )
 
 
 
 
 
 
236
  file_input = gr.File(
237
  label="Upload Excel File (.xlsx)",
238
  file_types=[".xlsx"]
@@ -248,9 +259,10 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
248
  )
249
  file_output = gr.File(label="下载翻译文件 (Download Translated File)")
250
 
 
251
  translate_button.click(
252
  fn=process_translation,
253
- inputs=[api_key_input, file_input],
254
  outputs=[log_output, file_output]
255
  )
256
 
 
21
  OUTPUT_SUFFIX = "_Dich_CN"
22
  BATCH_SIZE = 100
23
  SLEEP_BETWEEN_BATCHES = 0.1
 
24
  MAX_RETRIES = 5
25
+
26
+ # List of available Gemini models for the user to choose from
27
+ GEMINI_MODELS = [
28
+ "gemini-flash-latest", # Fast, cost-effective, good for most tasks
29
+ "gemini-2.5-pro", # Highest quality, larger context window
30
+ "gemini-flash-lite-latest", # Previous generation pro model
31
+ ] #
32
+
33
  # -----------------
34
 
35
+ # --- HELPER FUNCTIONS (Unchanged) ---
36
 
37
  def safe_sheet_title(base: str) -> str:
38
  cleaned = re.sub(r'[:\\/?*\[\]]', '_', base)
 
47
  def _gemini_translate_call(model, texts: List[str], *, src: str, tgt: str, max_retries: int = MAX_RETRIES) -> List[str]:
48
  if not texts:
49
  return []
 
50
  system_prompt = (
51
  "You are a professional translator. "
52
  f"Translate each input string from {src} to {tgt}. "
 
61
  + json.dumps(payload, ensure_ascii=False)
62
  + "\n\nOUTPUT: JSON array of strings only."
63
  )
 
64
  for attempt in range(1, max_retries + 1):
65
  try:
66
  resp = model.generate_content(user_msg)
 
90
  formula = pattern.sub(f"{new_q}!", formula)
91
  cell.value = formula
92
 
93
+ # --- MAIN PROCESSING FUNCTION FOR GRADIO ---
94
+
95
+ # <-- MODIFIED: Added 'model_name' as an argument
96
+ def process_translation(api_key: str, model_name: str, input_file, progress=gr.Progress(track_tqdm=True)):
97
  """
98
  Main function to be called by the Gradio interface.
99
+ It takes the API key, selected model, and uploaded file, performs translation, and returns the output file.
100
  """
101
  if not api_key or not api_key.strip():
102
  raise gr.Error("Gemini API Key is missing. Please paste your key.")
103
  if input_file is None:
104
  raise gr.Error("No Excel file uploaded. Please upload a .xlsx file.")
105
+ if not model_name:
106
+ raise gr.Error("No Gemini model selected. Please choose a model from the dropdown.")
107
 
108
  logs = []
109
 
110
  try:
111
+ # 1. Configure Gemini with the user-provided key and selected model
112
  genai.configure(api_key=api_key.strip())
113
+ # <-- MODIFIED: Use the 'model_name' argument instead of a fixed constant
114
+ model = genai.GenerativeModel(model_name)
115
+ logs.append(f"✅ Initialized Gemini model: {model_name}")
116
  yield "\n".join(logs), None # Update logs, no file yet
117
 
118
+ # The rest of the function remains the same as the corrected version from before
119
  wb = load_workbook(input_file.name)
120
  original_sheet_names = [name for name in wb.sheetnames if OUTPUT_SUFFIX not in name]
121
  logs.append(f"✅ Loaded Excel file. Found {len(original_sheet_names)} sheet(s) to translate.")
 
126
  # 3. Step 1: Translate and create new sheets
127
  for sheet_name in progress.tqdm(original_sheet_names, desc="Translating Sheets"):
128
  source_sheet = wb[sheet_name]
 
129
  new_sheet_name_raw = f"{sheet_name}{OUTPUT_SUFFIX}"
130
  new_sheet_name = safe_sheet_title(new_sheet_name_raw)
 
131
  sheet_name_map[sheet_name] = new_sheet_name
132
 
133
  if new_sheet_name in wb.sheetnames:
 
149
  cells_to_translate.append({'text': val, 'row': cell.row, 'col': cell.column})
150
 
151
  total_cells = len(cells_to_translate)
 
152
  logs.append(f"--- Translating Sheet: {sheet_name} ({total_cells} cells) -> {new_sheet_name} ---")
153
  yield "\n".join(logs), None
154
 
 
183
  target_cell.value = translated
184
 
185
  processed_count = min(idx + len(chunk), total_cells)
 
186
  logs[-1] = f"--- Translating Sheet: {sheet_name} ({processed_count}/{total_cells} cells) -> {new_sheet_name} ---"
187
  yield "\n".join(logs), None
188
 
189
  idx += BATCH_SIZE
190
  time.sleep(SLEEP_BETWEEN_BATCHES)
191
 
 
192
  logs.append(f"✅ Finished sheet: {sheet_name}")
193
  yield "\n".join(logs), None
194
 
 
212
  yield "\n".join(logs), output_file_path
213
 
214
  except Exception as e:
 
215
  raise gr.Error(f"An error occurred: {e}")
216
 
217
  # --- GRADIO INTERFACE ---
 
220
  gr.Markdown(
221
  """
222
  # 批量Excel翻译工具 (ZH-VI) | Excel Translator (ZH-VI)
223
+ 使用Google Gemini进行中越翻译。
224
 
225
  **使用说明 (Instructions):**
226
  1. 在下方输入您的 Google Gemini API Key。(API Key is kept private and not stored).
227
+ 2. 选择您想使用的 Gemini 模型。(`gemini-1.5-flash` is recommended for speed and cost).
228
+ 3. 上传您的 `.xlsx` 格式的Excel文件。
229
+ 4. 点击 "开始翻译 (Translate)" 按钮。
230
+ 5. 等待处理完成,处理日志会实时显示。
231
+ 6. 完成后,在右侧下载翻译好的文件。
232
  """
233
+ ) # <-- MODIFIED: Added instruction for model selector
234
  with gr.Row():
235
  with gr.Column(scale=1):
236
  api_key_input = gr.Textbox(
 
238
  type="password",
239
  placeholder="Enter your API key here..."
240
  )
241
+ # <-- ADDED: Dropdown for model selection
242
+ model_selector = gr.Dropdown(
243
+ label="选择Gemini模型 (Select Gemini Model)",
244
+ choices=GEMINI_MODELS,
245
+ value=GEMINI_MODELS[0] # Set default to flash
246
+ )
247
  file_input = gr.File(
248
  label="Upload Excel File (.xlsx)",
249
  file_types=[".xlsx"]
 
259
  )
260
  file_output = gr.File(label="下载翻译文件 (Download Translated File)")
261
 
262
+ # <-- MODIFIED: Add 'model_selector' to the inputs list
263
  translate_button.click(
264
  fn=process_translation,
265
+ inputs=[api_key_input, model_selector, file_input],
266
  outputs=[log_output, file_output]
267
  )
268