Upload app.py
Browse files
app.py
CHANGED
@@ -1,4 +1,12 @@
|
|
1 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
import requests
|
3 |
import json
|
4 |
import os
|
@@ -170,7 +178,7 @@ def extract_abstract(text: str) -> str:
|
|
170 |
|
171 |
return abstract_text if abstract_text else "無摘要資訊"
|
172 |
|
173 |
-
def process_json_data(json_input: str) -> str:
|
174 |
"""處理JSON數據,補充缺失欄位"""
|
175 |
try:
|
176 |
# 解析輸入的JSON
|
@@ -196,6 +204,9 @@ def process_json_data(json_input: str) -> str:
|
|
196 |
"摘要": ""
|
197 |
}
|
198 |
|
|
|
|
|
|
|
199 |
# 如果有下載位置,嘗試下載並提取資訊
|
200 |
if download_url:
|
201 |
print(f"正在處理: {collection_name}")
|
@@ -225,8 +236,11 @@ def process_json_data(json_input: str) -> str:
|
|
225 |
if not author or author == "犯罪防治研究中心彙編":
|
226 |
processed_item["作者"] = pdf_author
|
227 |
|
228 |
-
#
|
229 |
-
|
|
|
|
|
|
|
230 |
|
231 |
finally:
|
232 |
# 清理臨時文件
|
@@ -235,11 +249,11 @@ def process_json_data(json_input: str) -> str:
|
|
235 |
else:
|
236 |
# 如果無法下載PDF,使用現有資訊
|
237 |
processed_item["名稱"] = extract_title_from_collection(collection_name)
|
238 |
-
processed_item["摘要"] = "無法獲取摘要資訊"
|
239 |
else:
|
240 |
# 如果沒有下載位置,使用現有資訊
|
241 |
processed_item["名稱"] = extract_title_from_collection(collection_name)
|
242 |
-
processed_item["摘要"] = "無下載位置,無法提取摘要"
|
243 |
|
244 |
processed_data.append(processed_item)
|
245 |
|
@@ -249,27 +263,51 @@ def process_json_data(json_input: str) -> str:
|
|
249 |
except Exception as e:
|
250 |
return f"處理錯誤: {str(e)}"
|
251 |
|
252 |
-
def
|
253 |
-
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
254 |
try:
|
255 |
-
|
|
|
|
|
|
|
256 |
filename = "processed_data.json"
|
257 |
|
258 |
if not filename.endswith('.json'):
|
259 |
filename += '.json'
|
260 |
|
261 |
# 確保文件名安全
|
262 |
-
filename = re.sub(r'[^\w\-_\.]', '_', filename)
|
263 |
|
264 |
with open(filename, 'w', encoding='utf-8') as f:
|
265 |
f.write(json_data)
|
266 |
|
267 |
-
return f"文件已保存: {filename}"
|
268 |
except Exception as e:
|
269 |
-
return f"保存失敗: {str(e)}"
|
270 |
|
271 |
# PDF網址處理函數
|
272 |
-
def process_pdf_urls(urls_text: str) -> str:
|
273 |
"""處理PDF網址列表���直接提取資訊"""
|
274 |
try:
|
275 |
# 解析網址
|
@@ -279,6 +317,7 @@ def process_pdf_urls(urls_text: str) -> str:
|
|
279 |
return "請輸入至少一個PDF網址"
|
280 |
|
281 |
processed_data = []
|
|
|
282 |
|
283 |
for i, url in enumerate(urls, 1):
|
284 |
print(f"正在處理第 {i}/{len(urls)} 個PDF: {url}")
|
@@ -295,7 +334,7 @@ def process_pdf_urls(urls_text: str) -> str:
|
|
295 |
item = {
|
296 |
"名稱": extracted_info.get("title", f"PDF文件 {i}"),
|
297 |
"作者": extracted_info.get("author", "未知作者"),
|
298 |
-
"摘要": extracted_info.get("abstract", "無摘要資訊"),
|
299 |
"下載位置": url,
|
300 |
"論文集名稱": f"直接處理PDF {i}"
|
301 |
}
|
@@ -311,7 +350,7 @@ def process_pdf_urls(urls_text: str) -> str:
|
|
311 |
item = {
|
312 |
"名稱": f"無法下載的PDF {i}",
|
313 |
"作者": "未知作者",
|
314 |
-
"摘要": "PDF下載失敗,無法提取摘要",
|
315 |
"下載位置": url,
|
316 |
"論文集名稱": f"處理失敗 {i}"
|
317 |
}
|
@@ -345,14 +384,27 @@ with gr.Blocks(title="PDF資料處理器", theme=gr.themes.Soft()) as demo:
|
|
345 |
json_input = gr.Textbox(
|
346 |
label="輸入JSON資料",
|
347 |
placeholder="請貼上您的JSON資料...",
|
348 |
-
lines=
|
349 |
value='[\n {\n "論文集名稱": "刑事政策與犯罪防治研究36",\n "作者": "犯罪防治研究中心彙編",\n "下載位置": "https://www.cprc.moj.gov.tw/media/20213330/3_36%E6%9C%9F%E5%85%A8%E5%88%8A%E4%B8%8B%E8%BC%89.pdf?mediaDL=true"\n }\n]'
|
350 |
)
|
351 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
352 |
filename_input1 = gr.Textbox(
|
353 |
-
label="
|
354 |
placeholder="例: processed_papers.json",
|
355 |
-
value="processed_papers.json"
|
|
|
356 |
)
|
357 |
|
358 |
process_json_btn = gr.Button("處理JSON資料", variant="primary", size="lg")
|
@@ -360,7 +412,7 @@ with gr.Blocks(title="PDF資料處理器", theme=gr.themes.Soft()) as demo:
|
|
360 |
with gr.Column(scale=2):
|
361 |
output_json1 = gr.Textbox(
|
362 |
label="處理結果",
|
363 |
-
lines=
|
364 |
show_copy_button=True
|
365 |
)
|
366 |
|
@@ -381,14 +433,27 @@ with gr.Blocks(title="PDF資料處理器", theme=gr.themes.Soft()) as demo:
|
|
381 |
pdf_urls_input = gr.Textbox(
|
382 |
label="輸入PDF網址",
|
383 |
placeholder="請輸入PDF網址,每行一個...\n\n例如:\nhttps://example.com/paper1.pdf\nhttps://example.com/paper2.pdf\nhttps://example.com/paper3.pdf",
|
384 |
-
lines=
|
385 |
value="https://www.cprc.moj.gov.tw/media/20213330/3_36%E6%9C%9F%E5%85%A8%E5%88%8A%E4%B8%8B%E8%BC%89.pdf?mediaDL=true"
|
386 |
)
|
387 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
388 |
filename_input2 = gr.Textbox(
|
389 |
-
label="
|
390 |
placeholder="例: pdf_extracted_data.json",
|
391 |
-
value="pdf_extracted_data.json"
|
|
|
392 |
)
|
393 |
|
394 |
process_urls_btn = gr.Button("處理PDF網址", variant="primary", size="lg")
|
@@ -396,7 +461,7 @@ with gr.Blocks(title="PDF資料處理器", theme=gr.themes.Soft()) as demo:
|
|
396 |
with gr.Column(scale=2):
|
397 |
output_json2 = gr.Textbox(
|
398 |
label="處理結果",
|
399 |
-
lines=
|
400 |
show_copy_button=True
|
401 |
)
|
402 |
|
@@ -410,76 +475,151 @@ with gr.Blocks(title="PDF資料處理器", theme=gr.themes.Soft()) as demo:
|
|
410 |
visible=False
|
411 |
)
|
412 |
|
413 |
-
def process_and_save_json(json_input,
|
414 |
# 處理JSON資料
|
415 |
-
result = process_json_data(json_input)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
416 |
|
417 |
# 保存文件
|
418 |
-
save_msg = save_json_file(
|
|
|
|
|
|
|
|
|
|
|
419 |
|
420 |
# 如果保存成功,提供下載
|
421 |
-
if "已保存" in save_msg:
|
422 |
-
return result, save_msg, gr.update(visible=True, value=
|
423 |
else:
|
424 |
return result, save_msg, gr.update(visible=False)
|
425 |
|
426 |
-
def process_and_save_urls(urls_input,
|
427 |
# 處理PDF網址
|
428 |
-
result = process_pdf_urls(urls_input)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
429 |
|
430 |
# 保存文件
|
431 |
-
save_msg = save_json_file(
|
|
|
|
|
|
|
|
|
|
|
432 |
|
433 |
# 如果保存成功,提供下載
|
434 |
-
if "已保存" in save_msg:
|
435 |
-
return result, save_msg, gr.update(visible=True, value=
|
436 |
else:
|
437 |
return result, save_msg, gr.update(visible=False)
|
438 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
439 |
# JSON處理按鈕事件
|
440 |
process_json_btn.click(
|
441 |
process_and_save_json,
|
442 |
-
inputs=[json_input, filename_input1],
|
443 |
outputs=[output_json1, save_status1, download_file1]
|
444 |
)
|
445 |
|
446 |
# PDF網址處理按鈕事件
|
447 |
process_urls_btn.click(
|
448 |
process_and_save_urls,
|
449 |
-
inputs=[pdf_urls_input, filename_input2],
|
450 |
outputs=[output_json2, save_status2, download_file2]
|
451 |
)
|
452 |
|
453 |
gr.Markdown("""
|
454 |
## 使用說明:
|
455 |
|
|
|
|
|
|
|
|
|
|
|
456 |
### JSON資料處理模式:
|
457 |
1. 將現有的JSON資料貼入文本框
|
458 |
-
2.
|
459 |
-
3.
|
|
|
|
|
460 |
|
461 |
### PDF網址直接處理模式:
|
462 |
1. 直接貼入PDF網址,每行一個
|
463 |
-
2.
|
464 |
-
3.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
465 |
|
466 |
-
###
|
467 |
-
|
468 |
-
|
469 |
-
|
470 |
-
- 支援文件下載
|
471 |
|
472 |
## 注意事項:
|
473 |
-
-
|
474 |
-
-
|
475 |
-
- 如果PDF無法下載,會使用預設資訊
|
476 |
- 建議分批處理大量文件以獲得最佳效果
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
477 |
|
478 |
-
|
479 |
```
|
480 |
-
|
481 |
-
https://example.com/paper2.pdf
|
482 |
-
https://example.com/paper3.pdf
|
483 |
```
|
484 |
""")
|
485 |
|
|
|
1 |
+
gr.Markdown("""
|
2 |
+
## 使用說明:
|
3 |
+
|
4 |
+
### 🆕 新功能特色:
|
5 |
+
- **🔄 智能檔名**: 自動使用論文集名稱或PDF標題作為JSON檔名
|
6 |
+
- **📝 手動摘要**: 可貼上現有摘要,避免重複提取
|
7 |
+
- **⚡ 高效處理**: 有摘要就不用下載PDF,節省時間
|
8 |
+
|
9 |
+
### JSON資料import gradio as gr
|
10 |
import requests
|
11 |
import json
|
12 |
import os
|
|
|
178 |
|
179 |
return abstract_text if abstract_text else "無摘要資訊"
|
180 |
|
181 |
+
def process_json_data(json_input: str, manual_abstract: str = "") -> str:
|
182 |
"""處理JSON數據,補充缺失欄位"""
|
183 |
try:
|
184 |
# 解析輸入的JSON
|
|
|
204 |
"摘要": ""
|
205 |
}
|
206 |
|
207 |
+
# 如果有手動輸入的摘要,優先使用
|
208 |
+
use_manual_abstract = manual_abstract.strip()
|
209 |
+
|
210 |
# 如果有下載位置,嘗試下載並提取資訊
|
211 |
if download_url:
|
212 |
print(f"正在處理: {collection_name}")
|
|
|
236 |
if not author or author == "犯罪防治研究中心彙編":
|
237 |
processed_item["作者"] = pdf_author
|
238 |
|
239 |
+
# 設定摘要:優先使用手動輸入,否則使用PDF提取的
|
240 |
+
if use_manual_abstract:
|
241 |
+
processed_item["摘要"] = use_manual_abstract
|
242 |
+
else:
|
243 |
+
processed_item["摘要"] = extracted_info.get("abstract", "無摘要資訊")
|
244 |
|
245 |
finally:
|
246 |
# 清理臨時文件
|
|
|
249 |
else:
|
250 |
# 如果無法下載PDF,使用現有資訊
|
251 |
processed_item["名稱"] = extract_title_from_collection(collection_name)
|
252 |
+
processed_item["摘要"] = use_manual_abstract if use_manual_abstract else "無法獲取摘要資訊"
|
253 |
else:
|
254 |
# 如果沒有下載位置,使用現有資訊
|
255 |
processed_item["名稱"] = extract_title_from_collection(collection_name)
|
256 |
+
processed_item["摘要"] = use_manual_abstract if use_manual_abstract else "無下載位置,無法提取摘要"
|
257 |
|
258 |
processed_data.append(processed_item)
|
259 |
|
|
|
263 |
except Exception as e:
|
264 |
return f"處理錯誤: {str(e)}"
|
265 |
|
266 |
+
def generate_filename_from_collection(collection_name: str) -> str:
|
267 |
+
"""根據論文集名稱生成安全的文件名"""
|
268 |
+
if not collection_name:
|
269 |
+
return "processed_data.json"
|
270 |
+
|
271 |
+
# 移除特殊字符,保留中英文、數字、連字符
|
272 |
+
safe_name = re.sub(r'[^\w\u4e00-\u9fff\-]', '_', collection_name)
|
273 |
+
|
274 |
+
# 移除多餘的下劃線
|
275 |
+
safe_name = re.sub(r'_+', '_', safe_name).strip('_')
|
276 |
+
|
277 |
+
# 限制長度
|
278 |
+
if len(safe_name) > 50:
|
279 |
+
safe_name = safe_name[:50]
|
280 |
+
|
281 |
+
# 確保有副檔名
|
282 |
+
if not safe_name.endswith('.json'):
|
283 |
+
safe_name += '.json'
|
284 |
+
|
285 |
+
return safe_name
|
286 |
+
|
287 |
+
def save_json_file(json_data: str, filename: str = None, auto_filename: bool = False, collection_name: str = None) -> tuple:
|
288 |
+
"""保存JSON文件,支持自動文件名生成"""
|
289 |
try:
|
290 |
+
# 如果啟用自動文件名且有論文集名稱,使用論文集名稱
|
291 |
+
if auto_filename and collection_name:
|
292 |
+
filename = generate_filename_from_collection(collection_name)
|
293 |
+
elif not filename:
|
294 |
filename = "processed_data.json"
|
295 |
|
296 |
if not filename.endswith('.json'):
|
297 |
filename += '.json'
|
298 |
|
299 |
# 確保文件名安全
|
300 |
+
filename = re.sub(r'[^\w\u4e00-\u9fff\-_\.]', '_', filename)
|
301 |
|
302 |
with open(filename, 'w', encoding='utf-8') as f:
|
303 |
f.write(json_data)
|
304 |
|
305 |
+
return f"文件已保存: {filename}", filename
|
306 |
except Exception as e:
|
307 |
+
return f"保存失敗: {str(e)}", None
|
308 |
|
309 |
# PDF網址處理函數
|
310 |
+
def process_pdf_urls(urls_text: str, manual_abstract: str = "") -> str:
|
311 |
"""處理PDF網址列表���直接提取資訊"""
|
312 |
try:
|
313 |
# 解析網址
|
|
|
317 |
return "請輸入至少一個PDF網址"
|
318 |
|
319 |
processed_data = []
|
320 |
+
use_manual_abstract = manual_abstract.strip()
|
321 |
|
322 |
for i, url in enumerate(urls, 1):
|
323 |
print(f"正在處理第 {i}/{len(urls)} 個PDF: {url}")
|
|
|
334 |
item = {
|
335 |
"名稱": extracted_info.get("title", f"PDF文件 {i}"),
|
336 |
"作者": extracted_info.get("author", "未知作者"),
|
337 |
+
"摘要": use_manual_abstract if use_manual_abstract else extracted_info.get("abstract", "無摘要資訊"),
|
338 |
"下載位置": url,
|
339 |
"論文集名稱": f"直接處理PDF {i}"
|
340 |
}
|
|
|
350 |
item = {
|
351 |
"名稱": f"無法下載的PDF {i}",
|
352 |
"作者": "未知作者",
|
353 |
+
"摘要": use_manual_abstract if use_manual_abstract else "PDF下載失敗,無法提取摘要",
|
354 |
"下載位置": url,
|
355 |
"論文集名稱": f"處理失敗 {i}"
|
356 |
}
|
|
|
384 |
json_input = gr.Textbox(
|
385 |
label="輸入JSON資料",
|
386 |
placeholder="請貼上您的JSON資料...",
|
387 |
+
lines=8,
|
388 |
value='[\n {\n "論文集名稱": "刑事政策與犯罪防治研究36",\n "作者": "犯罪防治研究中心彙編",\n "下載位置": "https://www.cprc.moj.gov.tw/media/20213330/3_36%E6%9C%9F%E5%85%A8%E5%88%8A%E4%B8%8B%E8%BC%89.pdf?mediaDL=true"\n }\n]'
|
389 |
)
|
390 |
|
391 |
+
manual_abstract1 = gr.Textbox(
|
392 |
+
label="手動輸入摘要 (選填)",
|
393 |
+
placeholder="如果有摘要,請在此輸入。留空則自動從PDF中提取。",
|
394 |
+
lines=4
|
395 |
+
)
|
396 |
+
|
397 |
+
with gr.Row():
|
398 |
+
auto_filename1 = gr.Checkbox(
|
399 |
+
label="自動使用論文集名稱作為檔名",
|
400 |
+
value=True
|
401 |
+
)
|
402 |
+
|
403 |
filename_input1 = gr.Textbox(
|
404 |
+
label="自訂文件名 (僅在未勾選自動檔名時使用)",
|
405 |
placeholder="例: processed_papers.json",
|
406 |
+
value="processed_papers.json",
|
407 |
+
visible=False
|
408 |
)
|
409 |
|
410 |
process_json_btn = gr.Button("處理JSON資料", variant="primary", size="lg")
|
|
|
412 |
with gr.Column(scale=2):
|
413 |
output_json1 = gr.Textbox(
|
414 |
label="處理結果",
|
415 |
+
lines=18,
|
416 |
show_copy_button=True
|
417 |
)
|
418 |
|
|
|
433 |
pdf_urls_input = gr.Textbox(
|
434 |
label="輸入PDF網址",
|
435 |
placeholder="請輸入PDF網址,每行一個...\n\n例如:\nhttps://example.com/paper1.pdf\nhttps://example.com/paper2.pdf\nhttps://example.com/paper3.pdf",
|
436 |
+
lines=8,
|
437 |
value="https://www.cprc.moj.gov.tw/media/20213330/3_36%E6%9C%9F%E5%85%A8%E5%88%8A%E4%B8%8B%E8%BC%89.pdf?mediaDL=true"
|
438 |
)
|
439 |
|
440 |
+
manual_abstract2 = gr.Textbox(
|
441 |
+
label="手動輸入摘要 (選填)",
|
442 |
+
placeholder="如果有摘要,請在此輸入。留空則自動從PDF中提取。",
|
443 |
+
lines=4
|
444 |
+
)
|
445 |
+
|
446 |
+
with gr.Row():
|
447 |
+
auto_filename2 = gr.Checkbox(
|
448 |
+
label="自動使用第一個PDF標題作為檔名",
|
449 |
+
value=True
|
450 |
+
)
|
451 |
+
|
452 |
filename_input2 = gr.Textbox(
|
453 |
+
label="自訂文件名 (僅在未勾選自動檔名時使用)",
|
454 |
placeholder="例: pdf_extracted_data.json",
|
455 |
+
value="pdf_extracted_data.json",
|
456 |
+
visible=False
|
457 |
)
|
458 |
|
459 |
process_urls_btn = gr.Button("處理PDF網址", variant="primary", size="lg")
|
|
|
461 |
with gr.Column(scale=2):
|
462 |
output_json2 = gr.Textbox(
|
463 |
label="處理結果",
|
464 |
+
lines=18,
|
465 |
show_copy_button=True
|
466 |
)
|
467 |
|
|
|
475 |
visible=False
|
476 |
)
|
477 |
|
478 |
+
def process_and_save_json(json_input, manual_abstract, auto_filename, custom_filename):
|
479 |
# 處理JSON資料
|
480 |
+
result = process_json_data(json_input, manual_abstract)
|
481 |
+
|
482 |
+
# 獲取論文集名稱用於自動檔名
|
483 |
+
collection_name = ""
|
484 |
+
try:
|
485 |
+
data = json.loads(json_input)
|
486 |
+
if isinstance(data, list) and len(data) > 0:
|
487 |
+
collection_name = data[0].get("論文集名稱", "")
|
488 |
+
elif isinstance(data, dict):
|
489 |
+
collection_name = data.get("論文集名稱", "")
|
490 |
+
except:
|
491 |
+
pass
|
492 |
|
493 |
# 保存文件
|
494 |
+
save_msg, actual_filename = save_json_file(
|
495 |
+
result,
|
496 |
+
custom_filename if not auto_filename else None,
|
497 |
+
auto_filename,
|
498 |
+
collection_name
|
499 |
+
)
|
500 |
|
501 |
# 如果保存成功,提供下載
|
502 |
+
if actual_filename and "已保存" in save_msg:
|
503 |
+
return result, save_msg, gr.update(visible=True, value=actual_filename)
|
504 |
else:
|
505 |
return result, save_msg, gr.update(visible=False)
|
506 |
|
507 |
+
def process_and_save_urls(urls_input, manual_abstract, auto_filename, custom_filename):
|
508 |
# 處理PDF網址
|
509 |
+
result = process_pdf_urls(urls_input, manual_abstract)
|
510 |
+
|
511 |
+
# 獲取第一個PDF的標題用於自動檔名
|
512 |
+
title_for_filename = ""
|
513 |
+
if auto_filename:
|
514 |
+
try:
|
515 |
+
data = json.loads(result)
|
516 |
+
if isinstance(data, list) and len(data) > 0:
|
517 |
+
title_for_filename = data[0].get("名稱", "")
|
518 |
+
except:
|
519 |
+
pass
|
520 |
|
521 |
# 保存文件
|
522 |
+
save_msg, actual_filename = save_json_file(
|
523 |
+
result,
|
524 |
+
custom_filename if not auto_filename else None,
|
525 |
+
auto_filename,
|
526 |
+
title_for_filename
|
527 |
+
)
|
528 |
|
529 |
# 如果保存成功,提供下載
|
530 |
+
if actual_filename and "已保存" in save_msg:
|
531 |
+
return result, save_msg, gr.update(visible=True, value=actual_filename)
|
532 |
else:
|
533 |
return result, save_msg, gr.update(visible=False)
|
534 |
|
535 |
+
# 控制文件名輸入框的顯示/隱藏
|
536 |
+
def toggle_filename_input1(auto_filename):
|
537 |
+
return gr.update(visible=not auto_filename)
|
538 |
+
|
539 |
+
def toggle_filename_input2(auto_filename):
|
540 |
+
return gr.update(visible=not auto_filename)
|
541 |
+
|
542 |
+
# 綁定checkbox事件
|
543 |
+
auto_filename1.change(
|
544 |
+
toggle_filename_input1,
|
545 |
+
inputs=[auto_filename1],
|
546 |
+
outputs=[filename_input1]
|
547 |
+
)
|
548 |
+
|
549 |
+
auto_filename2.change(
|
550 |
+
toggle_filename_input2,
|
551 |
+
inputs=[auto_filename2],
|
552 |
+
outputs=[filename_input2]
|
553 |
+
)
|
554 |
+
|
555 |
# JSON處理按鈕事件
|
556 |
process_json_btn.click(
|
557 |
process_and_save_json,
|
558 |
+
inputs=[json_input, manual_abstract1, auto_filename1, filename_input1],
|
559 |
outputs=[output_json1, save_status1, download_file1]
|
560 |
)
|
561 |
|
562 |
# PDF網址處理按鈕事件
|
563 |
process_urls_btn.click(
|
564 |
process_and_save_urls,
|
565 |
+
inputs=[pdf_urls_input, manual_abstract2, auto_filename2, filename_input2],
|
566 |
outputs=[output_json2, save_status2, download_file2]
|
567 |
)
|
568 |
|
569 |
gr.Markdown("""
|
570 |
## 使用說明:
|
571 |
|
572 |
+
### 🆕 新功能特色:
|
573 |
+
- **🔄 智能檔名**: 自動使用論文集名稱或PDF標題作為JSON檔名
|
574 |
+
- **📝 手動摘要**: 可貼上現有摘要,避免重複提取
|
575 |
+
- **⚡ 高效處理**: 有摘要就不用下載PDF,���省時間
|
576 |
+
|
577 |
### JSON資料處理模式:
|
578 |
1. 將現有的JSON資料貼入文本框
|
579 |
+
2. **可選**: 在摘要欄位貼上已知的摘要內容
|
580 |
+
3. 勾選"自動使用論文集名稱作為檔名"(推薦)
|
581 |
+
4. 系統會根據下載位置自動獲取PDF並補充缺失欄位
|
582 |
+
5. 如果已提供摘要,系統將跳過PDF摘要提取,節省處理時間
|
583 |
|
584 |
### PDF網址直接處理模式:
|
585 |
1. 直接貼入PDF網址,每行一個
|
586 |
+
2. **可選**: 在摘要欄位貼上統一的摘要內容
|
587 |
+
3. 勾選"自動使用第一個PDF標題作為檔名"(推薦)
|
588 |
+
4. 系統會自動下載並提取完整資訊
|
589 |
+
5. 如果已提供摘要,將應用到所有PDF條目
|
590 |
+
|
591 |
+
### 檔名規則:
|
592 |
+
- **自動檔名**: 使用論文集名稱或PDF標題,自動清理特殊字符
|
593 |
+
- **自訂檔名**: 取消勾選自動檔名後可手動指定
|
594 |
+
- 檔名會自動加上`.json`副檔名
|
595 |
+
- 特殊字符會被替換為安全字符
|
596 |
|
597 |
+
### 摘要處理優先順序:
|
598 |
+
1. **手動輸入的摘要** (最高優先級)
|
599 |
+
2. PDF中提取的摘要
|
600 |
+
3. 預設訊息 ("無摘要資訊")
|
|
|
601 |
|
602 |
## 注意事項:
|
603 |
+
- 提供手動摘要可大幅加快處理速度
|
604 |
+
- 自動檔名會避免檔案系統不支援的字符
|
|
|
605 |
- 建議分批處理大量文件以獲得最佳效果
|
606 |
+
- 系統會自動清理重複的標題內容
|
607 |
+
|
608 |
+
## 範例使用情境:
|
609 |
+
|
610 |
+
### 情境1: 已知摘要的快速處理
|
611 |
+
```
|
612 |
+
有現成的論文摘要 → 貼入摘要欄位 → 勾選自動檔名 → 快速處理
|
613 |
+
```
|
614 |
+
|
615 |
+
### 情境2: 完全自動化處理
|
616 |
+
```
|
617 |
+
只有PDF網址 → 留空摘要欄位 → 勾選自動檔名 → 全自動提取
|
618 |
+
```
|
619 |
|
620 |
+
### 情境3: 批量處理相同摘要
|
621 |
```
|
622 |
+
多個PDF同一主題 → 輸入統一摘要 → 批量處理 → 節省時間
|
|
|
|
|
623 |
```
|
624 |
""")
|
625 |
|